Skip to content

Commit affb536

Browse files
authored
Support Redis 8 vector sets #4169 (#4203)
* Initial vector set commit Add support for - VRANDMEMBER - vlinks - vrem - vemb - vcard - vadd - vsim - vdim * Add UnifiedJedis vadd integration tests * Add support for reduce dim in vadd * Add support for vgetattr * Add support for vsetattr * Add support for vinfo * Add VDIM, VCARD integration test * Add VEMB integration test * Add VSETATTR/VGETATTR integration test * Add VLINKS integration test * Add VRANDMEMBER integration test * Add VREM integration test * Add VSIM integration test & refactor * cleanup * add missing RawVector * fix failing tests * fix PooledExtendedVectorSetCommandsTest * mark vector-set api as Experimental - Add integration test for Jedis client * Fix tests * clean up * Address review comments - remove duplicated DOUBLE_LIST - reduce code duplication * fix tests after merge conflict is resolved * format new files * Add EPSILON parameter * fix errors in javadocs (java 8) * fix errors after rebase
1 parent 9187e24 commit affb536

File tree

57 files changed

+6727
-174
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+6727
-174
lines changed

pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,10 @@
348348
<include>src/test/java/redis/clients/jedis/commands/jedis/ClusterStreamsCommandsTest.java</include>
349349
<include>src/test/java/redis/clients/jedis/commands/jedis/PooledStreamsCommandsTest.java</include>
350350
<include>src/test/java/redis/clients/jedis/resps/StreamEntryDeletionResultTest.java</include>
351+
<include>**/VectorSet*.java</include>
352+
<include>**/VectorTestUtils.java</include>
353+
<include>**/VAddParams.java</include>
354+
<include>**/VSimParams.java</include>
351355
<include>**/*FunctionCommandsTest*</include>
352356
</includes>
353357
</configuration>

src/main/java/redis/clients/jedis/BuilderFactory.java

Lines changed: 183 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ public String toString() {
190190

191191
public static final Builder<Set<byte[]>> BINARY_SET = new Builder<Set<byte[]>>() {
192192
@Override
193-
@SuppressWarnings("unchecked")
194193
public Set<byte[]> build(Object data) {
195194
if (null == data) {
196195
return null;
@@ -477,6 +476,66 @@ public String toString() {
477476
}
478477
};
479478

479+
public static final Builder<Map<String, Double>> STRING_DOUBLE_MAP = new Builder<Map<String, Double>>() {
480+
@Override
481+
@SuppressWarnings("unchecked")
482+
public Map<String, Double> build(Object data) {
483+
final List<Object> list = (List<Object>) data;
484+
if (list.isEmpty()) return Collections.emptyMap();
485+
486+
if (list.get(0) instanceof KeyValue) {
487+
final Map<String, Double> map = new LinkedHashMap<>(list.size(), 1f);
488+
for (Object o : list) {
489+
KeyValue<?, ?> kv = (KeyValue<?, ?>) o;
490+
map.put(STRING.build(kv.getKey()), DOUBLE.build(kv.getValue()));
491+
}
492+
return map;
493+
} else {
494+
final Map<String, Double> map = new LinkedHashMap<>(list.size() / 2, 1f);
495+
final Iterator iterator = list.iterator();
496+
while (iterator.hasNext()) {
497+
map.put(STRING.build(iterator.next()), DOUBLE.build(iterator.next()));
498+
}
499+
return map;
500+
}
501+
}
502+
503+
@Override
504+
public String toString() {
505+
return "Map<String, Double>";
506+
}
507+
};
508+
509+
510+
public static final Builder<Map<byte[], Double>> BINARY_DOUBLE_MAP = new Builder<Map<byte[], Double>>() {
511+
@Override
512+
@SuppressWarnings("unchecked")
513+
public Map<byte[], Double> build(Object data) {
514+
final List<Object> list = (List<Object>) data;
515+
if (list.isEmpty()) return Collections.emptyMap();
516+
517+
if (list.get(0) instanceof KeyValue) {
518+
final Map<byte[], Double> map = new LinkedHashMap<>(list.size(), 1f);
519+
for (Object o : list) {
520+
KeyValue<?, ?> kv = (KeyValue<?, ?>) o;
521+
map.put(BINARY.build(kv.getKey()), DOUBLE.build(kv.getValue()));
522+
}
523+
return map;
524+
} else {
525+
final Map<byte[], Double> map = new LinkedHashMap<>(list.size() / 2, 1f);
526+
final Iterator iterator = list.iterator();
527+
while (iterator.hasNext()) {
528+
map.put(BINARY.build(iterator.next()), DOUBLE.build(iterator.next()));
529+
}
530+
return map;
531+
}
532+
}
533+
534+
@Override
535+
public String toString() {
536+
return "Map<String, Double>";
537+
}
538+
};
480539
public static final Builder<KeyValue<String, String>> KEYED_ELEMENT = new Builder<KeyValue<String, String>>() {
481540
@Override
482541
@SuppressWarnings("unchecked")
@@ -1817,6 +1876,43 @@ public String toString() {
18171876
@Deprecated
18181877
public static final Builder<StreamFullInfo> STREAM_INFO_FULL = STREAM_FULL_INFO;
18191878

1879+
public static final Builder<VectorInfo> VECTOR_INFO = new Builder<VectorInfo>() {
1880+
1881+
final Map<String, Builder> mappingFunctions = createDecoderMap();
1882+
1883+
private Map<String, Builder> createDecoderMap() {
1884+
Map<String, Builder> tempMappingFunctions = new HashMap<>();
1885+
tempMappingFunctions.put(VectorInfo.VECTOR_DIM, LONG);
1886+
tempMappingFunctions.put(VectorInfo.TYPE, STRING);
1887+
tempMappingFunctions.put(VectorInfo.SIZE, LONG);
1888+
tempMappingFunctions.put(VectorInfo.MAX_NODE_UID, LONG);
1889+
tempMappingFunctions.put(VectorInfo.VSET_UID, LONG);
1890+
tempMappingFunctions.put(VectorInfo.MAX_NODES, LONG);
1891+
tempMappingFunctions.put(VectorInfo.PROJECTION_INPUT_DIM, LONG);
1892+
tempMappingFunctions.put(VectorInfo.ATTRIBUTES_COUNT, LONG);
1893+
tempMappingFunctions.put(VectorInfo.MAX_LEVEL, LONG);
1894+
return tempMappingFunctions;
1895+
}
1896+
1897+
@Override
1898+
@SuppressWarnings("unchecked")
1899+
public VectorInfo build(Object data) {
1900+
if (null == data) {
1901+
return null;
1902+
}
1903+
1904+
List<Object> vectorEntries = (List<Object>) data;
1905+
Iterator<Object> iterator = vectorEntries.iterator();
1906+
1907+
return new VectorInfo(createMapFromDecodingFunctions(iterator, mappingFunctions));
1908+
}
1909+
1910+
@Override
1911+
public String toString() {
1912+
return "VectorInfo";
1913+
}
1914+
};
1915+
18201916
public static final Builder<StreamPendingSummary> STREAM_PENDING_SUMMARY = new Builder<StreamPendingSummary>() {
18211917
@Override
18221918
@SuppressWarnings("unchecked")
@@ -2152,6 +2248,92 @@ public String toString() {
21522248
}
21532249
};
21542250

2251+
// Vector Set builders
2252+
2253+
2254+
public static final Builder<RawVector> VEMB_RAW_RESULT = new Builder<RawVector>() {
2255+
@Override
2256+
@SuppressWarnings("unchecked")
2257+
public RawVector build(Object data) {
2258+
if (data == null) return null;
2259+
List<Object> list = (List<Object>) data;
2260+
2261+
String quantizationType = STRING.build(list.get(0));
2262+
byte[] rawData = (byte[]) list.get(1);
2263+
Double norm = DOUBLE.build(list.get(2));
2264+
Double quantizationRange = list.size() > 3 ? DOUBLE.build(list.get(3)) : null;
2265+
2266+
return new RawVector(quantizationType, rawData, norm, quantizationRange);
2267+
}
2268+
2269+
@Override
2270+
public String toString() {
2271+
return "RawVector";
2272+
}
2273+
};
2274+
2275+
// VLINKS builders
2276+
public static final Builder<List<Map<String, Double>>> VLINKS_WITH_SCORES_RESULT = new Builder<List<Map<String, Double>>>() {
2277+
@Override
2278+
@SuppressWarnings("unchecked")
2279+
public List<Map<String, Double>> build(Object data) {
2280+
if (data == null) return null;
2281+
List<Object> list = (List<Object>) data;
2282+
2283+
List<Map<String, Double>> result = new ArrayList<>();
2284+
for (Object scoresRaw : list) {
2285+
if (scoresRaw == null) continue;
2286+
Map<String, Double> scores = STRING_DOUBLE_MAP.build(scoresRaw);
2287+
result.add(scores);
2288+
}
2289+
2290+
return result;
2291+
}
2292+
2293+
@Override
2294+
public String toString() {
2295+
return "List<Map<String, Double>>";
2296+
}
2297+
};
2298+
2299+
public static final Builder<List<List<byte[]>>> BINARY_LIST_LIST = new Builder<List<List<byte[]>>>() {
2300+
@Override
2301+
@SuppressWarnings("unchecked")
2302+
public List<List<byte[]>> build(Object data) {
2303+
if (null == data) return null;
2304+
return ((List<Object>) data).stream().map(BINARY_LIST::build).collect(Collectors.toList());
2305+
}
2306+
2307+
@Override
2308+
public String toString() {
2309+
return "List<List<String>>";
2310+
}
2311+
};
2312+
2313+
2314+
public static final Builder<List<Map<byte[], Double>>> VLINKS_WITH_SCORES_RESULT_BINARY = new Builder<List<Map<byte[], Double>>>() {
2315+
@Override
2316+
@SuppressWarnings("unchecked")
2317+
public List<Map<byte[], Double>> build(Object data) {
2318+
if (data == null) return null;
2319+
List<Object> list = (List<Object>) data;
2320+
2321+
List<Map<byte[], Double>> result = new ArrayList<>();
2322+
for (Object scoresRaw : list) {
2323+
if (scoresRaw == null) continue;
2324+
Map<byte[], Double> scores = BINARY_DOUBLE_MAP.build(scoresRaw);
2325+
result.add(scores);
2326+
}
2327+
2328+
return result;
2329+
}
2330+
2331+
@Override
2332+
public String toString() {
2333+
return "List<Map<byte[], Double>>";
2334+
}
2335+
};
2336+
21552337
/**
21562338
* A decorator to implement Set from List. Assume that given List do not contains duplicated
21572339
* values. The resulting set displays the same ordering, concurrency, and performance

0 commit comments

Comments
 (0)