[PPL-devel] [GIT] ppl/ppl(master): Added helper method insert_precise_aux to avoid recursive call.
Enea Zaffanella
zaffanella at cs.unipr.it
Fri Aug 17 17:21:38 CEST 2012
Module: ppl/ppl
Branch: master
Commit: 0873d966a21ec85959b2d8274e9e3ac561a3a09f
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=0873d966a21ec85959b2d8274e9e3ac561a3a09f
Author: Enea Zaffanella <zaffanella at cs.unipr.it>
Date: Fri Aug 17 17:13:39 2012 +0200
Added helper method insert_precise_aux to avoid recursive call.
Detected by ECLAIR service funrecsn.
---
src/CO_Tree.cc | 70 +++++++++++++++++++++++++++++---------------------
src/CO_Tree.defs.hh | 11 ++++++++
2 files changed, 52 insertions(+), 29 deletions(-)
diff --git a/src/CO_Tree.cc b/src/CO_Tree.cc
index cbc1d50..68d49d4 100644
--- a/src/CO_Tree.cc
+++ b/src/CO_Tree.cc
@@ -357,54 +357,69 @@ PPL::CO_Tree::insert_precise(dimension_type key1,
PPL_ASSERT(!empty());
#ifndef NDEBUG
+ // Check that `itr' is a correct hint.
tree_iterator itr2(*this);
itr2.go_down_searching_key(key1);
PPL_ASSERT(itr == itr2);
#endif
if (itr.index() == key1) {
+ // Replacement, rather than insertion.
*itr = data1;
PPL_ASSERT(OK());
return itr;
}
- if (data <= &data1 && &data1 < data + (reserved_size + 1)) {
- // data1 is a coefficient of this row.
- // Avoid invalidating it.
- data_type x = data1;
+ // Proper insertion: check if it would invalidate `data1'.
+ const bool invalidating
+ = (data <= &data1) && (&data1 < data + (reserved_size + 1));
+
+ if (!invalidating)
+ return insert_precise_aux(key1, data1, itr);
+
+ // `data1' could be invalidated by the insert, because it is
+ // a coefficient of this row. Avoid the issue by copying it.
+ data_type data1_copy = data1;
#ifndef NDEBUG
- dimension_type i = &data1 - data;
- dimension_type key2 = indexes[i];
- PPL_ASSERT(key2 != unused_index);
- // This is true since key1 is not in the tree.
- PPL_ASSERT(key2 != key1);
+ dimension_type i = &data1 - data;
+ dimension_type key2 = indexes[i];
+ PPL_ASSERT(key2 != unused_index);
+ // This is true since `key1' is not in the tree.
+ PPL_ASSERT(key2 != key1);
#endif
- // Insert a dummy coefficient.
- // NOTE: This may invalidate data1, because it may reallocate the tree
- // and/or move coefficients during rebalancing).
- itr = insert_precise(key1, Coefficient_zero(), itr);
+ // Insert a dummy coefficient.
+ // NOTE: this may invalidate `data1', because it may reallocate the tree
+ // and/or move coefficients during rebalancing.
+ itr = insert_precise_aux(key1, Coefficient_zero(), itr);
- PPL_ASSERT(itr.index() == key1);
+ PPL_ASSERT(itr.index() == key1);
- using std::swap;
+ // Swap the correct coefficient in place.
+ using std::swap;
+ swap(*itr, data1_copy);
- // Swap the correct coefficient in place.
- swap(*itr, x);
+ PPL_ASSERT(OK());
+ return itr;
+}
- PPL_ASSERT(OK());
- return itr;
- }
+PPL::CO_Tree::tree_iterator
+PPL::CO_Tree::insert_precise_aux(dimension_type key1,
+ data_type_const_reference data1,
+ tree_iterator itr) {
+ PPL_ASSERT(key1 != unused_index);
+ PPL_ASSERT(!empty());
+ // This is a proper insert.
+ PPL_ASSERT(itr.index() != key1);
+ // `data1' is not going to be invalidated.
+ PPL_ASSERT(!(data <= &data1 && &data1 < data + (reserved_size + 1)));
if (is_greater_than_ratio(size_ + 1, reserved_size, max_density_percent)) {
-
rebuild_bigger_tree();
-
- // itr was invalidated by the rebuild operation
+ // `itr' was invalidated by the rebuild operation
itr.get_root();
itr.go_down_searching_key(key1);
-
PPL_ASSERT(itr.index() != key1);
}
@@ -423,13 +438,10 @@ PPL::CO_Tree::insert_precise(dimension_type key1,
new (&(*itr)) data_type(data1);
// Set the index only if the construction was successful.
itr.index() = key1;
-
- } else {
-
+ }
+ else {
itr = rebalance(itr, key1, data1);
-
itr.go_down_searching_key(key1);
-
PPL_ASSERT(itr.index() == key1);
}
PPL_ASSERT(OK());
diff --git a/src/CO_Tree.defs.hh b/src/CO_Tree.defs.hh
index d02b467..c09f6f8 100644
--- a/src/CO_Tree.defs.hh
+++ b/src/CO_Tree.defs.hh
@@ -954,6 +954,17 @@ private:
data_type_const_reference data,
tree_iterator itr);
+ //! Helper for \c insert_precise.
+ /*!
+ This helper method takes the same arguments as \c insert_precise,
+ but besides assuming that \p itr is a correct hint, it also assumes
+ that \p key and \p data are not in the tree; namely, a proper
+ insertion has to be done and the insertion can not invalidate \p data.
+ */
+ tree_iterator insert_precise_aux(dimension_type key,
+ data_type_const_reference data,
+ tree_iterator itr);
+
//! Inserts an element in the tree.
/*!
More information about the PPL-devel
mailing list