Skip to content

Commit 5eaffdd

Browse files
anidotnetclaude
andcommitted
test: let the migration settle H2's key type before the readers compare
The concurrent legacy-index test failed on all three Java 17 builds with UnsupportedOperationException: Can not compare, from inside H2. That is not the race #1309 fixed. H2's ObjectDataType settles its key type on first use through an unsynchronized field and identity checks in SerializedObjectType.compare, so sixteen threads making a fresh map's first key comparison at once can each see a different type instance. The code is identical in h2 2.4.240 and 2.5.250; 2.5.250 only made it show up more often. With one legacy id the migration never compared a key, so the readers made the first comparison. Two ids make the migration's second put do it, before any reader gets past the migration lock. 10/10 green on 2.5.250 here; still 3/3 red on the pre-#1309 sources. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 7bdfdef commit 5eaffdd

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

‎nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVStoreTest.java‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
import java.nio.file.Files;
3535
import java.nio.file.Path;
3636
import java.util.ArrayList;
37+
import java.util.Arrays;
3738
import java.util.Collections;
3839
import java.util.Iterator;
40+
import java.util.LinkedHashSet;
3941
import java.util.List;
4042
import java.util.Set;
4143
import java.util.concurrent.CountDownLatch;
@@ -215,9 +217,14 @@ public void testConcurrentFirstReadOfALegacyIndexMigratesOnce() throws Exception
215217
try {
216218
final IndexDescriptor desc = new IndexDescriptor(IndexType.NON_UNIQUE,
217219
Fields.withNames("a"), "c");
218-
final NitriteId id = NitriteId.createId(1L);
220+
// two ids, so the migration's second put is the composite map's first key
221+
// comparison: H2's ObjectDataType settles its key type on first use without
222+
// any synchronization, and sixteen readers making that first comparison at
223+
// once can fail inside H2 with "Can not compare" (h2 2.4.240 and 2.5.250)
224+
final Set<NitriteId> ids = new LinkedHashSet<>(Arrays.asList(
225+
NitriteId.createId(1L), NitriteId.createId(2L)));
219226
store.openMap(deriveIndexMapName(desc), DBValue.class, ArrayList.class)
220-
.put(new DBValue("k"), new ArrayList<>(Collections.singletonList(id)));
227+
.put(new DBValue("k"), new ArrayList<>(ids));
221228

222229
final NitriteConfig config = mock(NitriteConfig.class);
223230
doReturn(store).when(config).getNitriteStore();
@@ -237,7 +244,7 @@ public void testConcurrentFirstReadOfALegacyIndexMigratesOnce() throws Exception
237244
}
238245
start.countDown();
239246
for (Future<Set<NitriteId>> read : reads) {
240-
assertEquals(Collections.singleton(id), read.get(5, TimeUnit.SECONDS));
247+
assertEquals(ids, read.get(5, TimeUnit.SECONDS));
241248
}
242249
assertFalse(store.hasMap(deriveIndexMapName(desc)));
243250
} finally {

0 commit comments

Comments
 (0)