Skip to content

Commit 339065f

Browse files
committed
wip
1 parent 5d205cf commit 339065f

25 files changed

+769
-1
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { strict as assert } from 'node:assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import VADD from './VADD';
4+
import { parseArgs } from './generic-transformers';
5+
6+
describe('VADD', () => {
7+
describe('transformArguments', () => {
8+
it('with VALUES', () => {
9+
assert.deepEqual(
10+
parseArgs(VADD, 'key', [1.0, 2.0, 3.0], 'element'),
11+
['VADD', 'key', 'VALUES', '3', '1', '2', '3', 'element']
12+
);
13+
});
14+
15+
it('with FP32', () => {
16+
assert.deepEqual(
17+
parseArgs(VADD, 'key', Buffer.from([0x3f, 0x80, 0x00, 0x00]), 'element'),
18+
['VADD', 'key', 'FP32', Buffer.from([0x3f, 0x80, 0x00, 0x00]), 'element']
19+
);
20+
});
21+
22+
it('with options', () => {
23+
assert.deepEqual(
24+
parseArgs(VADD, 'key', [1.0, 2.0], 'element', {
25+
REDUCE: 50,
26+
CAS: true,
27+
Q8: true,
28+
EF: 200,
29+
SETATTR: { name: 'test', value: 42 },
30+
M: 16
31+
}),
32+
[
33+
'VADD', 'key', 'REDUCE', '50', 'VALUES', '2', '1', '2', 'element',
34+
'CAS', 'Q8', 'EF', '200', 'SETATTR', '{"name":"test","value":42}', 'M', '16'
35+
]
36+
);
37+
});
38+
});
39+
40+
testUtils.testAll('vAdd', async client => {
41+
assert.equal(
42+
await client.vAdd('key', [1.0, 2.0, 3.0], 'element'),
43+
1
44+
);
45+
}, {
46+
client: GLOBAL.SERVERS.OPEN,
47+
cluster: GLOBAL.CLUSTERS.OPEN
48+
});
49+
});

packages/client/lib/commands/VADD.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { CommandParser } from '../client/parser';
2+
import { RedisArgument, NumberReply, Command } from '../RESP/types';
3+
import { transformDoubleArgument } from './generic-transformers';
4+
5+
export interface VAddOptions {
6+
REDUCE?: number;
7+
CAS?: boolean;
8+
NOQUANT?: boolean;
9+
Q8?: boolean;
10+
BIN?: boolean;
11+
EF?: number;
12+
SETATTR?: Record<string, any>;
13+
M?: number;
14+
}
15+
16+
export default {
17+
/**
18+
* Add a new element into the vector set specified by key
19+
*
20+
* @param parser - The command parser
21+
* @param key - The name of the key that will hold the vector set data
22+
* @param vector - The vector data as FP32 blob or array of numbers
23+
* @param element - The name of the element being added to the vector set
24+
* @param options - Optional parameters for vector addition
25+
* @see https://redis.io/commands/vadd/
26+
*/
27+
parseCommand(
28+
parser: CommandParser,
29+
key: RedisArgument,
30+
vector: RedisArgument | Array<number>,
31+
element: RedisArgument,
32+
options?: VAddOptions
33+
) {
34+
parser.push('VADD');
35+
parser.pushKey(key);
36+
37+
if (options?.REDUCE !== undefined) {
38+
parser.push('REDUCE', options.REDUCE.toString());
39+
}
40+
41+
if (Array.isArray(vector)) {
42+
parser.push('VALUES', vector.length.toString());
43+
for (const value of vector) {
44+
parser.push(transformDoubleArgument(value));
45+
}
46+
} else {
47+
parser.push('FP32', vector);
48+
}
49+
50+
parser.push(element);
51+
52+
if (options?.CAS) {
53+
parser.push('CAS');
54+
}
55+
56+
if (options?.NOQUANT) {
57+
parser.push('NOQUANT');
58+
} else if (options?.Q8) {
59+
parser.push('Q8');
60+
} else if (options?.BIN) {
61+
parser.push('BIN');
62+
}
63+
64+
if (options?.EF !== undefined) {
65+
parser.push('EF', options.EF.toString());
66+
}
67+
68+
if (options?.SETATTR) {
69+
parser.push('SETATTR', JSON.stringify(options.SETATTR));
70+
}
71+
72+
if (options?.M !== undefined) {
73+
parser.push('M', options.M.toString());
74+
}
75+
},
76+
transformReply: undefined as unknown as () => NumberReply
77+
} as const satisfies Command;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { strict as assert } from 'node:assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import VCARD from './VCARD';
4+
import { parseArgs } from './generic-transformers';
5+
6+
describe('VCARD', () => {
7+
it('transformArguments', () => {
8+
assert.deepEqual(
9+
parseArgs(VCARD, 'key'),
10+
['VCARD', 'key']
11+
);
12+
});
13+
14+
testUtils.testAll('vCard', async client => {
15+
await client.vAdd('key', [1.0, 2.0, 3.0], 'element1');
16+
await client.vAdd('key', [4.0, 5.0, 6.0], 'element2');
17+
18+
assert.equal(
19+
await client.vCard('key'),
20+
2
21+
);
22+
}, {
23+
client: GLOBAL.SERVERS.OPEN,
24+
cluster: GLOBAL.CLUSTERS.OPEN
25+
});
26+
});

