MOAB: Mesh Oriented datABase  (version 5.2.1)
TestTypeSequenceManager.cpp
Go to the documentation of this file.
00001 #include "TypeSequenceManager.hpp"
00002 #include "EntitySequence.hpp"
00003 #include "SequenceData.hpp"
00004 #include "TestUtil.hpp"
00005 #include "moab/Error.hpp"
00006 
00007 using namespace moab;
00008 
00009 void test_basic();
00010 void test_lower_bound();
00011 void test_upper_bound();
00012 void test_find();
00013 void test_get_entities();
00014 void test_insert_sequence_merge();
00015 void test_insert_sequence_nomerge();
00016 void test_remove_sequence();
00017 void test_replace_subsequence();
00018 void test_erase();
00019 void test_find_free_handle();
00020 void test_find_free_sequence();
00021 void test_is_free_sequence();
00022 void test_is_free_handle();
00023 
00024 void regression_svn1952();
00025 void regression_svn1958();
00026 void regression_svn1960();
00027 
00028 /* Construct sequence of vertex handles containing
00029    the ID ranges: { [3,7], [100,111], [1001] }
00030    referencing a SequnceData with the range [1,22000]
00031  */
00032 void make_basic_sequence( TypeSequenceManager& seq );
00033 void make_basic_sequence( TypeSequenceManager& seq, EntitySequence*& seq3to7, EntitySequence*& seq100to111,
00034                           EntitySequence*& seq1001 );
00035 
00036 /* Compare expected sequence contents to actual contents.
00037  * Also does some consistency checks.
00038  */
00039 bool seqman_equal( const EntityHandle pair_array[][2], unsigned num_pairs, const TypeSequenceManager& seqman );
00040 
00041 /*
00042  * Insert a sequence into a sequence manager.  Delete passed
00043  * sequence (and optionally SequenceData) if insertion fails.
00044  */
00045 ErrorCode insert_seq( TypeSequenceManager& seqman, EntityHandle start_handle, EntityID count, SequenceData* data,
00046                       bool del_data = false );
00047 
00048 int main()
00049 {
00050     if( RUN_TEST( test_basic ) )
00051     {
00052         printf( "BASIC USE TEST FAILED\nCANNOT TEST FURTHER\n" );
00053         return 1;
00054     }
00055 
00056     int error_count = 0;
00057     error_count += RUN_TEST( test_lower_bound );
00058     error_count += RUN_TEST( test_upper_bound );
00059     error_count += RUN_TEST( test_find );
00060     error_count += RUN_TEST( test_get_entities );
00061     error_count += RUN_TEST( test_insert_sequence_merge );
00062     error_count += RUN_TEST( test_insert_sequence_nomerge );
00063     error_count += RUN_TEST( test_remove_sequence );
00064     error_count += RUN_TEST( test_replace_subsequence );
00065     error_count += RUN_TEST( test_erase );
00066     error_count += RUN_TEST( test_find_free_handle );
00067     error_count += RUN_TEST( test_find_free_sequence );
00068     error_count += RUN_TEST( test_is_free_sequence );
00069 
00070     error_count += RUN_TEST( regression_svn1952 );
00071     error_count += RUN_TEST( regression_svn1958 );
00072     error_count += RUN_TEST( regression_svn1960 );
00073 
00074     if( !error_count )
00075         printf( "ALL TESTS PASSED\n" );
00076     else
00077         printf( "%d TESTS FAILED\n", error_count );
00078 
00079     return error_count;
00080 }
00081 
00082 class DumSeq : public EntitySequence
00083 {
00084   private:
00085     int valsPerEnt;
00086 
00087   public:
00088     DumSeq( EntityHandle start, EntityID count, SequenceData* data2, int vals_per_ent = 0 )
00089         : EntitySequence( start, count, data2 ), valsPerEnt( vals_per_ent )
00090     {
00091     }
00092     DumSeq( SequenceData* data2, int vals_per_ent = 0 )
00093         : EntitySequence( data2->start_handle(), data2->size(), data2 ), valsPerEnt( vals_per_ent )
00094     {
00095     }
00096 
00097     DumSeq( DumSeq& split_from, EntityHandle here )
00098         : EntitySequence( split_from, here ), valsPerEnt( split_from.valsPerEnt )
00099     {
00100     }
00101 
00102     virtual ~DumSeq() {}
00103 
00104     EntitySequence* split( EntityHandle here )
00105     {
00106         return new DumSeq( *this, here );
00107     }
00108 
00109     SequenceData* create_data_subset( EntityHandle a, EntityHandle b ) const
00110     {
00111         return data()->subset( a, b, 0 );
00112     }
00113 
00114     void get_const_memory_use( unsigned long& a, unsigned long& b ) const
00115     {
00116         a = b = 0;
00117     }
00118     unsigned long get_per_entity_memory_use( EntityHandle, EntityHandle ) const
00119     {
00120         return 0;
00121     }
00122 
00123     int values_per_entity() const
00124     {
00125         return valsPerEnt;
00126     }
00127 };
00128 
00129 void make_basic_sequence( TypeSequenceManager& seqman )
00130 {
00131     EntitySequence *s, *t, *u;
00132     make_basic_sequence( seqman, s, t, u );
00133 }
00134 
00135 ErrorCode insert_seq( TypeSequenceManager& seqman, EntityHandle start_handle, EntityID count, SequenceData* data,
00136                       bool del_data )
00137 {
00138     EntitySequence* seq = new DumSeq( start_handle, count, data );
00139     ErrorCode rval      = seqman.insert_sequence( seq );
00140     if( MB_SUCCESS != rval )
00141     {
00142         delete seq;
00143         if( del_data ) delete data;
00144     }
00145     else
00146     {
00147         CHECK( start_handle >= seq->start_handle() );
00148         CHECK( start_handle + count - 1 <= seq->end_handle() );
00149     }
00150     return rval;
00151 }
00152 
00153 void make_basic_sequence( TypeSequenceManager& seqman, EntitySequence*& seq1, EntitySequence*& seq2,
00154                           EntitySequence*& seq3 )
00155 {
00156     CHECK( seqman.empty() );
00157     CHECK_EQUAL( (EntityID)0, seqman.get_number_entities() );
00158 
00159     SequenceData* data = new SequenceData( 0, 1, 22000 );CHECK_ERR( insert_seq( seqman, 3, 5, data ) );CHECK_ERR( insert_seq( seqman, 100, 12, data ) );CHECK_ERR( insert_seq( seqman, 1001, 1, data ) );
00160 
00161     CHECK( !seqman.empty() );
00162     CHECK_EQUAL( (EntityID)18, seqman.get_number_entities() );
00163 
00164     TypeSequenceManager::iterator iter = seqman.begin();
00165     CHECK( iter != seqman.end() );
00166     seq1 = *iter;
00167     CHECK_EQUAL( (EntityHandle)3, seq1->start_handle() );
00168     CHECK_EQUAL( (EntityHandle)7, seq1->end_handle() );
00169     CHECK_EQUAL( data, seq1->data() );
00170     CHECK_EQUAL( (EntityID)5, seq1->size() );
00171 
00172     ++iter;
00173     CHECK( iter != seqman.end() );
00174     seq2 = *iter;
00175     CHECK_EQUAL( (EntityHandle)100, seq2->start_handle() );
00176     CHECK_EQUAL( (EntityHandle)111, seq2->end_handle() );
00177     CHECK_EQUAL( data, seq2->data() );
00178     CHECK_EQUAL( (EntityID)12, seq2->size() );
00179 
00180     ++iter;
00181     seq3 = *iter;
00182     CHECK( iter != seqman.end() );
00183     CHECK_EQUAL( (EntityHandle)1001, seq3->start_handle() );
00184     CHECK_EQUAL( (EntityHandle)1001, seq3->end_handle() );
00185     CHECK_EQUAL( data, seq3->data() );
00186     CHECK_EQUAL( (EntityID)1, seq3->size() );
00187 
00188     ++iter;
00189     CHECK( iter == seqman.end() );
00190 }
00191 
00192 void test_basic()
00193 {
00194     TypeSequenceManager seqman;
00195     make_basic_sequence( seqman );
00196 }
00197 
00198 void test_lower_bound()
00199 {
00200     TypeSequenceManager::const_iterator i;
00201     TypeSequenceManager seqman;
00202     EntitySequence *seq1,  // 3 to 7
00203         *seq2,             // 100 to 111
00204         *seq3;             // 1001
00205     make_basic_sequence( seqman, seq1, seq2, seq3 );
00206 
00207     i = seqman.lower_bound( 2 );
00208     CHECK_EQUAL( seq1, *i );
00209     i = seqman.lower_bound( 3 );
00210     CHECK_EQUAL( seq1, *i );
00211     i = seqman.lower_bound( 4 );
00212     CHECK_EQUAL( seq1, *i );
00213     i = seqman.lower_bound( 7 );
00214     CHECK_EQUAL( seq1, *i );
00215 
00216     i = seqman.lower_bound( 8 );
00217     CHECK_EQUAL( seq2, *i );
00218     i = seqman.lower_bound( 99 );
00219     CHECK_EQUAL( seq2, *i );
00220     i = seqman.lower_bound( 100 );
00221     CHECK_EQUAL( seq2, *i );
00222     i = seqman.lower_bound( 110 );
00223     CHECK_EQUAL( seq2, *i );
00224     i = seqman.lower_bound( 111 );
00225     CHECK_EQUAL( seq2, *i );
00226 
00227     i = seqman.lower_bound( 112 );
00228     CHECK_EQUAL( seq3, *i );
00229     i = seqman.lower_bound( 1000 );
00230     CHECK_EQUAL( seq3, *i );
00231     i = seqman.lower_bound( 1001 );
00232     CHECK_EQUAL( seq3, *i );
00233 
00234     i = seqman.lower_bound( 1002 );
00235     CHECK( i == seqman.end() );
00236 }
00237 
00238 void test_upper_bound()
00239 {
00240     TypeSequenceManager::const_iterator i;
00241     TypeSequenceManager seqman;
00242     EntitySequence *seq1,  // 3 to 7
00243         *seq2,             // 100 to 111
00244         *seq3;             // 1001
00245     make_basic_sequence( seqman, seq1, seq2, seq3 );
00246 
00247     i = seqman.upper_bound( 2 );
00248     CHECK_EQUAL( seq1, *i );
00249 
00250     i = seqman.upper_bound( 3 );
00251     CHECK_EQUAL( seq2, *i );
00252     i = seqman.upper_bound( 4 );
00253     CHECK_EQUAL( seq2, *i );
00254     i = seqman.upper_bound( 7 );
00255     CHECK_EQUAL( seq2, *i );
00256     i = seqman.upper_bound( 8 );
00257     CHECK_EQUAL( seq2, *i );
00258     i = seqman.upper_bound( 99 );
00259     CHECK_EQUAL( seq2, *i );
00260 
00261     i = seqman.upper_bound( 100 );
00262     CHECK_EQUAL( seq3, *i );
00263     i = seqman.upper_bound( 110 );
00264     CHECK_EQUAL( seq3, *i );
00265     i = seqman.upper_bound( 111 );
00266     CHECK_EQUAL( seq3, *i );
00267     i = seqman.upper_bound( 112 );
00268     CHECK_EQUAL( seq3, *i );
00269     i = seqman.upper_bound( 1000 );
00270     CHECK_EQUAL( seq3, *i );
00271 
00272     i = seqman.upper_bound( 1001 );
00273     CHECK( i == seqman.end() );
00274 }
00275 
00276 void test_find()
00277 {
00278     TypeSequenceManager seqman;
00279     EntitySequence *seq1,  // 3 to 7
00280         *seq2,             // 100 to 111
00281         *seq3,             // 1001
00282         *seq;
00283     make_basic_sequence( seqman, seq1, seq2, seq3 );
00284 
00285     seq = seqman.find( 2 );
00286     CHECK_EQUAL( NULL, seq );
00287     seq = seqman.find( 3 );
00288     CHECK_EQUAL( seq1, seq );
00289     seq = seqman.find( 4 );
00290     CHECK_EQUAL( seq1, seq );
00291     seq = seqman.find( 7 );
00292     CHECK_EQUAL( seq1, seq );
00293     seq = seqman.find( 8 );
00294     CHECK_EQUAL( NULL, seq );
00295 
00296     seq = seqman.find( 99 );
00297     CHECK_EQUAL( NULL, seq );
00298     seq = seqman.find( 100 );
00299     CHECK_EQUAL( seq2, seq );
00300     seq = seqman.find( 110 );
00301     CHECK_EQUAL( seq2, seq );
00302     seq = seqman.find( 111 );
00303     CHECK_EQUAL( seq2, seq );
00304     seq = seqman.find( 112 );
00305     CHECK_EQUAL( NULL, seq );
00306 
00307     seq = seqman.find( 1000 );
00308     CHECK_EQUAL( NULL, seq );
00309     seq = seqman.find( 1001 );
00310     CHECK_EQUAL( seq3, seq );
00311     seq = seqman.find( 1002 );
00312     CHECK_EQUAL( NULL, seq );
00313 }
00314 
00315 bool seqman_equal( const EntityHandle pair_array[][2], unsigned num_pairs, const TypeSequenceManager& seqman )
00316 {
00317     unsigned i;
00318     TypeSequenceManager::const_iterator j = seqman.begin();
00319     EntitySequence* seq                   = 0;
00320     for( i = 0; i < num_pairs; ++i, ++j )
00321     {
00322         if( j == seqman.end() ) break;
00323 
00324         if( seq && seq->end_handle() >= ( *j )->start_handle() )
00325         {
00326             printf( "Sequence [%lu,%lu] overlaps sequence [%lu,%lu]\n",
00327                     (unsigned long)ID_FROM_HANDLE( seq->start_handle() ),
00328                     (unsigned long)ID_FROM_HANDLE( seq->end_handle() ),
00329                     (unsigned long)ID_FROM_HANDLE( ( *j )->start_handle() ),
00330                     (unsigned long)ID_FROM_HANDLE( ( *j )->end_handle() ) );
00331             return false;
00332         }
00333 
00334         if( seq && seq->data() != ( *j )->data() && seq->data()->end_handle() >= ( *j )->data()->start_handle() )
00335         {
00336             printf( "SequenceData [%lu,%lu] overlaps SequenceData [%lu,%lu]\n",
00337                     (unsigned long)ID_FROM_HANDLE( seq->data()->start_handle() ),
00338                     (unsigned long)ID_FROM_HANDLE( seq->data()->end_handle() ),
00339                     (unsigned long)ID_FROM_HANDLE( ( *j )->data()->start_handle() ),
00340                     (unsigned long)ID_FROM_HANDLE( ( *j )->data()->end_handle() ) );
00341             return false;
00342         }
00343 
00344         seq = *j;
00345         if( seq->start_handle() > seq->end_handle() )
00346         {
00347             printf( "Inverted sequence [%lu,%lu]\n", (unsigned long)ID_FROM_HANDLE( seq->start_handle() ),
00348                     (unsigned long)ID_FROM_HANDLE( seq->end_handle() ) );
00349             return false;
00350         }
00351 
00352         if( pair_array[i][0] != seq->start_handle() || pair_array[i][1] != seq->end_handle() ) break;
00353 
00354         if( seq->data()->start_handle() > seq->start_handle() || seq->data()->end_handle() < seq->end_handle() )
00355         {
00356             printf( "Sequence [%lu,%lu] has data [%lu,%lu]\n", (unsigned long)ID_FROM_HANDLE( seq->start_handle() ),
00357                     (unsigned long)ID_FROM_HANDLE( seq->end_handle() ),
00358                     (unsigned long)ID_FROM_HANDLE( seq->data()->start_handle() ),
00359                     (unsigned long)ID_FROM_HANDLE( seq->data()->end_handle() ) );
00360             return false;
00361         }
00362     }
00363 
00364     if( i == num_pairs && j == seqman.end() ) return true;
00365 
00366     if( i < num_pairs )
00367         printf( "Sequence Mismatch: Expected: [%lu,%lu], got ", (unsigned long)ID_FROM_HANDLE( pair_array[i][0] ),
00368                 (unsigned long)ID_FROM_HANDLE( pair_array[i][1] ) );
00369     else
00370         printf( "Sequence Mismatch: Expected END, got " );
00371 
00372     if( j == seqman.end() )
00373         printf( "END.\n" );
00374     else
00375         printf( "[%lu,%lu]\n", (unsigned long)ID_FROM_HANDLE( ( *j )->start_handle() ),
00376                 (unsigned long)ID_FROM_HANDLE( ( *j )->end_handle() ) );
00377 
00378     return false;
00379 }
00380 
00381 void test_get_entities()
00382 {
00383     TypeSequenceManager seqman;
00384     make_basic_sequence( seqman );
00385 
00386     CHECK( !seqman.empty() );
00387     CHECK_EQUAL( (EntityID)18, seqman.get_number_entities() );
00388 
00389     Range entities;
00390     seqman.get_entities( entities );
00391     CHECK_EQUAL( (size_t)18, entities.size() );
00392 
00393     EntityHandle pairs[][2] = { { 3, 7 }, { 100, 111 }, { 1001, 1001 } };
00394     CHECK( seqman_equal( pairs, 3, seqman ) );
00395 }
00396 
00397 void test_insert_sequence_merge()
00398 {
00399     TypeSequenceManager seqman;
00400     make_basic_sequence( seqman );
00401     SequenceData* data = ( *seqman.begin() )->data();
00402 
00403     // append a sequence
00404     CHECK_ERR( insert_seq( seqman, 1003, 1, data ) );
00405     EntityHandle exp1[][2] = { { 3, 7 }, { 100, 111 }, { 1001, 1001 }, { 1003, 1003 } };
00406     CHECK( seqman_equal( exp1, 4, seqman ) );
00407 
00408     // prepend a sequence
00409     CHECK_ERR( insert_seq( seqman, 1, 1, data ) );
00410     EntityHandle exp2[][2] = { { 1, 1 }, { 3, 7 }, { 100, 111 }, { 1001, 1001 }, { 1003, 1003 } };
00411     CHECK( seqman_equal( exp2, 5, seqman ) );
00412 
00413     // insert sequence in middle
00414     CHECK_ERR( insert_seq( seqman, 150, 11, data ) );
00415     EntityHandle exp3[][2] = { { 1, 1 }, { 3, 7 }, { 100, 111 }, { 150, 160 }, { 1001, 1001 }, { 1003, 1003 } };
00416     CHECK( seqman_equal( exp3, 6, seqman ) );
00417 
00418     // merge sequence with predecessor
00419     CHECK_ERR( insert_seq( seqman, 8, 13, data ) );
00420     EntityHandle exp4[][2] = { { 1, 1 }, { 3, 20 }, { 100, 111 }, { 150, 160 }, { 1001, 1001 }, { 1003, 1003 } };
00421     CHECK( seqman_equal( exp4, 6, seqman ) );
00422 
00423     // merge sequence with following one
00424     CHECK_ERR( insert_seq( seqman, 87, 13, data ) );
00425     EntityHandle exp5[][2] = { { 1, 1 }, { 3, 20 }, { 87, 111 }, { 150, 160 }, { 1001, 1001 }, { 1003, 1003 } };
00426     CHECK( seqman_equal( exp5, 6, seqman ) );
00427 
00428     // merge sequence with two adjacent ones
00429     CHECK_ERR( insert_seq( seqman, 2, 1, data ) );
00430     EntityHandle exp6[][2] = { { 1, 20 }, { 87, 111 }, { 150, 160 }, { 1001, 1001 }, { 1003, 1003 } };
00431     CHECK( seqman_equal( exp6, 5, seqman ) );
00432 
00433     // try to insert a sequence that overlaps on the end
00434     CHECK_EQUAL( MB_ALREADY_ALLOCATED, insert_seq( seqman, 900, 1001, data ) );
00435 
00436     // try to insert a sequence that overlaps at the start
00437     CHECK_EQUAL( MB_ALREADY_ALLOCATED, insert_seq( seqman, 111, 140, data ) );
00438 }
00439 
00440 void test_insert_sequence_nomerge()
00441 {
00442     TypeSequenceManager seqman;
00443 
00444     // make sure inserting a sequence w/out a SequenceData fails
00445     CHECK_EQUAL( MB_FAILURE, insert_seq( seqman, 1, 5, NULL ) );
00446     CHECK( seqman.empty() );
00447 
00448     // Now set up a TypeSequenceManager for testing
00449 
00450     // Insert an EntitySequence for which the corresponding SequenceData
00451     // is exactly the same size.
00452     SequenceData* data1 = new SequenceData( 0, 3, 7 );
00453     DumSeq* seq         = new DumSeq( data1 );
00454     ErrorCode rval      = seqman.insert_sequence( seq );CHECK_ERR( rval );
00455     if( MB_SUCCESS != rval )
00456     {
00457         delete seq;
00458         delete data1;
00459         return;
00460     }
00461 
00462     // Insert an EntitySequence with additional room on both ends of
00463     // the SequenceData
00464     SequenceData* data2 = new SequenceData( 0, 100, 999 );
00465     seq                 = new DumSeq( 200, 100, data2 );
00466     rval                = seqman.insert_sequence( seq );CHECK_ERR( rval );
00467     if( MB_SUCCESS != rval )
00468     {
00469         delete seq;
00470         delete data2;
00471         return;
00472     }
00473 
00474     // Insert another EntitySequence sharing the previous SequenceData
00475     seq  = new DumSeq( 400, 100, data2 );
00476     rval = seqman.insert_sequence( seq );CHECK_ERR( rval );
00477     if( MB_SUCCESS != rval )
00478     {
00479         delete seq;
00480         return;
00481     }
00482 
00483     // Setup complete, begin tests
00484 
00485     // Test inserting sequence that appends an existing sequence
00486     // but overlaps underling SequenceData boundary
00487     SequenceData* data = new SequenceData( 0, 999, 1000 );
00488     seq                = new DumSeq( data );
00489     rval               = seqman.insert_sequence( seq );
00490     CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
00491     delete seq;
00492     delete data;
00493 
00494     // Test inserting sequence that prepends an existing sequence
00495     // but overlaps underling SequenceData boundary
00496     data = new SequenceData( 0, 50, 199 );
00497     seq  = new DumSeq( data );
00498     rval = seqman.insert_sequence( seq );
00499     CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
00500     delete seq;
00501     delete data;
00502 
00503     // Test fits within existing, but has different SequenceData
00504     data = new SequenceData( 0, 500, 599 );
00505     seq  = new DumSeq( data );
00506     rval = seqman.insert_sequence( seq );
00507     CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
00508     delete seq;
00509     delete data;
00510 
00511     // Make sure we're starting out with what we expect
00512     EntityHandle exp1[][2] = { { 3, 7 }, { 200, 299 }, { 400, 499 } };
00513     CHECK( seqman_equal( exp1, 3, seqman ) );
00514 
00515     // Test fits within existing, and has same data
00516     CHECK_ERR( insert_seq( seqman, 600, 100, data2 ) );
00517     EntityHandle exp2[][2] = { { 3, 7 }, { 200, 299 }, { 400, 499 }, { 600, 699 } };
00518     CHECK( seqman_equal( exp2, 4, seqman ) );
00519 
00520     // Test is entirely outside existing data
00521     CHECK_ERR( insert_seq( seqman, 2000, 2, new SequenceData( 0, 2000, 2001 ), true ) );
00522     EntityHandle exp3[][2] = { { 3, 7 }, { 200, 299 }, { 400, 499 }, { 600, 699 }, { 2000, 2001 } };
00523     CHECK( seqman_equal( exp3, 5, seqman ) );
00524 
00525     // Test abutts end of existing data
00526     CHECK_ERR( insert_seq( seqman, 1000, 6, new SequenceData( 0, 1000, 1005 ), true ) );
00527     EntityHandle exp4[][2] = { { 3, 7 }, { 200, 299 }, { 400, 499 }, { 600, 699 }, { 1000, 1005 }, { 2000, 2001 } };
00528     CHECK( seqman_equal( exp4, 6, seqman ) );
00529 
00530     // Test abutts beginning of existing data
00531     CHECK_ERR( insert_seq( seqman, 50, 50, new SequenceData( 0, 50, 99 ), true ) );
00532     EntityHandle exp5[][2] = { { 3, 7 },     { 50, 99 },     { 200, 299 },  { 400, 499 },
00533                                { 600, 699 }, { 1000, 1005 }, { 2000, 2001 } };
00534     CHECK( seqman_equal( exp5, 7, seqman ) );
00535 }
00536 
00537 void test_remove_sequence()
00538 {
00539     TypeSequenceManager seqman;
00540     EntitySequence *seq1,  // 3 to 7
00541         *seq2,             // 100 to 111
00542         *seq3;             // 1001
00543     make_basic_sequence( seqman, seq1, seq2, seq3 );
00544 
00545     // test removing something that hasn't been inserted
00546     bool last;
00547     DumSeq junk( 3, 5, NULL );
00548     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, seqman.remove_sequence( &junk, last ) );
00549     EntityHandle exp1[][2] = { { 3, 7 }, { 100, 111 }, { 1001, 1001 } };
00550     CHECK( seqman_equal( exp1, 3, seqman ) );
00551 
00552     // remove the middle sequence
00553     CHECK_ERR( seqman.remove_sequence( seq2, last ) );
00554     CHECK( !last );
00555     delete seq2;
00556 
00557     // remove the first sequence
00558     CHECK_ERR( seqman.remove_sequence( seq1, last ) );
00559     CHECK( !last );
00560     delete seq1;
00561 
00562     // remove the last sequence
00563     CHECK_ERR( seqman.remove_sequence( seq3, last ) );
00564     CHECK( last );
00565     SequenceData* data = seq3->data();
00566     delete seq3;
00567     delete data;
00568 }
00569 
00570 void test_replace_subsequence()
00571 {
00572     ErrorCode rval;
00573     TypeSequenceManager seqman;
00574 
00575     // create an initial set
00576     SequenceData* data1 = new SequenceData( 0, 51, 950 );
00577     rval                = insert_seq( seqman, 101, 100, data1, true );CHECK_ERR( rval );
00578     if( MB_SUCCESS != rval )
00579     {
00580         // data1 has been deleted by insert_seq call above
00581         return;
00582     }
00583     rval = insert_seq( seqman, 301, 300, data1 );CHECK_ERR( rval );
00584     rval = insert_seq( seqman, 701, 100, data1 );CHECK_ERR( rval );
00585 
00586     // try a sequence that is outside all existing data
00587     SequenceData* data = new SequenceData( 0, 10, 20 );
00588     DumSeq* seq        = new DumSeq( data );
00589     rval               = seqman.replace_subsequence( seq, 0, 0 );
00590     CHECK_EQUAL( MB_FAILURE, rval );
00591     delete seq;
00592     delete data;
00593 
00594     // try a sequence that overlaps the start of the data
00595     data = new SequenceData( 0, 40, 60 );
00596     seq  = new DumSeq( data );
00597     rval = seqman.replace_subsequence( seq, 0, 0 );
00598     CHECK_EQUAL( MB_FAILURE, rval );
00599     delete seq;
00600     delete data;
00601 
00602     // try a sequence that is within the data but not within any sequence
00603     data = new SequenceData( 0, 60, 70 );
00604     seq  = new DumSeq( data );
00605     rval = seqman.replace_subsequence( seq, 0, 0 );
00606     CHECK_EQUAL( MB_FAILURE, rval );
00607     delete seq;
00608     delete data;
00609 
00610     // try a sequence that overlaps an existing sequence
00611     data = new SequenceData( 0, 60, 101 );
00612     seq  = new DumSeq( data );
00613     rval = seqman.replace_subsequence( seq, 0, 0 );
00614     CHECK_EQUAL( MB_FAILURE, rval );
00615     delete seq;
00616     delete data;
00617 
00618     // try a sequence that should work, but with a SequenceData that
00619     // overlaps an existing sequence
00620     data = new SequenceData( 0, 150, 200 );
00621     seq  = new DumSeq( 190, 200, data );
00622     rval = seqman.replace_subsequence( seq, 0, 0 );
00623     CHECK_EQUAL( MB_FAILURE, rval );
00624     delete seq;
00625     delete data;
00626 
00627     // check that we're starting with what we expect
00628     EntityHandle exp1[][2] = { { 101, 200 }, { 301, 600 }, { 701, 800 } };
00629     CHECK( seqman_equal( exp1, 3, seqman ) );
00630 
00631     // split at start of sequence
00632     data = new SequenceData( 0, 101, 105 );
00633     seq  = new DumSeq( data );
00634     rval = seqman.replace_subsequence( seq, 0, 0 );CHECK_ERR( rval );
00635     if( MB_SUCCESS != rval )
00636     {
00637         delete seq;
00638         delete data;
00639         return;
00640     }
00641     EntityHandle exp2[][2] = { { 101, 105 }, { 106, 200 }, { 301, 600 }, { 701, 800 } };
00642     CHECK( seqman_equal( exp2, 4, seqman ) );
00643 
00644     // split at end of sequence
00645     data = new SequenceData( 0, 750, 800 );
00646     seq  = new DumSeq( data );
00647     rval = seqman.replace_subsequence( seq, 0, 0 );CHECK_ERR( rval );
00648     if( MB_SUCCESS != rval )
00649     {
00650         delete seq;
00651         delete data;
00652         return;
00653     }
00654     EntityHandle exp3[][2] = { { 101, 105 }, { 106, 200 }, { 301, 600 }, { 701, 749 }, { 750, 800 } };
00655     CHECK( seqman_equal( exp3, 5, seqman ) );
00656 
00657     // split at middle of sequence
00658     data = new SequenceData( 0, 400, 499 );
00659     seq  = new DumSeq( data );
00660     rval = seqman.replace_subsequence( seq, 0, 0 );CHECK_ERR( rval );
00661     if( MB_SUCCESS != rval )
00662     {
00663         delete seq;
00664         delete data;
00665         return;
00666     }
00667     EntityHandle exp4[][2] = { { 101, 105 }, { 106, 200 }, { 301, 399 }, { 400, 499 },
00668                                { 500, 600 }, { 701, 749 }, { 750, 800 } };
00669     CHECK( seqman_equal( exp4, 7, seqman ) );
00670 }
00671 
00672 void test_erase()
00673 {
00674     TypeSequenceManager seqman;
00675     make_basic_sequence( seqman );
00676     Error eh;
00677 
00678     // verify initial state
00679     EntityHandle exp1[][2] = { { 3, 7 }, { 100, 111 }, { 1001, 1001 } };
00680     CHECK( seqman_equal( exp1, 3, seqman ) );
00681 
00682     // try erasing invalid handles at start of existing sequence
00683     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, seqman.erase( &eh, 1000, 1001 ) );
00684     // try erasing invalid entities at end of existing sequence
00685     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, seqman.erase( &eh, 3, 8 ) );
00686     // verify initial state
00687     CHECK( seqman_equal( exp1, 3, seqman ) );
00688 
00689     // erase from front of sequence
00690     CHECK_ERR( seqman.erase( &eh, 3, 6 ) );
00691     EntityHandle exp2[][2] = { { 7, 7 }, { 100, 111 }, { 1001, 1001 } };
00692     CHECK( seqman_equal( exp2, 3, seqman ) );
00693 
00694     // erase from end of sequence
00695     CHECK_ERR( seqman.erase( &eh, 110, 111 ) );
00696     EntityHandle exp3[][2] = { { 7, 7 }, { 100, 109 }, { 1001, 1001 } };
00697     CHECK( seqman_equal( exp3, 3, seqman ) );
00698 
00699     // erase from middle of sequence
00700     CHECK_ERR( seqman.erase( &eh, 105, 107 ) );
00701     EntityHandle exp4[][2] = { { 7, 7 }, { 100, 104 }, { 108, 109 }, { 1001, 1001 } };
00702     CHECK( seqman_equal( exp4, 4, seqman ) );
00703 
00704     // erase sequence
00705     CHECK_ERR( seqman.erase( &eh, 7, 7 ) );
00706     EntityHandle exp5[][2] = { { 100, 104 }, { 108, 109 }, { 1001, 1001 } };
00707     CHECK( seqman_equal( exp5, 3, seqman ) );
00708 
00709     // erase sequence
00710     CHECK_ERR( seqman.erase( &eh, 108, 109 ) );
00711     EntityHandle exp6[][2] = { { 100, 104 }, { 1001, 1001 } };
00712     CHECK( seqman_equal( exp6, 2, seqman ) );
00713 
00714     // erase sequence
00715     CHECK_ERR( seqman.erase( &eh, 100, 104 ) );
00716     EntityHandle exp7[][2] = { { 1001, 1001 } };
00717     CHECK( seqman_equal( exp7, 1, seqman ) );
00718 
00719     // erase sequence
00720     CHECK_ERR( seqman.erase( &eh, 1001, 1001 ) );
00721     CHECK( seqman.empty() );
00722 }
00723 
00724 void test_find_free_handle()
00725 {
00726     bool append;
00727     TypeSequenceManager::iterator seq;
00728     TypeSequenceManager seqman;
00729     make_basic_sequence( seqman );  // { [3,7], [100,111], [1001] }
00730 
00731     seq = seqman.find_free_handle( 0, MB_END_ID, append );
00732     CHECK( seq != seqman.end() );
00733     // expect the first available handle (2).
00734     CHECK_EQUAL( (EntityHandle)3, ( *seq )->start_handle() );
00735     CHECK_EQUAL( (EntityHandle)7, ( *seq )->end_handle() );
00736     CHECK( !append );
00737 
00738     // Expect end() if no adjacent sequence
00739     seq = seqman.find_free_handle( 9, 98, append );
00740     CHECK( seq == seqman.end() );
00741 
00742     // Try a limited handle range
00743     seq = seqman.find_free_handle( 8, 99, append );
00744     CHECK( seq != seqman.end() );
00745     // expect the first available handle (8).
00746     CHECK_EQUAL( (EntityHandle)3, ( *seq )->start_handle() );
00747     CHECK_EQUAL( (EntityHandle)7, ( *seq )->end_handle() );
00748     CHECK( append );
00749 
00750     // Try an unambigious case (above tests have multiple
00751     // possible answers, were we assume the first available
00752     // handle).
00753     seq = seqman.find_free_handle( 8, 98, append );
00754     CHECK( seq != seqman.end() );
00755     CHECK_EQUAL( (EntityHandle)3, ( *seq )->start_handle() );
00756     CHECK_EQUAL( (EntityHandle)7, ( *seq )->end_handle() );
00757     CHECK( append );
00758 
00759     // Try an unambigious case (above tests have multiple
00760     // possible answers, were we assume the first available
00761     // handle).
00762     seq = seqman.find_free_handle( 9, 99, append );
00763     CHECK( seq != seqman.end() );
00764     CHECK_EQUAL( (EntityHandle)100, ( *seq )->start_handle() );
00765     CHECK_EQUAL( (EntityHandle)111, ( *seq )->end_handle() );
00766     CHECK( !append );
00767 
00768     // Try a case where the expected result handle
00769     // is in the middle of the input range.
00770     seq = seqman.find_free_handle( 900, 1100, append );
00771     CHECK( seq != seqman.end() );
00772     CHECK_EQUAL( (EntityHandle)1001, ( *seq )->start_handle() );
00773     CHECK_EQUAL( (EntityHandle)1001, ( *seq )->end_handle() );
00774     // Expect first available handle
00775     CHECK( !append );
00776 }
00777 
00778 void test_find_free_sequence()
00779 {
00780     EntityHandle start;
00781     SequenceData* data = 0;
00782     EntityID data_size = 0;
00783     TypeSequenceManager seqman;
00784     make_basic_sequence( seqman );  // { [3,7], [100,111], [1001] }
00785     SequenceData* expdata = ( *seqman.begin() )->data();
00786 
00787     start = seqman.find_free_sequence( 2, 1, 3, data, data_size );
00788     CHECK_EQUAL( expdata, data );
00789     CHECK_EQUAL( (EntityHandle)1, start );
00790 
00791     start = seqman.find_free_sequence( 3, 1, 7, data, data_size );
00792     CHECK_EQUAL( (EntityHandle)0, start );
00793     CHECK_EQUAL( NULL, data );
00794 
00795     start = seqman.find_free_sequence( 30, 1, 120, data, data_size );
00796     CHECK_EQUAL( expdata, data );
00797     CHECK( start == 8 || start == 70 );
00798 
00799     start = seqman.find_free_sequence( 10, 92, 999, data, data_size );
00800     CHECK_EQUAL( expdata, data );
00801     CHECK_EQUAL( (EntityHandle)112, start );
00802 
00803     start = seqman.find_free_sequence( 100, 1, 600, data, data_size );
00804     CHECK_EQUAL( expdata, data );
00805     CHECK_EQUAL( (EntityHandle)112, start );
00806 
00807     start = seqman.find_free_sequence( 1000, 1, MB_END_ID, data, data_size );
00808     CHECK_EQUAL( expdata, data );
00809     CHECK_EQUAL( (EntityHandle)1002, start );
00810 
00811     start = seqman.find_free_sequence( 980, 1, 1800, data, data_size );
00812     CHECK_EQUAL( (EntityHandle)0, start );
00813     CHECK_EQUAL( NULL, data );
00814 }
00815 
00816 void test_is_free_sequence()
00817 {
00818     SequenceData* data = 0;
00819     TypeSequenceManager seqman;
00820     make_basic_sequence( seqman );  // { [3,7], [100,111], [1001] }
00821     SequenceData* expdata = ( *seqman.begin() )->data();
00822 
00823     CHECK( !seqman.is_free_sequence( 1, 3, data ) );
00824     CHECK( seqman.is_free_sequence( 1, 2, data ) );
00825     CHECK_EQUAL( expdata, data );
00826     CHECK( !seqman.is_free_sequence( 7, 93, data ) );
00827     CHECK( !seqman.is_free_sequence( 8, 93, data ) );
00828     CHECK( seqman.is_free_sequence( 8, 92, data ) );
00829     CHECK_EQUAL( expdata, data );
00830     CHECK( !seqman.is_free_sequence( 111, 890, data ) );
00831     CHECK( !seqman.is_free_sequence( 112, 890, data ) );
00832     CHECK( seqman.is_free_sequence( 112, 879, data ) );
00833     CHECK_EQUAL( expdata, data );
00834     CHECK( seqman.is_free_sequence( 1002, 1, data ) );
00835     CHECK_EQUAL( expdata, data );
00836     CHECK( seqman.is_free_sequence( 2000, 20000, data ) );
00837     CHECK_EQUAL( expdata, data );
00838 }
00839 
00840 void test_is_free_handle()
00841 {
00842     // Construct a TypeSequenceManager with the following data:
00843     // EntitySequence: |[1,500]|   |[601,1000]|       |[2500,2599]|    |[2800,2999]|
00844     // SequenceData:   |       [1,1000]       |    |         [2001,3000]            |
00845     ErrorCode rval;
00846     TypeSequenceManager seqman;
00847     SequenceData* data1 = new SequenceData( 0, 1, 1000 );
00848     SequenceData* data2 = new SequenceData( 0, 2001, 3000 );
00849     rval                = insert_seq( seqman, 1, 500, data1, true );CHECK_ERR( rval );
00850     if( MB_SUCCESS != rval )
00851     {
00852         // data1 has been deleted by insert_seq call above
00853         return;
00854     }
00855     rval = insert_seq( seqman, 601, 400, data1, false );CHECK_ERR( rval );
00856     rval = insert_seq( seqman, 2500, 100, data2, true );CHECK_ERR( rval );
00857     if( MB_SUCCESS != rval )
00858     {
00859         // data2 has been deleted by insert_seq call above
00860         return;
00861     }
00862     rval = insert_seq( seqman, 2800, 200, data2, false );CHECK_ERR( rval );
00863 
00864     // Begin tests
00865     TypeSequenceManager::iterator seq;
00866     SequenceData* data;
00867     EntityHandle first, last;
00868 
00869     // Test handle in use
00870 
00871     CHECK_EQUAL( MB_ALREADY_ALLOCATED, seqman.is_free_handle( 1, seq, data, first, last ) );
00872     CHECK_EQUAL( MB_ALREADY_ALLOCATED, seqman.is_free_handle( 300, seq, data, first, last ) );
00873     CHECK_EQUAL( MB_ALREADY_ALLOCATED, seqman.is_free_handle( 500, seq, data, first, last ) );
00874     CHECK_EQUAL( MB_ALREADY_ALLOCATED, seqman.is_free_handle( 601, seq, data, first, last ) );
00875     CHECK_EQUAL( MB_ALREADY_ALLOCATED, seqman.is_free_handle( 2500, seq, data, first, last ) );
00876     CHECK_EQUAL( MB_ALREADY_ALLOCATED, seqman.is_free_handle( 2599, seq, data, first, last ) );
00877     CHECK_EQUAL( MB_ALREADY_ALLOCATED, seqman.is_free_handle( 2800, seq, data, first, last ) );
00878     CHECK_EQUAL( MB_ALREADY_ALLOCATED, seqman.is_free_handle( 2999, seq, data, first, last ) );
00879 
00880     // Test prepend to sequence
00881 
00882     seq   = seqman.end();
00883     data  = 0;
00884     first = last = 0;
00885     CHECK( seqman.is_free_handle( 600, seq, data, first, last ) );
00886     CHECK( seq != seqman.end() );
00887     CHECK_EQUAL( (EntityHandle)601, ( *seq )->start_handle() );
00888     CHECK_EQUAL( data1, data );
00889     CHECK_EQUAL( (EntityHandle)600, first );
00890     CHECK_EQUAL( (EntityHandle)600, last );
00891 
00892     seq   = seqman.end();
00893     data  = 0;
00894     first = last = 0;
00895     CHECK( seqman.is_free_handle( 2499, seq, data, first, last ) );
00896     CHECK( seq != seqman.end() );
00897     CHECK_EQUAL( (EntityHandle)2500, ( *seq )->start_handle() );
00898     CHECK_EQUAL( data2, data );
00899     CHECK_EQUAL( (EntityHandle)2499, first );
00900     CHECK_EQUAL( (EntityHandle)2499, last );
00901 
00902     seq   = seqman.end();
00903     data  = 0;
00904     first = last = 0;
00905     CHECK( seqman.is_free_handle( 2799, seq, data, first, last ) );
00906     CHECK( seq != seqman.end() );
00907     CHECK_EQUAL( (EntityHandle)2800, ( *seq )->start_handle() );
00908     CHECK_EQUAL( data2, data );
00909     CHECK_EQUAL( (EntityHandle)2799, first );
00910     CHECK_EQUAL( (EntityHandle)2799, last );
00911 
00912     // Test append to sequence
00913 
00914     seq   = seqman.end();
00915     data  = 0;
00916     first = last = 0;
00917     CHECK( seqman.is_free_handle( 501, seq, data, first, last ) );
00918     CHECK( seq != seqman.end() );
00919     CHECK_EQUAL( (EntityHandle)1, ( *seq )->start_handle() );
00920     CHECK_EQUAL( data1, data );
00921     CHECK_EQUAL( (EntityHandle)501, first );
00922     CHECK_EQUAL( (EntityHandle)501, last );
00923 
00924     seq   = seqman.end();
00925     data  = 0;
00926     first = last = 0;
00927     CHECK( seqman.is_free_handle( 2600, seq, data, first, last ) );
00928     CHECK( seq != seqman.end() );
00929     CHECK_EQUAL( (EntityHandle)2500, ( *seq )->start_handle() );
00930     CHECK_EQUAL( data2, data );
00931     CHECK_EQUAL( (EntityHandle)2600, first );
00932     CHECK_EQUAL( (EntityHandle)2600, last );
00933 
00934     seq   = seqman.end();
00935     data  = 0;
00936     first = last = 0;
00937     CHECK( seqman.is_free_handle( 3000, seq, data, first, last ) );
00938     CHECK( seq != seqman.end() );
00939     CHECK_EQUAL( (EntityHandle)2800, ( *seq )->start_handle() );
00940     CHECK_EQUAL( data2, data );
00941     CHECK_EQUAL( (EntityHandle)3000, first );
00942     CHECK_EQUAL( (EntityHandle)3000, last );
00943 
00944     // Test new sequence in existing SequenceData
00945 
00946     seq   = seqman.end();
00947     data  = 0;
00948     first = last = 0;
00949     CHECK( seqman.is_free_handle( 502, seq, data, first, last ) );
00950     CHECK( seqman.end() == seq );
00951     CHECK_EQUAL( data1, data );
00952     CHECK_EQUAL( (EntityHandle)501, first );
00953     CHECK_EQUAL( (EntityHandle)600, last );
00954 
00955     seq   = seqman.end();
00956     data  = 0;
00957     first = last = 0;
00958     CHECK( seqman.is_free_handle( 599, seq, data, first, last ) );
00959     CHECK( seqman.end() == seq );
00960     CHECK_EQUAL( data1, data );
00961     CHECK_EQUAL( (EntityHandle)501, first );
00962     CHECK_EQUAL( (EntityHandle)600, last );
00963 
00964     seq   = seqman.end();
00965     data  = 0;
00966     first = last = 0;
00967     CHECK( seqman.is_free_handle( 2001, seq, data, first, last ) );
00968     CHECK( seqman.end() == seq );
00969     CHECK_EQUAL( data2, data );
00970     CHECK_EQUAL( (EntityHandle)2001, first );
00971     CHECK_EQUAL( (EntityHandle)2499, last );
00972 
00973     seq   = seqman.end();
00974     data  = 0;
00975     first = last = 0;
00976     CHECK( seqman.is_free_handle( 2498, seq, data, first, last ) );
00977     CHECK( seqman.end() == seq );
00978     CHECK_EQUAL( data2, data );
00979     CHECK_EQUAL( (EntityHandle)2001, first );
00980     CHECK_EQUAL( (EntityHandle)2499, last );
00981 
00982     // Test new SequenceData
00983 
00984     seq   = seqman.end();
00985     data  = 0;
00986     first = last = 0;
00987     CHECK( seqman.is_free_handle( 1001, seq, data, first, last ) );
00988     CHECK( seqman.end() == seq );
00989     CHECK_EQUAL( (SequenceData*)0, data );
00990     CHECK_EQUAL( (EntityHandle)1001, first );
00991     CHECK_EQUAL( (EntityHandle)2000, last );
00992 
00993     seq   = seqman.end();
00994     data  = 0;
00995     first = last = 0;
00996     CHECK( seqman.is_free_handle( 1500, seq, data, first, last ) );
00997     CHECK( seqman.end() == seq );
00998     CHECK_EQUAL( (SequenceData*)0, data );
00999     CHECK_EQUAL( (EntityHandle)1001, first );
01000     CHECK_EQUAL( (EntityHandle)2000, last );
01001 
01002     seq   = seqman.end();
01003     data  = 0;
01004     first = last = 0;
01005     CHECK( seqman.is_free_handle( 2000, seq, data, first, last ) );
01006     CHECK( seqman.end() == seq );
01007     CHECK_EQUAL( (SequenceData*)0, data );
01008     CHECK_EQUAL( (EntityHandle)1001, first );
01009     CHECK_EQUAL( (EntityHandle)2000, last );
01010 
01011     seq   = seqman.end();
01012     data  = 0;
01013     first = last = 0;
01014     CHECK( seqman.is_free_handle( 3001, seq, data, first, last ) );
01015     CHECK( seqman.end() == seq );
01016     CHECK_EQUAL( (SequenceData*)0, data );
01017     CHECK_EQUAL( (EntityHandle)3001, first );
01018     CHECK_EQUAL( (EntityHandle)MB_END_ID, last );
01019 
01020     seq   = seqman.end();
01021     data  = 0;
01022     first = last = 0;
01023     CHECK( seqman.is_free_handle( 10000, seq, data, first, last ) );
01024     CHECK( seqman.end() == seq );
01025     CHECK_EQUAL( (SequenceData*)0, data );
01026     CHECK_EQUAL( (EntityHandle)3001, first );
01027     CHECK_EQUAL( (EntityHandle)MB_END_ID, last );
01028 }
01029 
01030 // Regression test for bug fixed in SVN revision 1952.
01031 // SVN checkin message:
01032 //  Fixing a bug in allocation of sequences.  Before this commit, when:
01033 //  - Existing sequence starts at one place, e.g. 41686, but its
01034 //  sequenceData starts earlier, e.g. 41673, and
01035 //  - You try to allocate a new sequence at a lower handle but with a
01036 //  range which is more than the room available in the sequenceData,
01037 //
01038 //  then
01039 //  - the code wants to allocate right up against the lower end of the
01040 //  existing sequence, and sizes the new sequenceData accordingly
01041 //  (i.e. with a max of 41685).
01042 //
01043 //  In this case, that new sequenceData will overlap the existing
01044 //  sequenceData (which starts at 41673, even though it has an empty chunk
01045 //  in front).
01046 //
01047 //  So, this change passes back a sequence data size from the code which
01048 //  computes where to put the start handle when allocating the new
01049 //  sequence.
01050 void regression_svn1952()
01051 {
01052     const EntityHandle last_handle = 50000;
01053     TypeSequenceManager seqman;
01054     SequenceData* data = new SequenceData( 0, 41673, last_handle );CHECK_ERR( insert_seq( seqman, 41686, 1000, data, true ) );
01055 
01056     SequenceData* result_data;
01057     EntityID result_size;
01058     EntityHandle result_handle;
01059     result_handle = seqman.find_free_sequence( 1686, 4000, 2 * last_handle, result_data, result_size );
01060     CHECK( result_handle > last_handle || result_handle + result_size <= 41673 );
01061     CHECK( result_handle + result_size <= 2 * last_handle );
01062 }
01063 
01064 // Regression test for bug fixed in SVN revision 1958.
01065 // SVN checkin message:
01066 //  Another fix to SequenceManager.  This time:
01067 //  - there was no sequence data allocated for the target range
01068 //  - there was exactly enough room in unallocated sequence data for the target range
01069 //  - the next data sequence up had a couple of empty slots, so the first occupied handle was a
01070 //  couple spaces from the start of the sequence data
01071 //  - the upper end of the range of the allocated sequence data was computed based on the first
01072 //  handle in the next sequence data
01073 //
01074 //  Fixed by setting the size using the parameter I added before.
01075 void regression_svn1958()
01076 {
01077     const int data_size           = 100;
01078     const EntityHandle data_start = 100;
01079     const EntityHandle data_end   = data_start + data_size - 1;
01080     const int seq_offset          = 2;
01081 
01082     TypeSequenceManager seqman;
01083     SequenceData* data = new SequenceData( 0, data_start, data_end );CHECK_ERR( insert_seq( seqman, data_start + seq_offset, data_size - seq_offset, data, true ) );
01084 
01085     SequenceData* result_data;
01086     EntityID result_size;
01087     EntityHandle result_handle;
01088     result_handle = seqman.find_free_sequence( data_start - 1, 1, 100000, result_data, result_size );
01089     CHECK( result_handle > data_end || result_handle + result_size <= data_start );
01090 }
01091 
01092 // Regression test for bug fixed in SVN revision 1960.
01093 // SVN checkin message:
01094 //  Third time pays for all.  This time, in TSM::is_free_sequence was true,
01095 //  so there was a free sequence; SM::create_entity_sequence then called
01096 //  SM::new_sequence_size, which used the first handle of the next higher
01097 //  sequence to compute the size, when the start handle of the data on
01098 //  which that first handle was allocated was smaller.  Sigh.
01099 void regression_svn1960()
01100 {
01101     const int data_size           = 6000;
01102     const EntityHandle data_start = 4000;
01103     const EntityHandle data_end   = data_start + data_size - 1;
01104     const int seq_offset          = 1000;
01105 
01106     TypeSequenceManager seqman;
01107     SequenceData* data = new SequenceData( 0, data_start, data_end );CHECK_ERR( insert_seq( seqman, data_start + seq_offset, data_size - seq_offset, data, true ) );
01108 
01109     SequenceData* result_data;
01110     EntityID result_size;
01111     EntityHandle result_handle;
01112     result_handle = seqman.find_free_sequence( data_start - 2, 1, 100000, result_data, result_size );
01113     CHECK( result_handle + result_size <= data_start );
01114 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines