Skip to content

Commit be90e62

Browse files
authored
Add support for T-Digest (#2214)
* wip * close #2216 - add support for TDIGEST.MERGESTORE and make compression optional on TDIGEST.CREATE * fix some tdigest commands, use bloom edge docker * fix index.ts * 2.4-RC2 (v2.4.1) * fix some commands and tests * clean code
1 parent 1c6d74f commit be90e62

33 files changed

+794
-20
lines changed

packages/bloom/lib/commands/index.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import Bloom from './bloom';
2-
import CountMinSketch from './count-min-sketch';
3-
import Cuckoo from './cuckoo';
4-
import TopK from './top-k';
1+
import bf from './bloom';
2+
import cms from './count-min-sketch';
3+
import cf from './cuckoo';
4+
import tDigest from './t-digest';
5+
import topK from './top-k';
56

67
export default {
7-
bf: Bloom,
8-
cms: CountMinSketch,
9-
cf: Cuckoo,
10-
topK: TopK
8+
bf,
9+
cms,
10+
cf,
11+
tDigest,
12+
topK
1113
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { strict as assert } from 'assert';
2+
import testUtils, { GLOBAL } from '../../test-utils';
3+
import { transformArguments } from './ADD';
4+
5+
describe('TDIGEST.ADD', () => {
6+
it('transformArguments', () => {
7+
assert.deepEqual(
8+
transformArguments('key', [1, 2]),
9+
['TDIGEST.ADD', 'key', '1', '2']
10+
);
11+
});
12+
13+
testUtils.testWithClient('client.tDigest.add', async client => {
14+
const [ , reply ] = await Promise.all([
15+
client.tDigest.create('key'),
16+
client.tDigest.add('key', [1])
17+
]);
18+
19+
assert.equal(reply, 'OK');
20+
}, GLOBAL.SERVERS.OPEN);
21+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
2+
3+
export const FIRST_KEY_INDEX = 1;
4+
5+
export function transformArguments(
6+
key: RedisCommandArgument,
7+
values: Array<number>
8+
): RedisCommandArguments {
9+
const args = ['TDIGEST.ADD', key];
10+
for (const item of values) {
11+
args.push(item.toString());
12+
}
13+
14+
return args;
15+
}
16+
17+
export declare function transformReply(): 'OK';
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { strict as assert } from 'assert';
2+
import testUtils, { GLOBAL } from '../../test-utils';
3+
import { transformArguments } from './BYRANK';
4+
5+
describe('TDIGEST.BYRANK', () => {
6+
it('transformArguments', () => {
7+
assert.deepEqual(
8+
transformArguments('key', [1, 2]),
9+
['TDIGEST.BYRANK', 'key', '1', '2']
10+
);
11+
});
12+
13+
testUtils.testWithClient('client.tDigest.byRank', async client => {
14+
const [ , reply ] = await Promise.all([
15+
client.tDigest.create('key'),
16+
client.tDigest.byRank('key', [1])
17+
]);
18+
19+
assert.deepEqual(reply, [NaN]);
20+
}, GLOBAL.SERVERS.OPEN);
21+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
2+
3+
export const FIRST_KEY_INDEX = 1;
4+
5+
export const IS_READ_ONLY = true;
6+
7+
export function transformArguments(
8+
key: RedisCommandArgument,
9+
ranks: Array<number>
10+
): RedisCommandArguments {
11+
const args = ['TDIGEST.BYRANK', key];
12+
for (const rank of ranks) {
13+
args.push(rank.toString());
14+
}
15+
16+
return args;
17+
}
18+
19+
export { transformDoublesReply as transformReply } from '.';
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { strict as assert } from 'assert';
2+
import testUtils, { GLOBAL } from '../../test-utils';
3+
import { transformArguments } from './BYREVRANK';
4+
5+
describe('TDIGEST.BYREVRANK', () => {
6+
it('transformArguments', () => {
7+
assert.deepEqual(
8+
transformArguments('key', [1, 2]),
9+
['TDIGEST.BYREVRANK', 'key', '1', '2']
10+
);
11+
});
12+
13+
testUtils.testWithClient('client.tDigest.byRevRank', async client => {
14+
const [ , reply ] = await Promise.all([
15+
client.tDigest.create('key'),
16+
client.tDigest.byRevRank('key', [1])
17+
]);
18+
19+
assert.deepEqual(reply, [NaN]);
20+
}, GLOBAL.SERVERS.OPEN);
21+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
2+
3+
export const FIRST_KEY_INDEX = 1;
4+
5+
export const IS_READ_ONLY = true;
6+
7+
export function transformArguments(
8+
key: RedisCommandArgument,
9+
ranks: Array<number>
10+
): RedisCommandArguments {
11+
const args = ['TDIGEST.BYREVRANK', key];
12+
for (const rank of ranks) {
13+
args.push(rank.toString());
14+
}
15+
16+
return args;
17+
}
18+
19+
export { transformDoublesReply as transformReply } from '.';
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { strict as assert } from 'assert';
2+
import testUtils, { GLOBAL } from '../../test-utils';
3+
import { transformArguments } from './CDF';
4+
5+
describe('TDIGEST.CDF', () => {
6+
it('transformArguments', () => {
7+
assert.deepEqual(
8+
transformArguments('key', [1, 2]),
9+
['TDIGEST.CDF', 'key', '1', '2']
10+
);
11+
});
12+
13+
testUtils.testWithClient('client.tDigest.cdf', async client => {
14+
const [ , reply ] = await Promise.all([
15+
client.tDigest.create('key'),
16+
client.tDigest.cdf('key', [1])
17+
]);
18+
19+
assert.deepEqual(reply, [NaN]);
20+
}, GLOBAL.SERVERS.OPEN);
21+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
2+
3+
export const FIRST_KEY_INDEX = 1;
4+
5+
export const IS_READ_ONLY = true;
6+
7+
export function transformArguments(
8+
key: RedisCommandArgument,
9+
values: Array<number>
10+
): RedisCommandArguments {
11+
const args = ['TDIGEST.CDF', key];
12+
for (const item of values) {
13+
args.push(item.toString());
14+
}
15+
16+
return args;
17+
}
18+
19+
export { transformDoublesReply as transformReply } from '.';
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { strict as assert } from 'assert';
2+
import testUtils, { GLOBAL } from '../../test-utils';
3+
import { transformArguments } from './CREATE';
4+
5+
describe('TDIGEST.CREATE', () => {
6+
describe('transformArguments', () => {
7+
it('without options', () => {
8+
assert.deepEqual(
9+
transformArguments('key'),
10+
['TDIGEST.CREATE', 'key']
11+
);
12+
});
13+
14+
it('with COMPRESSION', () => {
15+
assert.deepEqual(
16+
transformArguments('key', {
17+
COMPRESSION: 100
18+
}),
19+
['TDIGEST.CREATE', 'key', 'COMPRESSION', '100']
20+
);
21+
});
22+
});
23+
24+
testUtils.testWithClient('client.tDigest.create', async client => {
25+
assert.equal(
26+
await client.tDigest.create('key'),
27+
'OK'
28+
);
29+
}, GLOBAL.SERVERS.OPEN);
30+
});

0 commit comments

Comments
 (0)