Lazy semantic region summaries

- claims cache the next region shard without rebuilding its key summary
- summaries are computed when a query or compaction reads them
This commit is contained in:
Brian Neumann-Fopiano
2026-09-28 13:43:38 -04:00
parent 08353e3bdd
commit 20e10999dd
2 changed files with 26 additions and 1 deletions
@@ -1075,7 +1075,11 @@ public final class GenerationSemanticIndex {
private void cacheRegion(long regionKey, RegionShard region) {
regions.put(regionKey, region);
cacheSummary(regionKey, region.summary());
if (region.summary == null) {
summaries.remove(regionKey);
} else {
cacheSummary(regionKey, region.summary);
}
while (regions.size() > MAXIMUM_CACHED_REGIONS) {
Iterator<Map.Entry<Long, RegionShard>> entries = regions.entrySet().iterator();
entries.next();
@@ -206,6 +206,27 @@ public final class GenerationSemanticIndexTest {
new ChunkGenerationSemantics.BlockPosition(-520, 80, -8), 4)).isEmpty());
}
@Test
public void claimsDeferRegionSummariesUntilAQueryReadsThem() throws Exception {
Path root = temporaryFolder.newFolder("lazy-summaries").toPath();
GenerationSemanticIndex index = GenerationSemanticIndex.initialize(root);
index.claimAndPersist(ChunkGenerationSemantics.builder(-33, -1, 1L).addObject("iris:first").seal().build());
assertEquals(0, index.cachedSummaryCount());
assertEquals("iris:first", requiredMatch(index, GenerationSemanticIndex.SemanticKind.OBJECT, "iris:first").key());
assertEquals(1, index.cachedSummaryCount());
index.claimAndPersist(ChunkGenerationSemantics.builder(-34, -1, 1L).addObject("iris:second").seal().build());
assertEquals(0, index.cachedSummaryCount());
assertEquals("iris:second", requiredMatch(index, GenerationSemanticIndex.SemanticKind.OBJECT, "iris:second").key());
assertEquals("iris:first", requiredMatch(index, GenerationSemanticIndex.SemanticKind.OBJECT, "iris:first").key());
assertEquals(2, sealedClaims(index, 1L).size());
GenerationSemanticIndex reopened = GenerationSemanticIndex.load(root);
assertEquals("iris:second", requiredMatch(reopened, GenerationSemanticIndex.SemanticKind.OBJECT, "iris:second").key());
assertEquals(index.recordsSnapshot(), reopened.recordsSnapshot());
}
@Test
public void conflictingActivationsAndFactsAfterSealAreRejectedWithoutDiskChanges() throws Exception {
Path dimensionRoot = temporaryFolder.newFolder("sealed").toPath();