Skip to content

Commit 5d31674

Browse files
committed
add RAW variant for VEMB -> VEMB_RAW
1 parent 1afe3d7 commit 5d31674

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { strict as assert } from 'node:assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import VEMB_RAW from './VEMB_RAW';
4+
import { parseArgs } from './generic-transformers';
5+
6+
describe('VEMB_RAW', () => {
7+
it('transformArguments', () => {
8+
assert.deepEqual(
9+
parseArgs(VEMB_RAW, 'key', 'element'),
10+
['VEMB', 'key', 'element', 'RAW']
11+
);
12+
});
13+
14+
testUtils.testAll('vEmbRaw', async client => {
15+
await client.vAdd('key1', [1.0, 2.0, 3.0], 'element');
16+
const result1 = await client.vEmbRaw('key1', 'element');
17+
assert.equal(result1.quantization, 'int8');
18+
assert.ok(result1.quantizationRange !== undefined);
19+
20+
await client.vAdd('key2', [1.0, 2.0, 3.0], 'element', { QUANT: 'Q8' });
21+
const result2 = await client.vEmbRaw('key2', 'element');
22+
assert.equal(result2.quantization, 'int8');
23+
assert.ok(result2.quantizationRange !== undefined);
24+
25+
await client.vAdd('key3', [1.0, 2.0, 3.0], 'element', { QUANT: 'NOQUANT' });
26+
const result3 = await client.vEmbRaw('key3', 'element');
27+
assert.equal(result3.quantization, 'f32');
28+
assert.equal(result3.quantizationRange, undefined);
29+
30+
await client.vAdd('key4', [1.0, 2.0, 3.0], 'element', { QUANT: 'BIN' });
31+
const result4 = await client.vEmbRaw('key4', 'element');
32+
assert.equal(result4.quantization, 'bin');
33+
assert.equal(result4.quantizationRange, undefined);
34+
}, {
35+
client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 0] },
36+
cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 0] }
37+
});
38+
39+
testUtils.testWithClient('vEmbRaw with RESP3', async client => {
40+
await client.vAdd('key1', [1.0, 2.0, 3.0], 'element');
41+
const result1 = await client.vEmbRaw('key1', 'element');
42+
assert.equal(result1.quantization, 'int8');
43+
assert.ok(result1.quantizationRange !== undefined);
44+
45+
await client.vAdd('key2', [1.0, 2.0, 3.0], 'element', { QUANT: 'Q8' });
46+
const result2 = await client.vEmbRaw('key2', 'element');
47+
assert.equal(result2.quantization, 'int8');
48+
assert.ok(result2.quantizationRange !== undefined);
49+
50+
await client.vAdd('key3', [1.0, 2.0, 3.0], 'element', { QUANT: 'NOQUANT' });
51+
const result3 = await client.vEmbRaw('key3', 'element');
52+
assert.equal(result3.quantization, 'f32');
53+
assert.equal(result3.quantizationRange, undefined);
54+
55+
await client.vAdd('key4', [1.0, 2.0, 3.0], 'element', { QUANT: 'BIN' });
56+
const result4 = await client.vEmbRaw('key4', 'element');
57+
assert.equal(result4.quantization, 'bin');
58+
assert.equal(result4.quantizationRange, undefined);
59+
}, {
60+
...GLOBAL.SERVERS.OPEN,
61+
clientOptions: {
62+
RESP: 3
63+
},
64+
minimumDockerVersion: [8, 0]
65+
});
66+
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { CommandParser } from '../client/parser';
2+
import {
3+
RedisArgument,
4+
Command,
5+
BlobStringReply,
6+
SimpleStringReply,
7+
DoubleReply
8+
} from '../RESP/types';
9+
import { transformDoubleReply } from './generic-transformers';
10+
import VEMB from './VEMB';
11+
12+
type RawVembReply = {
13+
quantization: SimpleStringReply;
14+
raw: BlobStringReply;
15+
l2Norm: DoubleReply;
16+
quantizationRange?: DoubleReply;
17+
};
18+
19+
const transformRawVembReply = {
20+
2: (reply: any[]): RawVembReply => {
21+
return {
22+
quantization: reply[0],
23+
raw: reply[1],
24+
l2Norm: transformDoubleReply[2](reply[2]),
25+
...(reply[3] !== undefined && { quantizationRange: transformDoubleReply[2](reply[3]) })
26+
};
27+
},
28+
3: (reply: any[]): RawVembReply => {
29+
return {
30+
quantization: reply[0],
31+
raw: reply[1],
32+
l2Norm: reply[2],
33+
quantizationRange: reply[3]
34+
};
35+
},
36+
};
37+
38+
export default {
39+
IS_READ_ONLY: true,
40+
/**
41+
* Retrieve the RAW approximate vector associated with a vector set element
42+
*
43+
* @param parser - The command parser
44+
* @param key - The key of the vector set
45+
* @param element - The name of the element to retrieve the vector for
46+
* @see https://redis.io/commands/vemb/
47+
*/
48+
parseCommand(
49+
parser: CommandParser,
50+
key: RedisArgument,
51+
element: RedisArgument
52+
) {
53+
VEMB.parseCommand(parser, key, element);
54+
parser.push('RAW');
55+
},
56+
transformReply: transformRawVembReply
57+
} as const satisfies Command;

packages/client/lib/commands/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ import VADD from './VADD';
348348
import VCARD from './VCARD';
349349
import VDIM from './VDIM';
350350
import VEMB from './VEMB';
351+
import VEMB_RAW from './VEMB_RAW';
351352
import VGETATTR from './VGETATTR';
352353
import VINFO from './VINFO';
353354
import VLINKS from './VLINKS';
@@ -1059,6 +1060,8 @@ export default {
10591060
vDim: VDIM,
10601061
VEMB,
10611062
vEmb: VEMB,
1063+
VEMB_RAW,
1064+
vEmbRaw: VEMB_RAW,
10621065
VGETATTR,
10631066
vGetAttr: VGETATTR,
10641067
VINFO,

0 commit comments

Comments
 (0)