Skip to content

Commit 7cfcb6b

Browse files
committed
refactor: replace Float[] with float[]
We started off using Float[] and Float[][] because v5 did so and it was easier to reuse (read: copy-paste) some bits of code. Thing with object arrays is that they name N allocations (1 for each element) compared to 1 that a primitive array makes. That creates unnecessary work for GC and we aren't gaining anything from using boxed values. They're still useful for request parameters like distance/certainty/force, because they can be null. But vectors are not sparse and should never contain nulls in principle.
1 parent 48cb18f commit 7cfcb6b

11 files changed

Lines changed: 143 additions & 89 deletions

File tree

src/it/java/io/weaviate/ConcurrentTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import org.junit.Rule;
99
import org.junit.rules.TestName;
1010

11+
import com.google.common.primitives.Floats;
12+
1113
/**
1214
* ConcurrentTest is the base class for integration tests, which provides
1315
* utility methods to uniqualize collections and objects created in the
@@ -56,9 +58,9 @@ protected static String randomUUID() {
5658
* @param bound Value range upper bound.
5759
* @return
5860
*/
59-
protected static Float[] randomVector(int length, float origin, float bound) {
60-
return IntStream.range(0, length)
61+
protected static float[] randomVector(int length, float origin, float bound) {
62+
return Floats.toArray(IntStream.range(0, length)
6163
.<Float>mapToObj(f -> rand.nextFloat(origin, bound))
62-
.toArray(Float[]::new);
64+
.toList());
6365
}
6466
}

