Skip to content

Commit 144fdf1

Browse files
author
Stefan Vodita
committed
Revert ramBytesUsage
1 parent 5467dcb commit 144fdf1

File tree

4 files changed

+39
-39
lines changed

4 files changed

+39
-39
lines changed

lucene/core/src/java/org/apache/lucene/util/hnsw/NeighborArray.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@
2121
import java.util.Arrays;
2222
import java.util.concurrent.locks.ReadWriteLock;
2323
import java.util.concurrent.locks.ReentrantReadWriteLock;
24-
import org.apache.lucene.util.Accountable;
2524
import org.apache.lucene.util.ArrayUtil;
26-
import org.apache.lucene.util.RamUsageEstimator;
2725

2826
/**
2927
* NeighborArray encodes the neighbors of a node and their mutual scores in the HNSW graph as a pair
@@ -33,7 +31,7 @@
3331
*
3432
* @lucene.internal
3533
*/
36-
public class NeighborArray implements Accountable {
34+
public class NeighborArray {
3735
private static final int INITIAL_CAPACITY = 10;
3836
private final boolean scoresDescOrder;
3937
private final int maxSize;
@@ -211,12 +209,4 @@ private int descSortFindRightMostInsertionPoint(float newScore, int bound) {
211209
}
212210
return start;
213211
}
214-
215-
@Override
216-
public long ramBytesUsed() {
217-
return (long) node.length * (Integer.BYTES + Float.BYTES)
218-
+ RamUsageEstimator.NUM_BYTES_ARRAY_HEADER * 2L
219-
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF * 2L
220-
+ Integer.BYTES * 5;
221-
}
222212
}

lucene/core/src/java/org/apache/lucene/util/hnsw/OnHeapHnswGraph.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,21 @@ private void generateLevelToNodes() {
275275

276276
@Override
277277
public long ramBytesUsed() {
278+
long neighborArrayBytes0 =
279+
(long) nsize0 * (Integer.BYTES + Float.BYTES)
280+
+ RamUsageEstimator.NUM_BYTES_ARRAY_HEADER * 2L
281+
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF * 2L
282+
+ Integer.BYTES * 5;
283+
long neighborArrayBytes =
284+
(long) nsize * (Integer.BYTES + Float.BYTES)
285+
+ RamUsageEstimator.NUM_BYTES_ARRAY_HEADER * 2L
286+
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF * 2L
287+
+ Integer.BYTES * 5;
278288
long total = 0;
279-
for (NeighborArray[] neighborArraysPerNode : graph) {
280-
if (neighborArraysPerNode != null) {
281-
for (NeighborArray neighborArrayPerNodeAndLevel : neighborArraysPerNode) {
282-
total += neighborArrayPerNodeAndLevel.ramBytesUsed();
283-
}
284-
}
285-
}
286-
289+
total +=
290+
size() * (neighborArrayBytes0 + RamUsageEstimator.NUM_BYTES_ARRAY_HEADER)
291+
+ RamUsageEstimator.NUM_BYTES_ARRAY_HEADER; // for graph and level 0;
292+
total += nonZeroLevelSize.get() * neighborArrayBytes; // for non-zero level
287293
total += 4 * Integer.BYTES; // all int fields
288294
total += 1; // field: noGrowth
289295
total +=

lucene/core/src/test/org/apache/lucene/util/hnsw/HnswGraphTestCase.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,30 @@ public void testRamUsageEstimate() throws IOException {
757757
long estimated = RamUsageEstimator.sizeOfObject(hnsw);
758758
long actual = ramUsed(hnsw);
759759

760+
// The estimation assumes neighbor arrays are always max size.
761+
// When this is not true, the estimate can be much larger than the actual value.
762+
// In these cases, we compute how much we overestimated the neighbors arrays.
763+
if (estimated > actual) {
764+
long neighborsError = 0;
765+
int numLevels = hnsw.numLevels();
766+
for (int level = 0; level < numLevels; ++level) {
767+
NodesIterator nodesOnLevel = hnsw.getNodesOnLevel(level);
768+
while (nodesOnLevel.hasNext()) {
769+
int node = nodesOnLevel.nextInt();
770+
NeighborArray neighbors = hnsw.getNeighbors(level, node);
771+
long maxNeighborsSize;
772+
if (level == 0) {
773+
maxNeighborsSize = (long) (Integer.BYTES + Float.BYTES) * (M * 2L + 1);
774+
} else {
775+
maxNeighborsSize = (long) (Integer.BYTES + Float.BYTES) * (M + 1);
776+
}
777+
long actualNeighborsSize = (long) (Integer.BYTES + Float.BYTES) * neighbors.size();
778+
neighborsError += maxNeighborsSize - actualNeighborsSize;
779+
}
780+
}
781+
estimated -= neighborsError;
782+
}
783+
760784
assertEquals((double) actual, (double) estimated, (double) actual * 0.3);
761785
}
762786

lucene/core/src/test/org/apache/lucene/util/hnsw/TestNeighborArray.java

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@
1717

1818
package org.apache.lucene.util.hnsw;
1919

20-
import static org.apache.lucene.tests.util.RamUsageTester.ramUsed;
21-
2220
import java.io.IOException;
2321
import org.apache.lucene.tests.util.LuceneTestCase;
2422
import org.apache.lucene.util.Bits;
25-
import org.apache.lucene.util.RamUsageEstimator;
2623

2724
public class TestNeighborArray extends LuceneTestCase {
2825

@@ -244,21 +241,4 @@ default Bits getAcceptOrds(Bits acceptDocs) {
244241
throw new UnsupportedOperationException();
245242
}
246243
}
247-
248-
public void testRamUsageEstimate() {
249-
int maxSize = random().nextInt(100, 10_000);
250-
int numAdditions = random().nextInt(100, 1_000);
251-
NeighborArray neighbors = new NeighborArray(maxSize, true);
252-
253-
int count = 0;
254-
while (count < maxSize) {
255-
for (int i = 0; i < numAdditions && count < maxSize; i++) {
256-
neighbors.addInOrder(count, 0f);
257-
count++;
258-
}
259-
long estimated = RamUsageEstimator.sizeOfObject(neighbors);
260-
long actual = ramUsed(neighbors);
261-
assertEquals((double) actual, (double) estimated, (double) actual * 0.3);
262-
}
263-
}
264244
}

0 commit comments

Comments
 (0)