Skip to content

Commit 72044bf

Browse files
author
Jonathan Ellis
committed
make vectorCount atomic in MutablePQ
1 parent bd21ee7 commit 72044bf

File tree

3 files changed

+24
-15
lines changed

3 files changed

+24
-15
lines changed

jvector-base/src/main/java/io/github/jbellis/jvector/quantization/ImmutablePQVectors.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import io.github.jbellis.jvector.vector.types.ByteSequence;
2020

2121
public class ImmutablePQVectors extends PQVectors {
22+
private final int vectorCount;
23+
2224
/**
2325
* Construct an immutable PQVectors instance with the given ProductQuantization and compressed data chunks.
2426
* @param pq the ProductQuantization to use
@@ -37,4 +39,9 @@ public ImmutablePQVectors(ProductQuantization pq, ByteSequence<?>[] compressedDa
3739
protected int validChunkCount() {
3840
return compressedDataChunks.length;
3941
}
42+
43+
@Override
44+
public int count() {
45+
return vectorCount;
46+
}
4047
}

jvector-base/src/main/java/io/github/jbellis/jvector/quantization/MutablePQVectors.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.github.jbellis.jvector.quantization;
1818

1919
import io.github.jbellis.jvector.vector.VectorizationProvider;
20+
import java.util.concurrent.atomic.AtomicInteger;
2021
import io.github.jbellis.jvector.vector.types.ByteSequence;
2122
import io.github.jbellis.jvector.vector.types.VectorFloat;
2223
import io.github.jbellis.jvector.vector.types.VectorTypeSupport;
@@ -30,29 +31,31 @@ public class MutablePQVectors extends PQVectors implements MutableCompressedVect
3031
private static final int INITIAL_CHUNKS = 10;
3132
private static final float GROWTH_FACTOR = 1.5f;
3233

34+
protected AtomicInteger vectorCount;
35+
3336
/**
3437
* Construct a mutable PQVectors instance with the given ProductQuantization.
3538
* The vectors storage will grow dynamically as needed.
3639
* @param pq the ProductQuantization to use
3740
*/
3841
public MutablePQVectors(ProductQuantization pq) {
3942
super(pq);
40-
this.vectorCount = 0;
43+
this.vectorCount = new AtomicInteger(0);
4144
this.vectorsPerChunk = VECTORS_PER_CHUNK;
4245
this.compressedDataChunks = new ByteSequence<?>[INITIAL_CHUNKS];
4346
}
4447

4548
@Override
4649
public void encodeAndSet(int ordinal, VectorFloat<?> vector) {
4750
ensureChunkCapacity(ordinal);
48-
vectorCount = max(vectorCount, ordinal + 1);
51+
vectorCount.updateAndGet(current -> max(current, ordinal + 1));
4952
pq.encodeTo(vector, get(ordinal));
5053
}
5154

5255
@Override
5356
public void setZero(int ordinal) {
5457
ensureChunkCapacity(ordinal);
55-
vectorCount = max(vectorCount, ordinal + 1);
58+
vectorCount.updateAndGet(current -> max(current, ordinal + 1));
5659
get(ordinal).zero();
5760
}
5861

@@ -78,9 +81,14 @@ private void ensureChunkCapacity(int ordinal) {
7881

7982
@Override
8083
protected int validChunkCount() {
81-
if (vectorCount == 0)
84+
if (vectorCount.get() == 0)
8285
return 0;
83-
int chunkOrdinal = (vectorCount - 1) / vectorsPerChunk;
86+
int chunkOrdinal = (vectorCount.get() - 1) / vectorsPerChunk;
8487
return chunkOrdinal + 1;
8588
}
89+
90+
@Override
91+
public int count() {
92+
return vectorCount.get();
93+
}
8694
}

jvector-base/src/main/java/io/github/jbellis/jvector/quantization/PQVectors.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ public abstract class PQVectors implements CompressedVectors {
4141

4242
final ProductQuantization pq;
4343
protected ByteSequence<?>[] compressedDataChunks;
44-
protected int vectorCount;
4544
protected int vectorsPerChunk;
4645

4746
protected PQVectors(ProductQuantization pq) {
@@ -155,19 +154,14 @@ public static ImmutablePQVectors encodeAndBuild(ProductQuantization pq, int vect
155154
return new ImmutablePQVectors(pq, chunks, vectorCount, vectorsPerChunk);
156155
}
157156

158-
@Override
159-
public int count() {
160-
return vectorCount;
161-
}
162-
163157
@Override
164158
public void write(DataOutput out, int version) throws IOException
165159
{
166160
// pq codebooks
167161
pq.write(out, version);
168162

169163
// compressed vectors
170-
out.writeInt(vectorCount);
164+
out.writeInt(count());
171165
out.writeInt(pq.getSubspaceCount());
172166
for (int i = 0; i < validChunkCount(); i++) {
173167
vectorTypeSupport.writeByteSequence(out, compressedDataChunks[i]);
@@ -286,8 +280,8 @@ public ScoreFunction.ApproximateScoreFunction scoreFunctionFor(VectorFloat<?> q,
286280
}
287281

288282
public ByteSequence<?> get(int ordinal) {
289-
if (ordinal < 0 || ordinal >= vectorCount)
290-
throw new IndexOutOfBoundsException("Ordinal " + ordinal + " out of bounds for vector count " + vectorCount);
283+
if (ordinal < 0 || ordinal >= count())
284+
throw new IndexOutOfBoundsException("Ordinal " + ordinal + " out of bounds for vector count " + count());
291285
return get(compressedDataChunks, ordinal, vectorsPerChunk, pq.getSubspaceCount());
292286
}
293287

@@ -341,7 +335,7 @@ public long ramBytesUsed() {
341335
public String toString() {
342336
return "PQVectors{" +
343337
"pq=" + pq +
344-
", count=" + vectorCount +
338+
", count=" + count() +
345339
'}';
346340
}
347341
}

0 commit comments

Comments
 (0)