]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Use a std::vector<Range> instead of a std::set<Range>. Keep it always sorted.
authorbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 15 Oct 2009 22:31:15 +0000 (22:31 +0000)
committerbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 15 Oct 2009 22:31:15 +0000 (22:31 +0000)
git-svn-id: https://svn.dealii.org/trunk@19896 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/base/include/base/index_set.h
deal.II/base/source/index_set.cc

index ae290dec156e9d519441b6444f699d28ec23f2e4..eb6a8b2bf1a2657f18bca72d524223b0dae3bc0b 100644 (file)
@@ -16,7 +16,8 @@
 #include <base/config.h>
 #include <base/exceptions.h>
 
-#include <set>
+#include <vector>
+#include <algorithm>
 
 
 DEAL_II_NAMESPACE_OPEN
@@ -154,12 +155,24 @@ class IndexSet
                                      * A type that denotes the half
                                      * open index range
                                      * <code>[begin,end)</code>.
+                                     *
+                                     * The nth_index_in_set denotes
+                                     * the how many-th index within
+                                     * this IndexSet the first
+                                     * element of the current range
+                                     * is. This information is only
+                                     * accurate if
+                                     * IndexSet::compress() has been
+                                     * called after the last
+                                     * insertion.
                                      */
     struct Range
     {
        unsigned int begin;
        unsigned int end;
 
+       unsigned int nth_index_in_set;
+
        Range (const unsigned int i1,
               const unsigned int i2);
 
@@ -178,7 +191,8 @@ class IndexSet
                                     /**
                                      * A set of contiguous ranges of
                                      * indices that make up (part of)
-                                     * this index set.
+                                     * this index set. This variable
+                                     * is always kept sorted.
                                      *
                                      * The variable is marked
                                      * "mutable" so that it can be
@@ -188,7 +202,7 @@ class IndexSet
                                      * representation of this index
                                      * set.
                                      */
-    mutable std::set<Range> ranges;
+    mutable std::vector<Range> ranges;
 
                                     /**
                                      * True if compress() has been
@@ -280,7 +294,11 @@ IndexSet::add_range (const unsigned int begin,
 
   if (begin != end)
     {
-      ranges.insert (Range(begin,end));
+      const Range new_range(begin,end);
+      ranges.insert (std::lower_bound (ranges.begin(),
+                                      ranges.end(),
+                                      new_range),
+                    new_range);
       is_compressed = false;
     }
 }
@@ -294,7 +312,11 @@ IndexSet::add_index (const unsigned int index)
   Assert (index < index_space_size,
          ExcIndexRange (index, 0, index_space_size));
 
-  ranges.insert (Range(index, index+1));
+  const Range new_range(index, index+1);
+  ranges.insert (std::lower_bound (ranges.begin(),
+                                  ranges.end(),
+                                  new_range),
+                new_range);
   is_compressed = false;
 }
 
@@ -355,7 +377,7 @@ IndexSet::is_element (const unsigned int index) const
                                       // of the following ranges
                                       // because otherwise p would be
                                       // a different iterator
-      std::set<Range>::const_iterator
+      std::vector<Range>::const_iterator
        p = std::upper_bound (ranges.begin(),
                              ranges.end(),
                              Range (index, size()+1));
@@ -396,12 +418,11 @@ unsigned int
 IndexSet::n_elements () const
 {
                                   // make sure we have
-                                  // non-overlapping ranges and
-                                  // individual indices
+                                  // non-overlapping ranges
   compress ();
 
   unsigned int s = 0;
-  for (std::set<Range>::iterator range = ranges.begin();
+  for (std::vector<Range>::iterator range = ranges.begin();
        range != ranges.end();
        ++range)
     s += (range->end - range->begin);
index 4b7e0a2a294a1fe355ad722ce338736e4f31a506..70e99070b076de09e85674bb7d153c2e0c7c303f 100644 (file)
@@ -25,12 +25,11 @@ IndexSet::compress () const
                                   // merged. since they are sorted by
                                   // their first index, determining
                                   // overlap isn't all that hard
-  for (std::set<Range>::iterator
+  for (std::vector<Range>::iterator
         i = ranges.begin();
-       i != ranges.end();
-       ++i)
+       i != ranges.end(); )
     {
-      std::set<Range>::const_iterator
+      std::vector<Range>::iterator
        next = i;
       ++next;
 
@@ -50,33 +49,36 @@ IndexSet::compress () const
 
       if (can_merge == true)
        {
-                                          // delete the old
-                                          // ranges and insert the
-                                          // new range
-         ranges.erase (i, next);
-         ranges.insert (Range(first_index,
-                              last_index));
-
-                                          // then set iterator to
-                                          // the same position as
-                                          // before. in the next
-                                          // step, the loop is then
-                                          // going to increase 'i'
-                                          // by one. note that we
-                                          // don't need to
-                                          // reconsider the same
-                                          // iterator for merging
-                                          // with the next range
-                                          // because we have made
-                                          // sure we gobble up as
-                                          // many of the following
-                                          // ranges as possible
-         i = ranges.lower_bound (Range(first_index,
-                                       last_index));
+                                          // delete the old ranges
+                                          // and insert the new range
+                                          // in place of the previous
+                                          // one
+         *i = Range(first_index, last_index);
+         i = ranges.erase (i+1, next);
        }
+      else
+       ++i;
     }
 
+
+                                  // now compute indices within set
+  unsigned int next_index = 0;
+  for (std::vector<Range>::iterator
+        i = ranges.begin();
+       i != ranges.end();
+       ++i)
+    {
+      i->nth_index_in_set = next_index;
+      next_index += (i->end - i->begin);
+    }
   is_compressed = true;
+
+                                  // check that next_index is
+                                  // correct. needs to be after the
+                                  // previous statement because we
+                                  // otherwise will get into an
+                                  // endless loop
+  Assert (next_index == n_elements(), ExcInternalError());
 }
 
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.