[MOAB-dev] r2547 - MOAB/trunk

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Wed Jan 14 15:42:11 CST 2009


Author: kraftche
Date: 2009-01-14 15:42:11 -0600 (Wed, 14 Jan 2009)
New Revision: 2547

Modified:
   MOAB/trunk/TypeSequenceManager.cpp
Log:
refactor TypeSequenceManager::replace_subsequence -- fixes several bugs

Modified: MOAB/trunk/TypeSequenceManager.cpp
===================================================================
--- MOAB/trunk/TypeSequenceManager.cpp	2009-01-14 21:41:23 UTC (rev 2546)
+++ MOAB/trunk/TypeSequenceManager.cpp	2009-01-14 21:42:11 UTC (rev 2547)
@@ -157,93 +157,91 @@
   iterator i = lower_bound( seq_ptr->start_handle() );
   if (i == end() || (*i)->data() == seq_ptr->data())
     return MB_FAILURE;
+      // new sequence must be a subset of an existing one
   if (seq_ptr->start_handle() < (*i)->start_handle() ||
       seq_ptr->end_handle() > (*i)->end_handle())
     return MB_FAILURE;
+    // new sequence's data must be new also, and cannot intersect
+    // any existing sequence (just require that the data range
+    // matches the sequence range for now)
   if (!seq_ptr->using_entire_data())
     return MB_FAILURE;
-  (*i)->data()->move_tag_data( seq_ptr->data(), tag_server );
+    // copy tag data (move owership of var-len data)
+  SequenceData* const dead_data = (*i)->data();
+  dead_data->move_tag_data( seq_ptr->data(), tag_server );
   
-    // Get the range of sequences that point to the shared
-    // SequenceData instance.  Untimately, should have the
-    // following iterators:
-    // p : first sequence sharing SequenceData
-    // j : last sequence before where seq_ptr will be (or i if no prev seq)
-    // i : first sequence after where seq_ptr will be (or j if no next seq)
-    // n : the last sequence sharing the SequenceData 
-  iterator j = i, n = i;
-  iterator p = (*i)->data()->seqManData.firstSequence;
+    // split sequences sharing old data into two groups:
+    // p->i : first sequence to i
+    // i->n : i to one past last sequence
+  iterator p, n = i;
+  p = (*i)->data()->seqManData.firstSequence;
   for (++n; n != end() && (*n)->data() == (*i)->data(); ++n); 
-  --n;
   
-    // quick case -- replacing entire, single sequence
-  if (n == p && 
-     (*i)->start_handle() == seq_ptr->start_handle() &&
-     (*i)->end_handle() == seq_ptr->end_handle())
-  {
-      // delete old sequence and data (sequence first in case
-      // it needs to reference data during destruction)
+    // First subdivide EntitySequence as necessary
+    // Move i to be the first sequence past the insertion point
+    // such that the new order will be:
+    // [p,i-1] seq_ptr [i,n]
+    // where p == i if no previous sequence
+
+    // Four possible cases:
+    // 0. All entities in sequence are in new sequence
+    // 1. Old entities in sequence before and after new sequence,
+    //    reqiring sequence to be split.
+    // 2. Old entities after new sequence
+    // 3. Old entities before new sequence
+  const bool some_before = ((*i)->start_handle() < seq_ptr->start_handle());
+  const bool some_after  = ((*i)->  end_handle() > seq_ptr->  end_handle());
+    // case 0
+  if (!(some_before || some_after)) {
+      // remove dead sequence from internal lists
     EntitySequence* seq = *i;
-    SequenceData* data = seq->data();
-    if (!seq->using_entire_data())
-      availableList.erase( data );
+    iterator dead = i; ++i;
+    if (p == dead)
+      p = i;
+    sequenceSet.erase( dead );
+
+      // delete old sequence 
     delete seq;
-    delete data;
-    
-      // update structures for tracking sequences
-    iterator d = i++;
-    sequenceSet.erase( d );
-    i = sequenceSet.insert( i, seq_ptr );
-    if (!seq_ptr->using_entire_data())
-      availableList.insert( seq_ptr->data() );
-      
       // make sure lastReferenced isn't stale
     if (lastReferenced == seq)
       lastReferenced = seq_ptr;
-    
-      // each SequenceData has pointer to the first EntitySequence referencing it
-    seq_ptr->data()->seqManData.firstSequence = i;
-    
-    assert( check_valid_data( seq_ptr ) );
-    return MB_SUCCESS;
   }
-  
-    // remove entities in new sequence from current sequence list
-  if ((*i)->start_handle() == seq_ptr->start_handle()) {
-    if (j != p)
-      --j;
-    (*i)->pop_front( seq_ptr->end_handle() - seq_ptr->start_handle() + 1 );
+    // case 1
+  else if (some_before && some_after) {
+    i = split_sequence( i, seq_ptr->start_handle() );
+    (*i)->pop_front( seq_ptr->size() );
   }
-  else if ((*i)->end_handle() == seq_ptr->end_handle()) {
-    (*i)->pop_back( seq_ptr->end_handle() - seq_ptr->start_handle() + 1 );
-    if (i != n)
-      ++i;
+    // case 2
+  else if (some_after) {  
+    (*i)->pop_front( seq_ptr->size() );
   }
-  else {
-    i = split_sequence( i, seq_ptr->start_handle() );
-    (*i)->pop_front( seq_ptr->end_handle() - seq_ptr->start_handle() + 1 );
-    if (n == j) 
-      n = i;
+    // case 3
+  else { // some_before
+    (*i)->pop_back( seq_ptr->size() );
+    ++i;
   }
   
-    // split underlying sequence data
-  SequenceData* dead_data = (*i)->data();
+    // now subdivid the underlying sequence data as necessary
   availableList.erase( dead_data );
   if (p != i) {
-    SequenceData* new_data = (*p)->create_data_subset( (*p)->start_handle(), (*j)->end_handle() );
+    iterator last = i; --last;
+    SequenceData* new_data = (*p)->create_data_subset( (*p)->start_handle(), (*last)->end_handle() );
     new_data->seqManData.firstSequence = p;
-    iterator s = j;
-    for (++s; p != s; ++p)
+    
+    for (; p != i; ++p)
       (*p)->data( new_data );
+      // copy tag data (move owership of var-len data)
     dead_data->move_tag_data( new_data, tag_server );
     if (!(*new_data->seqManData.firstSequence)->using_entire_data())
       availableList.insert( new_data );
   }
-  if (j != n) {
-    SequenceData* new_data = (*n)->create_data_subset( (*i)->start_handle(), (*n)->end_handle() );
+  if (i != n) {
+    iterator last = n; --last;
+    SequenceData* new_data = (*i)->create_data_subset( (*i)->start_handle(), (*last)->end_handle() );
     new_data->seqManData.firstSequence = i;
-    for (++n; i != n; ++i)
+    for (; i != n; ++i)
       (*i)->data( new_data );
+      // copy tag data (move owership of var-len data)
     dead_data->move_tag_data( new_data, tag_server );
     if (!(*new_data->seqManData.firstSequence)->using_entire_data())
       availableList.insert( new_data );
@@ -253,7 +251,6 @@
     // put new sequence in lists
   return insert_sequence( seq_ptr );
 }
-  
     
 
 TypeSequenceManager::iterator TypeSequenceManager::erase( iterator i )




More information about the moab-dev mailing list