You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
Bloom commands (#1786)
* ft.alter * bloom commands * tdigest * delete tdigest * uncomment tests * small changes * Update MADD.ts * small changes * clean code * Update README.md * Update README.md Co-authored-by: leibale <leibale1998@gmail.com>
This commit is contained in:
41
packages/bloom/lib/commands/count-min-sketch/INCRBY.spec.ts
Normal file
41
packages/bloom/lib/commands/count-min-sketch/INCRBY.spec.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../../test-utils';
|
||||
import { transformArguments } from './INCRBY';
|
||||
|
||||
describe('CMS INCRBY', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('single item', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', {
|
||||
item: 'item',
|
||||
incrementBy: 1
|
||||
}),
|
||||
['CMS.INCRBY', 'key', 'item', '1']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple items', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', [{
|
||||
item: 'a',
|
||||
incrementBy: 1
|
||||
}, {
|
||||
item: 'b',
|
||||
incrementBy: 2
|
||||
}]),
|
||||
['CMS.INCRBY', 'key', 'a', '1', 'b', '2']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.cms.incrBy', async client => {
|
||||
await client.cms.initByDim('key', 1000, 5);
|
||||
assert.deepEqual(
|
||||
await client.cms.incrBy('key', {
|
||||
item: 'item',
|
||||
incrementBy: 1
|
||||
}),
|
||||
[1]
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
29
packages/bloom/lib/commands/count-min-sketch/INCRBY.ts
Normal file
29
packages/bloom/lib/commands/count-min-sketch/INCRBY.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
interface IncrByItem {
|
||||
item: string;
|
||||
incrementBy: number;
|
||||
}
|
||||
|
||||
export function transformArguments(
|
||||
key: string,
|
||||
items: IncrByItem | Array<IncrByItem>
|
||||
): Array<string> {
|
||||
const args = ['CMS.INCRBY', key];
|
||||
|
||||
if (Array.isArray(items)) {
|
||||
for (const item of items) {
|
||||
pushIncrByItem(args, item);
|
||||
}
|
||||
} else {
|
||||
pushIncrByItem(args, items);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
function pushIncrByItem(args: Array<string>, { item, incrementBy }: IncrByItem): void {
|
||||
args.push(item, incrementBy.toString());
|
||||
}
|
||||
|
||||
export declare function transformReply(): Array<number>;
|
25
packages/bloom/lib/commands/count-min-sketch/INFO.spec.ts
Normal file
25
packages/bloom/lib/commands/count-min-sketch/INFO.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../../test-utils';
|
||||
import { transformArguments } from './INFO';
|
||||
|
||||
describe('CMS INFO', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key'),
|
||||
['CMS.INFO', 'key']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.cms.info', async client => {
|
||||
await client.cms.initByDim('key', 1000, 5);
|
||||
|
||||
assert.deepEqual(
|
||||
await client.cms.info('key'),
|
||||
{
|
||||
width: 1000,
|
||||
depth: 5,
|
||||
count: 0
|
||||
}
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
30
packages/bloom/lib/commands/count-min-sketch/INFO.ts
Normal file
30
packages/bloom/lib/commands/count-min-sketch/INFO.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export const IS_READ_ONLY = true;
|
||||
|
||||
export function transformArguments(key: string): Array<string> {
|
||||
return ['CMS.INFO', key];
|
||||
}
|
||||
|
||||
export type InfoRawReply = [
|
||||
_: string,
|
||||
width: number,
|
||||
_: string,
|
||||
depth: number,
|
||||
_: string,
|
||||
count: number
|
||||
];
|
||||
|
||||
export interface InfoReply {
|
||||
width: number;
|
||||
depth: number;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export function transformReply(reply: InfoRawReply): InfoReply {
|
||||
return {
|
||||
width: reply[1],
|
||||
depth: reply[3],
|
||||
count: reply[5]
|
||||
};
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../../test-utils';
|
||||
import { transformArguments } from './INITBYDIM';
|
||||
|
||||
describe('CMS INITBYDIM', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 1000, 5),
|
||||
['CMS.INITBYDIM', 'key', '1000', '5']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.cms.initByDim', async client => {
|
||||
assert.equal(
|
||||
await client.cms.initByDim('key', 1000, 5),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
@@ -0,0 +1,7 @@
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export function transformArguments(key: string, width: number, depth: number): Array<string> {
|
||||
return ['CMS.INITBYDIM', key, width.toString(), depth.toString()];
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK';
|
@@ -0,0 +1,19 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../../test-utils';
|
||||
import { transformArguments } from './INITBYPROB';
|
||||
|
||||
describe('CMS INITBYPROB', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 0.001, 0.01),
|
||||
['CMS.INITBYPROB', 'key', '0.001', '0.01']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.cms.initByProb', async client => {
|
||||
assert.equal(
|
||||
await client.cms.initByProb('key', 0.001, 0.01),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
@@ -0,0 +1,7 @@
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export function transformArguments(key: string, error: number, probability: number): Array<string> {
|
||||
return ['CMS.INITBYPROB', key, error.toString(), probability.toString()];
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK';
|
36
packages/bloom/lib/commands/count-min-sketch/MERGE.spec.ts
Normal file
36
packages/bloom/lib/commands/count-min-sketch/MERGE.spec.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../../test-utils';
|
||||
import { transformArguments } from './MERGE';
|
||||
|
||||
describe('CMS MERGE', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('without WEIGHTS', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('dest', ['src']),
|
||||
['CMS.MERGE', 'dest', '1', 'src']
|
||||
);
|
||||
});
|
||||
|
||||
it('with WEIGHTS', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('dest', [{
|
||||
name: 'src',
|
||||
weight: 1
|
||||
}]),
|
||||
['CMS.MERGE', 'dest', '1', 'src', 'WEIGHTS', '1']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.cms.merge', async client => {
|
||||
await Promise.all([
|
||||
client.cms.initByDim('src', 1000, 5),
|
||||
client.cms.initByDim('dest', 1000, 5),
|
||||
]);
|
||||
|
||||
assert.equal(
|
||||
await client.cms.merge('dest', ['src']),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
37
packages/bloom/lib/commands/count-min-sketch/MERGE.ts
Normal file
37
packages/bloom/lib/commands/count-min-sketch/MERGE.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
interface Sketch {
|
||||
name: string;
|
||||
weight: number;
|
||||
}
|
||||
|
||||
type Sketches = Array<string> | Array<Sketch>;
|
||||
|
||||
export function transformArguments(dest: string, src: Sketches): Array<string> {
|
||||
const args = [
|
||||
'CMS.MERGE',
|
||||
dest,
|
||||
src.length.toString()
|
||||
];
|
||||
|
||||
if (isStringSketches(src)) {
|
||||
args.push(...src);
|
||||
} else {
|
||||
for (const sketch of src) {
|
||||
args.push(sketch.name);
|
||||
}
|
||||
|
||||
args.push('WEIGHTS');
|
||||
for (const sketch of src) {
|
||||
args.push(sketch.weight.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
function isStringSketches(src: Sketches): src is Array<string> {
|
||||
return typeof src[0] === 'string';
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK';
|
22
packages/bloom/lib/commands/count-min-sketch/QUERY.spec.ts
Normal file
22
packages/bloom/lib/commands/count-min-sketch/QUERY.spec.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../../test-utils';
|
||||
import { transformArguments } from './QUERY';
|
||||
|
||||
describe('CMS QUERY', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 'item'),
|
||||
['CMS.QUERY', 'key', 'item']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.cms.query', async client => {
|
||||
await client.cms.initByDim('key', 1000, 5);
|
||||
|
||||
assert.deepEqual(
|
||||
await client.cms.query('key', 'item'),
|
||||
[0]
|
||||
);
|
||||
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
15
packages/bloom/lib/commands/count-min-sketch/QUERY.ts
Normal file
15
packages/bloom/lib/commands/count-min-sketch/QUERY.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { RedisCommandArguments } from '@node-redis/client/dist/lib/commands';
|
||||
import { pushVerdictArguments } from '@node-redis/client/dist/lib/commands/generic-transformers';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export const IS_READ_ONLY = true;
|
||||
|
||||
export function transformArguments(
|
||||
key: string,
|
||||
items: string | Array<string>
|
||||
): RedisCommandArguments {
|
||||
return pushVerdictArguments(['CMS.QUERY', key], items);
|
||||
}
|
||||
|
||||
export declare function transformReply(): Array<number>;
|
21
packages/bloom/lib/commands/count-min-sketch/index.ts
Normal file
21
packages/bloom/lib/commands/count-min-sketch/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import * as INCRBY from './INCRBY';
|
||||
import * as INFO from './INFO';
|
||||
import * as INITBYDIM from './INITBYDIM';
|
||||
import * as INITBYPROB from './INITBYPROB';
|
||||
import * as MERGE from './MERGE';
|
||||
import * as QUERY from './QUERY';
|
||||
|
||||
export default {
|
||||
INCRBY,
|
||||
incrBy: INCRBY,
|
||||
INFO,
|
||||
info: INFO,
|
||||
INITBYDIM,
|
||||
initByDim: INITBYDIM,
|
||||
INITBYPROB,
|
||||
initByProb: INITBYPROB,
|
||||
MERGE,
|
||||
merge: MERGE,
|
||||
QUERY,
|
||||
query: QUERY
|
||||
};
|
Reference in New Issue
Block a user