src/it/java/io/weaviate/integration/DataITest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public static void beforeAll() throws IOException {
3737
public void testCreateGetDelete() throws IOException {
3838
var artists = client.collections.use(COLLECTION);
3939
var id = randomUUID();
40-
Float[] vector = { 1f, 2f, 3f };
40+
float[] vector = { 1, 2, 3 };
4141

4242
artists.data.insert(Map.of("name", "john doe"),
4343
metadata -> metadata
@@ -56,8 +56,8 @@ public void testCreateGetDelete() throws IOException {
5656
Assertions.assertThat(obj.metadata().uuid())
5757
.as("object id").isEqualTo(id);
5858

59-
Assertions.assertThat(obj.metadata().vectors()).extracting(v -> v.getSingle(VECTOR_INDEX))
60-
.asInstanceOf(InstanceOfAssertFactories.array(Float[].class)).containsExactly(vector);
59+
Assertions.assertThat(obj.metadata().vectors().getSingle(VECTOR_INDEX))
60+
.containsExactly(vector);
6161

6262
Assertions.assertThat(obj.properties())
6363
.as("has expected properties")
@@ -227,7 +227,7 @@ public void testUpdate() throws IOException {
227227
var authors = client.collections.use(nsAuthors);
228228
var walter = authors.data.insert(Map.of("name", "walter scott"));
229229

230-
var vector = new Float[] { 1f, 2f, 3f };
230+
var vector = new float[] { 1, 2, 3 };
231231

232232
var books = client.collections.use(nsBooks);
233233

src/it/java/io/weaviate/integration/SearchITest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public class SearchITest extends ConcurrentTest {
5353
/**
5454
* One of the inserted vectors which will be used as target vector for search.
5555
*/
56-
private static Float[] searchVector;
56+
private static float[] searchVector;
5757

5858
@BeforeClass
5959
public static void beforeAll() throws IOException {
@@ -104,8 +104,8 @@ public void testNearVector_groupBy() {
104104
*
105105
* @returns IDs of inserted objects and their corresponding vectors.
106106
*/
107-
private static Map<String, Float[]> populateTest(int n) throws IOException {
108-
var created = new HashMap<String, Float[]>();
107+
private static Map<String, float[]> populateTest(int n) throws IOException {
108+
var created = new HashMap<String, float[]>();
109109

110110
var things = client.collections.use(COLLECTION);
111111
for (int i = 0; i < n; i++) {

src/main/java/io/weaviate/client6/v1/api/collections/Vectors.java

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,22 @@
2525
*/
2626
@ToString
2727
public class Vectors {
28+
/** Elements of this map must only be {@code float[]} or {@code float[][]}. */
2829
private final Map<String, Object> namedVectors;
2930

30-
public static Vectors of(Float[] vector) {
31-
return new Vectors(VectorIndex.DEFAULT_VECTOR_NAME, vector);
31+
public static Vectors of(float[] vector) {
32+
return of(VectorIndex.DEFAULT_VECTOR_NAME, vector);
3233
}
3334

34-
public static Vectors of(String name, Float[] vector) {
35+
public static Vectors of(String name, float[] vector) {
3536
return new Vectors(name, vector);
3637
}
3738

38-
public static Vectors of(Float[][] vector) {
39-
return new Vectors(VectorIndex.DEFAULT_VECTOR_NAME, vector);
39+
public static Vectors of(float[][] vector) {
40+
return of(VectorIndex.DEFAULT_VECTOR_NAME, vector);
4041
}
4142

42-
public static Vectors of(String name, Float[][] vector) {
43+
public static Vectors of(String name, float[][] vector) {
4344
return new Vectors(name, vector);
4445
}
4546

@@ -51,33 +52,43 @@ public Vectors(Builder builder) {
5152
this.namedVectors = builder.namedVectors;
5253
}
5354

54-
/*
55+
/**
5556
* Create a single named vector.
56-
* Intended to be used by factory methods, which can statically restrict
57-
* vector's type to {@code Float[]} and {@code Float[][]}.
5857
*
59-
* @param name Vector name.
60-
*
61-
* @param vector {@code Float[]} or {@code Float[][]} vector.
58+
* <p>
59+
* Callers must ensure that vectors are either
60+
* {@code float[]} or {@code float[][]}.
6261
*
62+
* @param name Vector name.
63+
* @param vector {@code float[]} or {@code float[][]} vector.
6364
*/
6465
private Vectors(String name, Object vector) {
6566
this.namedVectors = Collections.singletonMap(name, vector);
6667
}
6768

69+
/**
70+
* Create a Vectors from a map.
71+
*
72+
* <p>
73+
* Callers must ensure that vectors are either
74+
* {@code float[]} or {@code float[][]}.
75+
*
76+
* @param name Vector name.
77+
* @param vector Map of named vectors.
78+
*/
6879
private Vectors(Map<String, Object> namedVectors) {
6980
this.namedVectors = namedVectors;
7081
}
7182

7283
public static class Builder implements ObjectBuilder<Vectors> {
7384
private final Map<String, Object> namedVectors = new HashMap<>();
7485

75-
public Builder vector(String name, Float[] vector) {
86+
public Builder vector(String name, float[] vector) {
7687
this.namedVectors.put(name, vector);
7788
return this;
7889
}
7990

80-
public Builder vector(String name, Float[][] vector) {
91+
public Builder vector(String name, float[][] vector) {
8192
this.namedVectors.put(name, vector);
8293
return this;
8394
}
@@ -88,22 +99,55 @@ public Vectors build() {
8899
}
89100
}
90101

91-
public Float[] getSingle(String name) {
92-
return (Float[]) namedVectors.get(name);
102+
/**
103+
* Get 1-dimensional vector by name.
104+
*
105+
* @returns Vector as {@code float[]} or {@code null}.
106+
* @throws ClassCastException The underlying vector is not a {@code float[]}.
107+
*/
108+
public float[] getSingle(String name) {
109+
return (float[]) namedVectors.get(name);
93110
}
94111

95-
public Float[] getDefaultSingle() {
112+
/**
113+
* Get default 1-dimensional vector.
114+
*
115+
* @returns Vector as {@code float[]} or {@code null}.
116+
* @throws ClassCastException if the underlying object is not a {@code float[]}.
117+
*/
118+
public float[] getDefaultSingle() {
96119
return getSingle(VectorIndex.DEFAULT_VECTOR_NAME);
97120
}
98121

99-
public Float[][] getMulti(String name) {
100-
return (Float[][]) namedVectors.get(name);
122+
/**
123+
* Get 2-dimensional vector by name.
124+
*
125+
* @returns Vector as {@code float[][]} or {@code null}.
126+
* @throws ClassCastException if the underlying object is not a
127+
* {@code float[][]}.
128+
*/
129+
public float[][] getMulti(String name) {
130+
return (float[][]) namedVectors.get(name);
101131
}
102132

103-
public Float[][] getDefaultMulti() {
133+
/**
134+
* Get default 2-dimensional vector.
135+
*
136+
* @returns Vector as {@code float[][]} or {@code null}.
137+
* @throws ClassCastException if the underlying object is not a
138+
* {@code float[][]}.
139+
*/
140+
public float[][] getDefaultMulti() {
104141
return getMulti(VectorIndex.DEFAULT_VECTOR_NAME);
105142
}
106143

144+
/**
145+
* Get all vectors.
146+
* Each element is either a {@code float[]} or a {@code float[][]}.
147+
*
148+
*
149+
* @returns Map of name-vector pairs. The returned map is immutable.
150+
*/
107151
public Map<String, Object> asMap() {
108152
return Map.copyOf(namedVectors);
109153
}
@@ -119,8 +163,8 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
119163
}
120164
final var mapAdapter = gson.getDelegateAdapter(this, new TypeToken<Map<String, Object>>() {
121165
});
122-
final var float_1d = gson.getDelegateAdapter(this, TypeToken.get(Float[].class));
123-
final var float_2d = gson.getDelegateAdapter(this, TypeToken.get(Float[][].class));
166+
final var float_1d = gson.getDelegateAdapter(this, TypeToken.get(float[].class));
167+
final var float_2d = gson.getDelegateAdapter(this, TypeToken.get(float[][].class));
124168
return (TypeAdapter<T>) new TypeAdapter<Vectors>() {
125169

126170
@Override
@@ -144,6 +188,8 @@ public Vectors read(JsonReader in) throws IOException {
144188
} else {
145189
vector = float_1d.fromJsonTree(array);
146190
}
191+
192+
assert (vector instanceof float[]) || (vector instanceof float[][]) : "invalid vector type";
147193
namedVectors.put(vectorName, vector);
148194
}
149195
}

src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ public GroupedResponseT hybrid(Hybrid filter, Function<Aggregation.Builder, Obje
7272

7373
// NearVector ---------------------------------------------------------------
7474

75-
public ResponseT nearVector(Float[] vector, Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn) {
75+
public ResponseT nearVector(float[] vector, Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn) {
7676
return nearVector(NearVector.of(vector), fn);
7777
}
7878

79-
public ResponseT nearVector(Float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> nv,
79+
public ResponseT nearVector(float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> nv,
8080
Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn) {
8181
return nearVector(NearVector.of(vector, nv), fn);
8282
}
@@ -85,12 +85,12 @@ public ResponseT nearVector(NearVector filter, Function<Aggregation.Builder, Obj
8585
return performRequest(Aggregation.of(filter, fn));
8686
}
8787

88-
public GroupedResponseT nearVector(Float[] vector, Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn,
88+
public GroupedResponseT nearVector(float[] vector, Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn,
8989
GroupBy groupBy) {
9090
return nearVector(NearVector.of(vector), fn, groupBy);
9191
}
9292

93-
public GroupedResponseT nearVector(Float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> nv,
93+
public GroupedResponseT nearVector(float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> nv,
9494
Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn, GroupBy groupBy) {
9595
return nearVector(NearVector.of(vector, nv), fn, groupBy);
9696
}

src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ public static <T> void buildObject(WeaviateProtoBatch.BatchObject.Builder object
101101
var vector = WeaviateProtoBase.Vectors.newBuilder()
102102
.setName(entry.getKey());
103103

104-
if (value instanceof Float[] single) {
104+
if (value instanceof float[] single) {
105105
vector.setType(VectorType.VECTOR_TYPE_SINGLE_FP32);
106106
vector.setVectorBytes(ByteStringUtil.encodeVectorSingle(single));
107-
} else if (value instanceof Float[][] multi) {
107+
} else if (value instanceof float[][] multi) {
108108
vector.setVectorBytes(ByteStringUtil.encodeVectorMulti(multi));
109109
vector.setType(VectorType.VECTOR_TYPE_MULTI_FP32);
110110
}

src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,23 +110,23 @@ public GroupedResponseT hybrid(Hybrid query, GroupBy groupBy) {
110110

111111
// NearVector queries -------------------------------------------------------
112112

113-
public ResponseT nearVector(Float[] vector) {
113+
public ResponseT nearVector(float[] vector) {
114114
return nearVector(NearVector.of(vector));
115115
}
116116

117-
public ResponseT nearVector(Float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> fn) {
117+
public ResponseT nearVector(float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> fn) {
118118
return nearVector(NearVector.of(vector, fn));
119119
}
120120

121121
public ResponseT nearVector(NearVector query) {
122122
return performRequest(query);
123123
}
124124

125-
public GroupedResponseT nearVector(Float[] vector, GroupBy groupBy) {
125+
public GroupedResponseT nearVector(float[] vector, GroupBy groupBy) {
126126
return nearVector(NearVector.of(vector), groupBy);
127127
}
128128

129-
public GroupedResponseT nearVector(Float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> fn,
129+
public GroupedResponseT nearVector(float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> fn,
130130
GroupBy groupBy) {
131131
return nearVector(NearVector.of(vector, fn), groupBy);
132132
}

src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch;
1111
import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet;
1212

13-
public record NearVector(Float[] vector, Float distance, Float certainty, BaseQueryOptions common)
13+
public record NearVector(float[] vector, Float distance, Float certainty, BaseQueryOptions common)
1414
implements QueryOperator, AggregateObjectFilter {
1515

16-
public static final NearVector of(Float[] vector) {
16+
public static final NearVector of(float[] vector) {
1717
return of(vector, ObjectBuilder.identity());
1818
}
1919

20-
public static final NearVector of(Float[] vector, Function<Builder, ObjectBuilder<NearVector>> fn) {
20+
public static final NearVector of(float[] vector, Function<Builder, ObjectBuilder<NearVector>> fn) {
2121
return fn.apply(new Builder(vector)).build();
2222
}
2323

@@ -27,9 +27,9 @@ public NearVector(Builder builder) {
2727

2828
public static class Builder extends BaseVectorSearchBuilder<Builder, NearVector> {
2929
// Required query parameters.
30-
private final Float[] vector;
30+
private final float[] vector;
3131

32-
public Builder(Float[] vector) {
32+
public Builder(float[] vector) {
3333
this.vector = vector;
3434
}
3535

0 commit comments

Comments
 (0)