packages/client/lib/commands/VCARD.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { CommandParser } from '../client/parser';
2+
import { RedisArgument, NumberReply, Command } from '../RESP/types';
3+
4+
export default {
5+
CACHEABLE: true,
6+
IS_READ_ONLY: true,
7+
/**
8+
* Retrieve the number of elements in a vector set
9+
*
10+
* @param parser - The command parser
11+
* @param key - The key of the vector set
12+
* @see https://redis.io/commands/vcard/
13+
*/
14+
parseCommand(parser: CommandParser, key: RedisArgument) {
15+
parser.push('VCARD');
16+
parser.pushKey(key);
17+
},
18+
transformReply: undefined as unknown as () => NumberReply
19+
} as const satisfies Command;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { strict as assert } from 'node:assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import VDIM from './VDIM';
4+
import { parseArgs } from './generic-transformers';
5+
6+
describe('VDIM', () => {
7+
it('transformArguments', () => {
8+
assert.deepEqual(
9+
parseArgs(VDIM, 'key'),
10+
['VDIM', 'key']
11+
);
12+
});
13+
14+
testUtils.testAll('vDim', async client => {
15+
await client.vAdd('key', [1.0, 2.0, 3.0], 'element');
16+
17+
assert.equal(
18+
await client.vDim('key'),
19+
3
20+
);
21+
}, {
22+
client: GLOBAL.SERVERS.OPEN,
23+
cluster: GLOBAL.CLUSTERS.OPEN
24+
});
25+
});

packages/client/lib/commands/VDIM.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { CommandParser } from '../client/parser';
2+
import { RedisArgument, NumberReply, Command } from '../RESP/types';
3+
4+
export default {
5+
CACHEABLE: true,
6+
IS_READ_ONLY: true,
7+
/**
8+
* Retrieve the dimension of the vectors in a vector set
9+
*
10+
* @param parser - The command parser
11+
* @param key - The key of the vector set
12+
* @see https://redis.io/commands/vdim/
13+
*/
14+
parseCommand(parser: CommandParser, key: RedisArgument) {
15+
parser.push('VDIM');
16+
parser.pushKey(key);
17+
},
18+
transformReply: undefined as unknown as () => NumberReply
19+
} as const satisfies Command;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { strict as assert } from 'node:assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import VEMB from './VEMB';
4+
import { parseArgs } from './generic-transformers';
5+
6+
describe('VEMB', () => {
7+
it('transformArguments', () => {
8+
assert.deepEqual(
9+
parseArgs(VEMB, 'key', 'element'),
10+
['VEMB', 'key', 'element']
11+
);
12+
});
13+
14+
testUtils.testAll('vEmb', async client => {
15+
await client.vAdd('key', [1.0, 2.0, 3.0], 'element');
16+
17+
const result = await client.vEmb('key', 'element');
18+
assert.ok(Array.isArray(result));
19+
assert.equal(result.length, 3);
20+
}, {
21+
client: GLOBAL.SERVERS.OPEN,
22+
cluster: GLOBAL.CLUSTERS.OPEN
23+
});
24+
});

packages/client/lib/commands/VEMB.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { CommandParser } from '../client/parser';
2+
import { RedisArgument, ArrayReply, DoubleReply, Command } from '../RESP/types';
3+
4+
export default {
5+
CACHEABLE: true,
6+
IS_READ_ONLY: true,
7+
/**
8+
* Retrieve the approximate vector associated with a vector set element
9+
*
10+
* @param parser - The command parser
11+
* @param key - The key of the vector set
12+
* @param element - The name of the element to retrieve the vector for
13+
* @see https://redis.io/commands/vemb/
14+
*/
15+
parseCommand(parser: CommandParser, key: RedisArgument, element: RedisArgument) {
16+
parser.push('VEMB');
17+
parser.pushKey(key);
18+
parser.push(element);
19+
},
20+
transformReply: undefined as unknown as () => ArrayReply<DoubleReply>
21+
} as const satisfies Command;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { strict as assert } from 'node:assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import VGETATTR from './VGETATTR';
4+
import { parseArgs } from './generic-transformers';
5+
6+
describe('VGETATTR', () => {
7+
it('transformArguments', () => {
8+
assert.deepEqual(
9+
parseArgs(VGETATTR, 'key', 'element'),
10+
['VGETATTR', 'key', 'element']
11+
);
12+
});
13+
14+
testUtils.testAll('vGetAttr', async client => {
15+
await client.vAdd('key', [1.0, 2.0, 3.0], 'element');
16+
await client.vSetAttr('key', 'element', { name: 'test' });
17+
18+
const result = await client.vGetAttr('key', 'element');
19+
assert.ok(result !== null);
20+
}, {
21+
client: GLOBAL.SERVERS.OPEN,
22+
cluster: GLOBAL.CLUSTERS.OPEN
23+
});
24+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { CommandParser } from '../client/parser';
2+
import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types';
3+
4+
export default {
5+
CACHEABLE: true,
6+
IS_READ_ONLY: true,
7+
/**
8+
* Retrieve the attributes of a vector set element
9+
*
10+
* @param parser - The command parser
11+
* @param key - The key of the vector set
12+
* @param element - The name of the element to retrieve attributes for
13+
* @see https://redis.io/commands/vgetattr/
14+
*/
15+
parseCommand(parser: CommandParser, key: RedisArgument, element: RedisArgument) {
16+
parser.push('VGETATTR');
17+
parser.pushKey(key);
18+
parser.push(element);
19+
},
20+
transformReply: undefined as unknown as () => BlobStringReply | NullReply
21+
} as const satisfies Command;

0 commit comments

Comments
 (0)