@@ -479,45 +479,65 @@ void snapshotRestoreIndex(final TestType testType) throws IOException {
479479 final Path originalDbPath = testDirectory .resolve ("merkledb-snapshotRestoreIndex-" + testType );
480480 final KeySerializer keySerializer = testType .dataType ().getKeySerializer ();
481481 final ValueSerializer valueSerializer = testType .dataType ().getValueSerializer ();
482- createAndApplyDataSource (originalDbPath , tableName , testType , count , 0 , dataSource -> {
483- final int tableId = dataSource .getTableId ();
484- // create some leaves
485- dataSource .saveRecords (
486- count - 1 ,
487- count * 2 - 2 ,
488- IntStream .range (0 , count * 2 - 1 ).mapToObj (i -> createVirtualInternalRecord (i , i + 1 )),
489- IntStream .range (count - 1 , count * 2 - 1 )
490- .mapToObj (i -> testType .dataType ().createVirtualLeafRecord (i ))
491- .map (r -> r .toBytes (keySerializer , valueSerializer )),
492- Stream .empty ());
493- // create a snapshot
494- final Path snapshotDbPath =
495- testDirectory .resolve ("merkledb-snapshotRestoreIndex-" + testType + "_SNAPSHOT" );
496- dataSource .getDatabase ().snapshot (snapshotDbPath , dataSource );
497- // close data source
498- dataSource .close ();
499-
500- final MerkleDb snapshotDb = MerkleDb .getInstance (snapshotDbPath , CONFIGURATION );
501- final MerkleDbPaths snapshotPaths = new MerkleDbPaths (snapshotDb .getTableDir (tableName , tableId ));
502- // Delete all indices
503- Files .delete (snapshotPaths .pathToDiskLocationLeafNodesFile );
504- Files .delete (snapshotPaths .pathToDiskLocationInternalNodesFile );
505- // There is no way to use MerkleDbPaths to get bucket index file path
506- Files .deleteIfExists (snapshotPaths .keyToPathDirectory .resolve (tableName + "_bucket_index.ll" ));
507-
508- final MerkleDbDataSource snapshotDataSource = snapshotDb .getDataSource (tableName , false );
509- reinitializeDirectMemoryUsage ();
510- IntStream .range (0 , count * 2 - 1 ).forEach (i -> assertHash (snapshotDataSource , i , i + 1 ));
511- IntStream .range (count - 1 , count * 2 - 1 )
512- .forEach (i ->
513- assertLeaf (testType , keySerializer , valueSerializer , snapshotDataSource , i , i , i + 1 , i ));
514- // close data source
515- snapshotDataSource .close ();
516-
517- // check db count
518- assertEventuallyEquals (
519- 0L , MerkleDbDataSource ::getCountOfOpenDatabases , Duration .ofSeconds (1 ), "Expected no open dbs" );
520- });
482+ final int [] deltas = {-10 , 0 , 10 };
483+ for (int delta : deltas ) {
484+ createAndApplyDataSource (originalDbPath , tableName , testType , count + Math .abs (delta ), 0 , dataSource -> {
485+ final int tableId = dataSource .getTableId ();
486+ // create some records
487+ dataSource .saveRecords (
488+ count - 1 ,
489+ count * 2 - 2 ,
490+ IntStream .range (0 , count * 2 - 1 ).mapToObj (i -> createVirtualInternalRecord (i , i + 1 )),
491+ IntStream .range (count - 1 , count * 2 - 1 )
492+ .mapToObj (i -> testType .dataType ().createVirtualLeafRecord (i ))
493+ .map (r -> r .toBytes (keySerializer , valueSerializer )),
494+ Stream .empty ());
495+ if (delta != 0 ) {
496+ // create some more, current leaf path range shifted by delta
497+ dataSource .saveRecords (
498+ count - 1 + delta ,
499+ count * 2 - 2 + 2 * delta ,
500+ IntStream .range (0 , count * 2 - 1 + 2 * delta )
501+ .mapToObj (i -> createVirtualInternalRecord (i , i + 1 )),
502+ IntStream .range (count - 1 + delta , count * 2 - 1 + 2 * delta )
503+ .mapToObj (i -> testType .dataType ().createVirtualLeafRecord (i ))
504+ .map (r -> r .toBytes (keySerializer , valueSerializer )),
505+ Stream .empty ());
506+ }
507+ // create a snapshot
508+ final Path snapshotDbPath =
509+ testDirectory .resolve ("merkledb-snapshotRestoreIndex-" + testType + "_SNAPSHOT" );
510+ dataSource .getDatabase ().snapshot (snapshotDbPath , dataSource );
511+ // close data source
512+ dataSource .close ();
513+
514+ final MerkleDb snapshotDb = MerkleDb .getInstance (snapshotDbPath , CONFIGURATION );
515+ final MerkleDbPaths snapshotPaths = new MerkleDbPaths (snapshotDb .getTableDir (tableName , tableId ));
516+ // Delete all indices
517+ Files .delete (snapshotPaths .pathToDiskLocationLeafNodesFile );
518+ Files .delete (snapshotPaths .pathToDiskLocationInternalNodesFile );
519+ // There is no way to use MerkleDbPaths to get bucket index file path
520+ Files .deleteIfExists (snapshotPaths .keyToPathDirectory .resolve (tableName + "_bucket_index.ll" ));
521+
522+ final MerkleDbDataSource snapshotDataSource = snapshotDb .getDataSource (tableName , false );
523+ reinitializeDirectMemoryUsage ();
524+ // Check hashes
525+ IntStream .range (0 , count * 2 - 1 + 2 * delta ).forEach (i -> assertHash (snapshotDataSource , i , i + 1 ));
526+ assertNullHash (snapshotDataSource , count * 2 + 2 * delta );
527+ // Check leaves
528+ IntStream .range (0 , count - 2 + delta ).forEach (i -> assertNullLeaf (snapshotDataSource , i ));
529+ IntStream .range (count - 1 + delta , count * 2 - 1 + 2 * delta )
530+ .forEach (i -> assertLeaf (
531+ testType , keySerializer , valueSerializer , snapshotDataSource , i , i , i + 1 , i ));
532+ assertNullLeaf (snapshotDataSource , count * 2 + 2 * delta );
533+ // close data source
534+ snapshotDataSource .close ();
535+
536+ // check db count
537+ assertEventuallyEquals (
538+ 0L , MerkleDbDataSource ::getCountOfOpenDatabases , Duration .ofSeconds (1 ), "Expected no open dbs" );
539+ });
540+ }
521541 }
522542
523543 @ Test
@@ -789,7 +809,16 @@ public static void assertHash(final MerkleDbDataSource dataSource, final long pa
789809 try {
790810 assertEqualsAndPrint (hash (i ), dataSource .loadHash (path ));
791811 } catch (final Exception e ) {
792- e .printStackTrace ();
812+ e .printStackTrace (System .err );
813+ fail ("Exception should not have been thrown here!" );
814+ }
815+ }
816+
817+ public static void assertNullHash (final MerkleDbDataSource dataSource , final long path ) {
818+ try {
819+ assertNull (dataSource .loadHash (path ));
820+ } catch (final Exception e ) {
821+ e .printStackTrace (System .err );
793822 fail ("Exception should not have been thrown here!" );
794823 }
795824 }
@@ -830,6 +859,15 @@ public static void assertLeaf(
830859 }
831860 }
832861
862+ public static void assertNullLeaf (final MerkleDbDataSource dataSource , final long path ) {
863+ try {
864+ assertNull (dataSource .loadLeafRecord (path ));
865+ } catch (final Exception e ) {
866+ e .printStackTrace (System .err );
867+ fail ("Exception should not have been thrown here!" );
868+ }
869+ }
870+
833871 public static <T > void assertEqualsAndPrint (final T recordA , final T recordB ) {
834872 assertEquals (
835873 recordA == null ? null : recordA .toString (),
0 commit comments