11// SPDX-License-Identifier: Apache-2.0
22package com .swirlds .virtualmap .internal .hash ;
33
4- import static com .swirlds .virtualmap .test .fixtures .VirtualMapTestUtils .VIRTUAL_MAP_CONFIG ;
54import static org .junit .jupiter .api .Assertions .assertDoesNotThrow ;
65import static org .junit .jupiter .api .Assertions .assertEquals ;
76import static org .junit .jupiter .api .Assertions .assertNotNull ;
@@ -55,11 +54,10 @@ class VirtualHasherTest extends VirtualHasherTestBase {
5554 @ Tag (TestComponentTags .VMAP )
5655 @ DisplayName ("Null preloader produces NPE" )
5756 void nullPreloaderProducesNPE () {
58- final VirtualHasher hasher = new VirtualHasher (VIRTUAL_MAP_CONFIG );
5957 final List <VirtualLeafBytes > leaves = new ArrayList <>();
6058 assertThrows (
6159 NullPointerException .class ,
62- () -> hasher .hash (CHUNK_HEIGHT , null , leaves .iterator (), 1 , 2 , null ),
60+ () -> defaultHasher .hash (CHUNK_HEIGHT , null , leaves .iterator (), 1 , 2 , null ),
6361 "Call should have produced an NPE" );
6462 }
6563
@@ -71,10 +69,9 @@ void nullPreloaderProducesNPE() {
7169 @ DisplayName ("Null stream produces NPE" )
7270 void nullStreamProducesNPE () {
7371 final TestDataSource ds = new TestDataSource (1 , 2 , CHUNK_HEIGHT );
74- final VirtualHasher hasher = new VirtualHasher (VIRTUAL_MAP_CONFIG );
7572 assertThrows (
7673 NullPointerException .class ,
77- () -> hasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , null , 1 , 2 , null ),
74+ () -> defaultHasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , null , 1 , 2 , null ),
7875 "Call should have produced an NPE" );
7976 }
8077
@@ -87,10 +84,9 @@ void nullStreamProducesNPE() {
8784 @ SuppressWarnings ({"MismatchedQueryAndUpdateOfCollection" , "RedundantOperationOnEmptyContainer" })
8885 void emptyStreamProducesNull () {
8986 final TestDataSource ds = new TestDataSource (1 , 2 , CHUNK_HEIGHT );
90- final VirtualHasher hasher = new VirtualHasher (VIRTUAL_MAP_CONFIG );
9187 final List <VirtualLeafBytes > leaves = new ArrayList <>();
9288 assertNull (
93- hasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , leaves .iterator (), 1 , 2 , null ),
89+ defaultHasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , leaves .iterator (), 1 , 2 , null ),
9490 "Call should have returned a null hash" );
9591 }
9692
@@ -102,11 +98,10 @@ void emptyStreamProducesNull() {
10298 @ DisplayName ("Invalid leaf paths" )
10399 void invalidLeafPaths () {
104100 final TestDataSource ds = new TestDataSource (Path .INVALID_PATH , Path .INVALID_PATH , CHUNK_HEIGHT );
105- final VirtualHasher hasher = new VirtualHasher (VIRTUAL_MAP_CONFIG );
106101 final List <VirtualLeafBytes > emptyLeaves = new ArrayList <>();
107102 // Empty dirty leaves stream -> null hash
108103 assertNull (
109- hasher .hash (
104+ defaultHasher .hash (
110105 CHUNK_HEIGHT ,
111106 ds ::loadHashChunk ,
112107 emptyLeaves .iterator (),
@@ -115,23 +110,23 @@ void invalidLeafPaths() {
115110 null ),
116111 "Call should have produced null" );
117112 assertNull (
118- hasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , emptyLeaves .iterator (), Path .INVALID_PATH , 2 , null ),
113+ defaultHasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , emptyLeaves .iterator (), Path .INVALID_PATH , 2 , null ),
119114 "Call should have produced null" );
120115 assertNull (
121- hasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , emptyLeaves .iterator (), 1 , Path .INVALID_PATH , null ),
116+ defaultHasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , emptyLeaves .iterator (), 1 , Path .INVALID_PATH , null ),
122117 "Call should have produced null" );
123118 assertNull (
124- hasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , emptyLeaves .iterator (), 0 , 2 , null ),
119+ defaultHasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , emptyLeaves .iterator (), 0 , 2 , null ),
125120 "Call should have produced null" );
126121 assertNull (
127- hasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , emptyLeaves .iterator (), 1 , 0 , null ),
122+ defaultHasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , emptyLeaves .iterator (), 1 , 0 , null ),
128123 "Call should have produced null" );
129124 // Non-empty dirty leaves stream + empty leaf path range -> IllegalStateException
130125 final List <VirtualLeafBytes > nonEmptyLeaves = new ArrayList <>();
131126 nonEmptyLeaves .add (appleLeaf (VirtualTestBase .A_PATH ));
132127 assertThrows (
133128 IllegalArgumentException .class ,
134- () -> hasher .hash (
129+ () -> defaultHasher .hash (
135130 CHUNK_HEIGHT ,
136131 ds ::loadHashChunk ,
137132 nonEmptyLeaves .iterator (),
@@ -141,11 +136,11 @@ void invalidLeafPaths() {
141136 "Non-null leaves iterator + invalid paths should throw an exception" );
142137 assertThrows (
143138 IllegalArgumentException .class ,
144- () -> hasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , nonEmptyLeaves .iterator (), 0 , 2 , null ),
139+ () -> defaultHasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , nonEmptyLeaves .iterator (), 0 , 2 , null ),
145140 "Non-null leaves iterator + invalid paths should throw an exception" );
146141 assertThrows (
147142 IllegalArgumentException .class ,
148- () -> hasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , nonEmptyLeaves .iterator (), 1 , 0 , null ),
143+ () -> defaultHasher .hash (CHUNK_HEIGHT , ds ::loadHashChunk , nonEmptyLeaves .iterator (), 1 , 0 , null ),
149144 "Non-null leaves iterator + invalid paths should throw an exception" );
150145 }
151146
@@ -168,11 +163,10 @@ void hashingPermutations(final long firstLeafPath, final long lastLeafPath, fina
168163 throws Exception {
169164 final TestDataSource ds = new TestDataSource (firstLeafPath , lastLeafPath , CHUNK_HEIGHT );
170165 final HashingListener listener = new HashingListener ();
171- final VirtualHasher hasher = new VirtualHasher (VIRTUAL_MAP_CONFIG );
172166 final Hash expected = hashTree (ds );
173167 final List <VirtualLeafBytes > leaves = invalidateNodes (ds , dirtyPaths .stream ());
174- final Hash rootHash =
175- hasher . hash ( CHUNK_HEIGHT , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
168+ final Hash rootHash = defaultHasher . hash (
169+ CHUNK_HEIGHT , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
176170 assertEquals (expected , rootHash , "Hash value does not match expected" );
177171
178172 // Make sure the saver saw each dirty node exactly once.
@@ -196,8 +190,8 @@ void hashingPermutations(final long firstLeafPath, final long lastLeafPath, fina
196190 assertEquals (savedChunks .size (), seenChunks .size (), "Expected equals" );
197191 assertCallsAreBalanced (listener );
198192
199- final Hash hashItAgain =
200- hasher . hash ( CHUNK_HEIGHT , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
193+ final Hash hashItAgain = defaultHasher . hash (
194+ CHUNK_HEIGHT , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
201195 assertEquals (expected , hashItAgain , "Hash value does not match expected" );
202196
203197 for (int i = 0 ; i < leaves .size (); i ++) {
@@ -209,8 +203,8 @@ void hashingPermutations(final long firstLeafPath, final long lastLeafPath, fina
209203 }
210204 }
211205 leaves .sort (Comparator .comparing (VirtualLeafBytes ::path ));
212- final Hash hashItOnceMore =
213- hasher . hash ( CHUNK_HEIGHT , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
206+ final Hash hashItOnceMore = defaultHasher . hash (
207+ CHUNK_HEIGHT , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
214208 assertEquals (expected , hashItOnceMore , "Hash value does not match expected" );
215209 }
216210
@@ -342,7 +336,6 @@ void repeatedTest(final int chunkHeight) throws Exception {
342336 final long firstLeafPath = 52L ;
343337 final long lastLeafPath = firstLeafPath * 2 ;
344338 final TestDataSource ds = new TestDataSource (firstLeafPath , lastLeafPath , chunkHeight );
345- final VirtualHasher hasher = new VirtualHasher (VIRTUAL_MAP_CONFIG );
346339 final Hash expected = hashTree (ds );
347340 final List <Long > dirtyLeafPaths = List .of (
348341 53L , 56L , 59L , 63L , 66L , 72L , 76L , 77L , 80L , 81L , 82L , 83L , 85L , 87L , 88L , 94L , 96L , 100L , 104L );
@@ -351,8 +344,8 @@ void repeatedTest(final int chunkHeight) throws Exception {
351344 // this will *likely* find it.
352345 for (int i = 0 ; i < 500 ; i ++) {
353346 final List <VirtualLeafBytes > leaves = invalidateNodes (ds , dirtyLeafPaths .stream ());
354- final Hash rootHash =
355- hasher . hash ( chunkHeight , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , null );
347+ final Hash rootHash = defaultHasher . hash (
348+ chunkHeight , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , null );
356349 assertEquals (expected , rootHash , "Expected equals" );
357350 }
358351
@@ -365,7 +358,7 @@ public synchronized void onHashChunkHashed(final VirtualHashChunk chunk) {
365358 };
366359 for (int i = 0 ; i < 500 ; i ++) {
367360 final List <VirtualLeafBytes > leaves = invalidateNodes (ds , dirtyLeafPaths .stream ());
368- final Hash rootHash = hasher .hash (
361+ final Hash rootHash = defaultHasher .hash (
369362 chunkHeight , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
370363 assertEquals (expected , rootHash , "Expected equals" );
371364 }
@@ -377,7 +370,6 @@ void testAllDirtyLeaves(final int chunkHeight) throws Exception {
377370 final long firstLeafPath = 801 ;
378371 final long lastLeafPath = firstLeafPath * 2 ;
379372 final TestDataSource ds = new TestDataSource (firstLeafPath , lastLeafPath , chunkHeight );
380- final VirtualHasher hasher = new VirtualHasher (VIRTUAL_MAP_CONFIG );
381373 final Hash expected = hashTree (ds );
382374 final List <Long > dirtyLeafPaths =
383375 LongStream .range (firstLeafPath , lastLeafPath + 1 ).boxed ().toList ();
@@ -389,13 +381,13 @@ public synchronized void onHashChunkHashed(final VirtualHashChunk chunk) {
389381 }
390382 };
391383 final List <VirtualLeafBytes > leaves = invalidateNodes (ds , dirtyLeafPaths .stream ());
392- final Hash rootHash =
393- hasher . hash ( chunkHeight , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
384+ final Hash rootHash = defaultHasher . hash (
385+ chunkHeight , ds ::loadHashChunk , leaves .iterator (), firstLeafPath , lastLeafPath , listener );
394386 assertEquals (expected , rootHash , "Expected equals" );
395387
396388 final List <VirtualLeafBytes > oneDirtyLeaf = List .of (ds .getLeaf ((firstLeafPath + lastLeafPath ) / 2 ));
397- final Hash hashItAgain =
398- hasher . hash ( chunkHeight , ds ::loadHashChunk , oneDirtyLeaf .iterator (), firstLeafPath , lastLeafPath , null );
389+ final Hash hashItAgain = defaultHasher . hash (
390+ chunkHeight , ds ::loadHashChunk , oneDirtyLeaf .iterator (), firstLeafPath , lastLeafPath , null );
399391 assertEquals (expected , hashItAgain , "Expected equals" );
400392 }
401393
@@ -438,6 +430,7 @@ void listenerCallCounts() throws Exception {
438430
439431 // Validate the calls were all balanced
440432 assertCallsAreBalanced (listener );
433+ hasher .shutdown ();
441434 }
442435
443436 /**
@@ -451,7 +444,6 @@ void listenerCallCounts() throws Exception {
451444 @ DisplayName ("Verify the hasher does not ask for internal records it will recreate" )
452445 void hasherDoesNotAskForInternalsItWillRecreate () {
453446 final HashingListener listener = new HashingListener ();
454- final VirtualHasher hasher = new VirtualHasher (VIRTUAL_MAP_CONFIG );
455447
456448 // We will simulate growing the tree from 53 leaves to 106 leaves (doubling the size) and providing
457449 // all new leaves. This will guarantee that some internal nodes live at the paths that leaves used
@@ -469,7 +461,8 @@ void hasherDoesNotAskForInternalsItWillRecreate() {
469461
470462 assertDoesNotThrow (
471463 () -> {
472- hasher .hash (CHUNK_HEIGHT , hashChunkReader , dirtyLeaves , firstLeafPath , lastLeafPath , listener );
464+ defaultHasher .hash (
465+ CHUNK_HEIGHT , hashChunkReader , dirtyLeaves , firstLeafPath , lastLeafPath , listener );
473466 },
474467 "Hashing should not throw an exception" );
475468 }
0 commit comments