[PPL-devel] [GIT] ppl/ppl(sparse_matrices): CO_Tree: optimize go_down_searching_key() for the DFS layout.

Marco Poletti poletti.marco at gmail.com
Sun May 9 13:52:36 CEST 2010


Module: ppl/ppl
Branch: sparse_matrices
Commit: 633bb9f9ad12fb4995c3dee47e111bfd09c02b4f
URL:    http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=633bb9f9ad12fb4995c3dee47e111bfd09c02b4f

Author: Marco Poletti <poletti.marco at gmail.com>
Date:   Sat May  8 18:35:00 2010 +0200

CO_Tree: optimize go_down_searching_key() for the DFS layout.

---

 src/CO_Tree.defs.hh    |    6 +--
 src/CO_Tree.inlines.hh |  132 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+), 4 deletions(-)

diff --git a/src/CO_Tree.defs.hh b/src/CO_Tree.defs.hh
index 21fcd1e..c185103 100644
--- a/src/CO_Tree.defs.hh
+++ b/src/CO_Tree.defs.hh
@@ -583,8 +583,7 @@ private:
   //! The tree the iterator points to.
   const CO_Tree* tree;
 
-  friend dimension_type
-    CO_Tree::count_used_in_subtree(inorder_const_iterator& itr);
+  friend class CO_Tree;
 };
 
 class CO_Tree::inorder_iterator {
@@ -743,8 +742,7 @@ private:
   friend inorder_const_iterator&
     inorder_const_iterator::operator=(const inorder_iterator&);
 
-  friend dimension_type
-    CO_Tree::count_used_in_subtree(inorder_iterator& itr);
+  friend class CO_Tree;
 };
 
 } // namespace Parma_Polyhedra_Library
diff --git a/src/CO_Tree.inlines.hh b/src/CO_Tree.inlines.hh
index 8797d65..f91f8ac 100644
--- a/src/CO_Tree.inlines.hh
+++ b/src/CO_Tree.inlines.hh
@@ -353,7 +353,71 @@ CO_Tree::go_down_searching_key(inorder_const_iterator& itr,
 
 inline void
 CO_Tree::lower_bound(inorder_iterator& itr, dimension_type key) {
+#ifdef USE_PPL_CO_TREE_DFS_LAYOUT
+  PPL_ASSERT(!empty());
+  PPL_ASSERT(itr.is_at_end() || itr->first <= key);
+
+  if (itr.is_before_begin())
+    ++itr;
+
+  PPL_ASSERT(itr.is_at_end() || itr->first <= key);
+
+  if (itr.is_at_end())
+    return;
+
+  dimension_type low_index = itr.i;
+  dimension_type high_index = reserved_size;
+
+  PPL_ASSERT(low_index > 0);
+
+  while (low_index + 1 < high_index) {
+
+    dimension_type avg = (low_index + high_index) / 2;
+    dimension_type index = avg;
+
+    while (indexes[index] == unused_index)
+      ++index;
+
+    if (index > high_index || indexes[index] > key) {
+      high_index = avg;
+    } else {
+      low_index = index;
+    }
+  }
+
+  if (low_index == high_index) {
+    if (indexes[low_index] == unused_index || indexes[low_index] < key)
+      ++low_index;
+    while (indexes[low_index] == unused_index)
+      ++low_index;
+
+  } else {
+    PPL_ASSERT(low_index + 1 == high_index);
+    if (indexes[low_index] == unused_index || indexes[low_index] < key) {
+      ++low_index;
+      if (indexes[low_index] == unused_index || indexes[low_index] < key)
+        ++low_index;
+    }
+    while (indexes[low_index] == unused_index)
+      ++low_index;
+  }
+
+  itr.i = low_index;
+
+#ifndef NDEBUG
+  inorder_iterator itr2 = itr;
+  itr2.get_previous_value();
+  PPL_ASSERT(itr2.is_before_begin() || itr2->first < key);
+  itr2.get_next_value();
+  PPL_ASSERT(itr2 == itr);
+#endif
+
+  PPL_ASSERT(itr.is_at_end() || itr->first >= key);
+
+#else // defined(USE_PPL_CO_TREE_DFS_LAYOUT)
+
   PPL_ASSERT(!empty());
+  PPL_ASSERT(itr.is_at_end() || itr->first <= key);
   if (itr->first <= key)
     while (itr.has_parent() && itr->first < key)
       itr.get_parent();
@@ -378,11 +442,77 @@ CO_Tree::lower_bound(inorder_iterator& itr, dimension_type key) {
   itr.get_next_value();
 #endif
   PPL_ASSERT(itr.is_at_end() || itr->first >= key);
+
+#endif // defined(USE_PPL_CO_TREE_DFS_LAYOUT)
 }
 
 inline void
 CO_Tree::lower_bound(inorder_const_iterator& itr, dimension_type key) const {
+#ifdef USE_PPL_CO_TREE_DFS_LAYOUT
+  PPL_ASSERT(!empty());
+  PPL_ASSERT(itr.is_at_end() || itr->first <= key);
+
+  if (itr.is_before_begin())
+    ++itr;
+
+  PPL_ASSERT(itr.is_at_end() || itr->first <= key);
+
+  if (itr.is_at_end())
+    return;
+
+  dimension_type low_index = itr.i;
+  dimension_type high_index = reserved_size;
+
+  PPL_ASSERT(low_index > 0);
+
+  while (low_index + 1 < high_index) {
+
+    dimension_type avg = (low_index + high_index) / 2;
+    dimension_type index = avg;
+
+    while (indexes[index] == unused_index)
+      ++index;
+
+    if (index > high_index || indexes[index] > key) {
+      high_index = avg;
+    } else {
+      low_index = index;
+    }
+  }
+
+  if (low_index == high_index) {
+    if (indexes[low_index] == unused_index || indexes[low_index] < key)
+      ++low_index;
+    while (indexes[low_index] == unused_index)
+      ++low_index;
+
+  } else {
+    PPL_ASSERT(low_index + 1 == high_index);
+    if (indexes[low_index] == unused_index || indexes[low_index] < key) {
+      ++low_index;
+      if (indexes[low_index] == unused_index || indexes[low_index] < key)
+        ++low_index;
+    }
+    while (indexes[low_index] == unused_index)
+      ++low_index;
+  }
+
+  itr.i = low_index;
+
+#ifndef NDEBUG
+  inorder_const_iterator itr2 = itr;
+  itr2.get_previous_value();
+  PPL_ASSERT(itr2.is_before_begin() || itr2->first < key);
+  itr2.get_next_value();
+  PPL_ASSERT(itr2 == itr);
+#endif
+
+  PPL_ASSERT(itr.is_at_end() || itr->first >= key);
+
+#else // defined(USE_PPL_CO_TREE_DFS_LAYOUT)
+
   PPL_ASSERT(!empty());
+  PPL_ASSERT(itr.is_at_end() || itr->first <= key);
   if (itr->first <= key)
     while (itr.has_parent() && itr->first < key)
       itr.get_parent();
@@ -407,6 +537,8 @@ CO_Tree::lower_bound(inorder_const_iterator& itr, dimension_type key) const {
   itr.get_next_value();
 #endif
   PPL_ASSERT(itr.is_at_end() || itr->first >= key);
+
+#endif // defined(USE_PPL_CO_TREE_DFS_LAYOUT)
 }
 
 inline void




More information about the PPL-devel mailing list