diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 979f742b3082..fe51f3e48680 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -386,6 +386,9 @@ Bug Fixes * GITHUB#16389: Fix double-counting of the underlying Automaton in AutomatonQuery#ramBytesUsed. (Sasilekha R) +* GITHUB#16405: PointInSetQuery#ramBytesUsed now accounts for the retained + lowerPoint and upperPoint bounds arrays. (Sasilekha R) + * GITHUB#16367: HNSW graph construction now periodically checks whether the surrounding merge has been aborted, so IndexWriter#rollback and abortMerges no longer block until the entire graph is built. (Jeho Jeong) diff --git a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java index 431c5b87b25d..90bca4e8def7 100644 --- a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java @@ -136,7 +136,9 @@ protected PointInSetQuery(String field, int numDims, int bytesPerDim, Stream pac ramBytesUsed = BASE_RAM_BYTES + RamUsageEstimator.sizeOfObject(field) - + RamUsageEstimator.sizeOfObject(sortedPackedPoints); + + RamUsageEstimator.sizeOfObject(sortedPackedPoints) + + RamUsageEstimator.sizeOfObject(lowerPoint) + + RamUsageEstimator.sizeOfObject(upperPoint); } @Override diff --git a/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java b/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java index a61adf527fff..2b3a91b55bf7 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java @@ -62,11 +62,13 @@ import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.search.FixedBitSetCollector; import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.RamUsageTester; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.NumericUtils; +import org.apache.lucene.util.RamUsageEstimator; import org.apache.lucene.util.bkd.BKDConfig; import org.junit.BeforeClass; @@ -2630,4 +2632,39 @@ protected String toString(byte[] point) { }); assertEquals("values are out of order: saw [2] before [1]", expected.getMessage()); } + + public void testRamBytesUsedIncludesBoundsArrays() { + // The constructor allocates lowerPoint/upperPoint and retains them for the whole + // lifetime of the query (scorerSupplier uses them for a per-segment pre-check). + // Both must contribute to ramBytesUsed(). + PointInSetQuery q = + (PointInSetQuery) BinaryPoint.newSetQuery("f", new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); + assertNotNull(q.lowerPoint); + assertNotNull(q.upperPoint); + long expected = + RamUsageEstimator.shallowSizeOfInstance(PointInSetQuery.class) + + RamUsageEstimator.sizeOfObject(q.field) + + RamUsageEstimator.sizeOfObject(q.sortedPackedPoints) + + RamUsageEstimator.sizeOfObject(q.lowerPoint) + + RamUsageEstimator.sizeOfObject(q.upperPoint); + assertEquals(expected, q.ramBytesUsed()); + } + + public void testRamBytesUsedMatchesActualWithinTolerance() { + // Independent cross-check against a full object-graph walk; guards against the + // case where the byte-exact test and the implementation drift together. + // Mirrors TestTermInSetQuery#testRamBytesUsed (many entries, 5% margin). + final int numPoints = 10000 + random().nextInt(1000); + final byte[][] values = new byte[numPoints][]; + for (int i = 0; i < numPoints; i++) { + values[i] = new byte[8]; + random().nextBytes(values[i]); + } + PointInSetQuery query = (PointInSetQuery) BinaryPoint.newSetQuery("f", values); + final long actualRamBytesUsed = RamUsageTester.ramUsed(query); + final long expectedRamBytesUsed = query.ramBytesUsed(); + // error margin within 5% + assertEquals( + (double) expectedRamBytesUsed, (double) actualRamBytesUsed, actualRamBytesUsed / 20.d); + } }