From 38c52751239226fe60236053508f8a0360ad96fa Mon Sep 17 00:00:00 2001 From: Shaya Potter Date: Tue, 7 May 2024 14:45:38 +0300 Subject: [PATCH 1/3] CAE-193: add "IGNORE" options to time series commands (for v4 branch) --- packages/time-series/lib/commands/ADD.spec.ts | 32 +++++++++++++++-- packages/time-series/lib/commands/ADD.ts | 9 +++++ .../time-series/lib/commands/ALTER.spec.ts | 34 +++++++++++++++++-- packages/time-series/lib/commands/ALTER.ts | 6 +++- .../time-series/lib/commands/CREATE.spec.ts | 34 +++++++++++++++++-- packages/time-series/lib/commands/CREATE.ts | 7 +++- packages/time-series/lib/commands/index.ts | 10 ++++++ 7 files changed, 122 insertions(+), 10 deletions(-) diff --git a/packages/time-series/lib/commands/ADD.spec.ts b/packages/time-series/lib/commands/ADD.spec.ts index 94ad30627f8..21a9142c0af 100644 --- a/packages/time-series/lib/commands/ADD.spec.ts +++ b/packages/time-series/lib/commands/ADD.spec.ts @@ -57,6 +57,33 @@ describe('ADD', () => { ); }); + it('with IGNORE no values', () => { + assert.deepEqual( + transformArguments('key', '*', 1, { + IGNORE: { } + }), + ['TS.ADD', 'key', '*', '1', 'IGNORE', '0', '0'] + ) + }); + + it('with IGNORE with MAX_TIME_DIFF', () => { + assert.deepEqual( + transformArguments('key', '*', 1, { + IGNORE: { MAX_TIME_DIFF: 1} + }), + ['TS.ADD', 'key', '*', '1', 'IGNORE', '1', '0'] + ) + }); + + it('with IGNORE with MAX_VAL_DIFF', () => { + assert.deepEqual( + transformArguments('key', '*', 1, { + IGNORE: { MAX_VAL_DIFF: 1} + }), + ['TS.ADD', 'key', '*', '1', 'IGNORE', '0', '1'] + ) + }); + it('with RETENTION, ENCODING, CHUNK_SIZE, ON_DUPLICATE, LABELS', () => { assert.deepEqual( transformArguments('key', '*', 1, { @@ -64,9 +91,10 @@ describe('ADD', () => { ENCODING: TimeSeriesEncoding.UNCOMPRESSED, CHUNK_SIZE: 1, ON_DUPLICATE: TimeSeriesDuplicatePolicies.BLOCK, - LABELS: { label: 'value' } + LABELS: { label: 'value' }, + IGNORE: { MAX_TIME_DIFF: 1, MAX_VAL_DIFF: 1} }), - ['TS.ADD', 'key', '*', '1', 'RETENTION', '1', 'ENCODING', 'UNCOMPRESSED', 'CHUNK_SIZE', '1', 'ON_DUPLICATE', 'BLOCK', 'LABELS', 'label', 'value'] + ['TS.ADD', 'key', '*', '1', 'RETENTION', '1', 'ENCODING', 'UNCOMPRESSED', 'CHUNK_SIZE', '1', 'ON_DUPLICATE', 'BLOCK', 'LABELS', 'label', 'value', 'IGNORE', '1', '1'] ); }); }); diff --git a/packages/time-series/lib/commands/ADD.ts b/packages/time-series/lib/commands/ADD.ts index 1988a964513..f5a3305d3c3 100644 --- a/packages/time-series/lib/commands/ADD.ts +++ b/packages/time-series/lib/commands/ADD.ts @@ -8,14 +8,21 @@ import { Labels, pushLabelsArgument, Timestamp, + pushIgnoreArgument, } from '.'; +export interface TsIgnoreOptions { + MAX_TIME_DIFF?: number; + MAX_VAL_DIFF?: number; +} + interface AddOptions { RETENTION?: number; ENCODING?: TimeSeriesEncoding; CHUNK_SIZE?: number; ON_DUPLICATE?: TimeSeriesDuplicatePolicies; LABELS?: Labels; + IGNORE?: TsIgnoreOptions; } export const FIRST_KEY_INDEX = 1; @@ -40,6 +47,8 @@ export function transformArguments(key: string, timestamp: Timestamp, value: num pushLabelsArgument(args, options?.LABELS); + pushIgnoreArgument(args, options?.IGNORE); + return args; } diff --git a/packages/time-series/lib/commands/ALTER.spec.ts b/packages/time-series/lib/commands/ALTER.spec.ts index cd066533aa4..2de99b0cdd5 100644 --- a/packages/time-series/lib/commands/ALTER.spec.ts +++ b/packages/time-series/lib/commands/ALTER.spec.ts @@ -48,15 +48,43 @@ describe('ALTER', () => { ); }); - it('with RETENTION, CHUNK_SIZE, DUPLICATE_POLICY, LABELS', () => { + it('with IGNORE no values', () => { + assert.deepEqual( + transformArguments('key', { + IGNORE: { } + }), + ['TS.ALTER', 'key', 'IGNORE', '0', '0'] + ) + }); + + it('with IGNORE with MAX_TIME_DIFF', () => { + assert.deepEqual( + transformArguments('key', { + IGNORE: { MAX_TIME_DIFF: 1} + }), + ['TS.ALTER', 'key', 'IGNORE', '1', '0'] + ) + }); + + it('with IGNORE with MAX_VAL_DIFF', () => { + assert.deepEqual( + transformArguments('key', { + IGNORE: { MAX_VAL_DIFF: 1} + }), + ['TS.ALTER', 'key', 'IGNORE', '0', '1'] + ) + }); + + it('with RETENTION, CHUNK_SIZE, DUPLICATE_POLICY, LABELS, IGNORE', () => { assert.deepEqual( transformArguments('key', { RETENTION: 1, CHUNK_SIZE: 1, DUPLICATE_POLICY: TimeSeriesDuplicatePolicies.BLOCK, - LABELS: { label: 'value' } + LABELS: { label: 'value' }, + IGNORE: { MAX_TIME_DIFF: 1, MAX_VAL_DIFF: 1} }), - ['TS.ALTER', 'key', 'RETENTION', '1', 'CHUNK_SIZE', '1', 'DUPLICATE_POLICY', 'BLOCK', 'LABELS', 'label', 'value'] + ['TS.ALTER', 'key', 'RETENTION', '1', 'CHUNK_SIZE', '1', 'DUPLICATE_POLICY', 'BLOCK', 'LABELS', 'label', 'value', 'IGNORE', '1', '1'] ); }); }); diff --git a/packages/time-series/lib/commands/ALTER.ts b/packages/time-series/lib/commands/ALTER.ts index 7b9e1e774c6..576153a0cca 100644 --- a/packages/time-series/lib/commands/ALTER.ts +++ b/packages/time-series/lib/commands/ALTER.ts @@ -1,4 +1,5 @@ -import { pushRetentionArgument, Labels, pushLabelsArgument, TimeSeriesDuplicatePolicies, pushChunkSizeArgument, pushDuplicatePolicy } from '.'; +import { pushRetentionArgument, Labels, pushLabelsArgument, TimeSeriesDuplicatePolicies, pushChunkSizeArgument, pushDuplicatePolicy, pushIgnoreArgument } from '.'; +import { TsIgnoreOptions } from './ADD'; export const FIRST_KEY_INDEX = 1; @@ -7,6 +8,7 @@ interface AlterOptions { CHUNK_SIZE?: number; DUPLICATE_POLICY?: TimeSeriesDuplicatePolicies; LABELS?: Labels; + IGNORE?: TsIgnoreOptions; } export function transformArguments(key: string, options?: AlterOptions): Array { @@ -20,6 +22,8 @@ export function transformArguments(key: string, options?: AlterOptions): Array { ); }); - it('with RETENTION, ENCODING, CHUNK_SIZE, DUPLICATE_POLICY, LABELS', () => { + it('with IGNORE no values', () => { + assert.deepEqual( + transformArguments('key', { + IGNORE: { } + }), + ['TS.CREATE', 'key', 'IGNORE', '0', '0'] + ) + }); + + it('with IGNORE with MAX_TIME_DIFF', () => { + assert.deepEqual( + transformArguments('key', { + IGNORE: { MAX_TIME_DIFF: 1} + }), + ['TS.CREATE', 'IGNORE', '1', '0'] + ) + }); + + it('with IGNORE with MAX_VAL_DIFF', () => { + assert.deepEqual( + transformArguments('key', { + IGNORE: { MAX_VAL_DIFF: 1} + }), + ['TS.CREATE', 'IGNORE', '0', '1'] + ) + }); + + it('with RETENTION, ENCODING, CHUNK_SIZE, DUPLICATE_POLICY, LABELS, IGNORE', () => { assert.deepEqual( transformArguments('key', { RETENTION: 1, ENCODING: TimeSeriesEncoding.UNCOMPRESSED, CHUNK_SIZE: 1, DUPLICATE_POLICY: TimeSeriesDuplicatePolicies.BLOCK, - LABELS: { label: 'value' } + LABELS: { label: 'value' }, + IGNORE: { MAX_TIME_DIFF: 1, MAX_VAL_DIFF: 1} }), - ['TS.CREATE', 'key', 'RETENTION', '1', 'ENCODING', 'UNCOMPRESSED', 'CHUNK_SIZE', '1', 'DUPLICATE_POLICY', 'BLOCK', 'LABELS', 'label', 'value'] + ['TS.CREATE', 'key', 'RETENTION', '1', 'ENCODING', 'UNCOMPRESSED', 'CHUNK_SIZE', '1', 'DUPLICATE_POLICY', 'BLOCK', 'LABELS', 'label', 'value', 'IGNORE', '1', '1'] ); }); }); diff --git a/packages/time-series/lib/commands/CREATE.ts b/packages/time-series/lib/commands/CREATE.ts index a360950feff..a84d4b5f9fb 100644 --- a/packages/time-series/lib/commands/CREATE.ts +++ b/packages/time-series/lib/commands/CREATE.ts @@ -6,8 +6,10 @@ import { TimeSeriesDuplicatePolicies, Labels, pushLabelsArgument, - pushDuplicatePolicy + pushDuplicatePolicy, + pushIgnoreArgument } from '.'; +import { TsIgnoreOptions } from './ADD'; export const FIRST_KEY_INDEX = 1; @@ -17,6 +19,7 @@ interface CreateOptions { CHUNK_SIZE?: number; DUPLICATE_POLICY?: TimeSeriesDuplicatePolicies; LABELS?: Labels; + IGNORE?: TsIgnoreOptions; } export function transformArguments(key: string, options?: CreateOptions): Array { @@ -32,6 +35,8 @@ export function transformArguments(key: string, options?: CreateOptions): Array< pushLabelsArgument(args, options?.LABELS); + pushIgnoreArgument(args, options?.IGNORE); + return args; } diff --git a/packages/time-series/lib/commands/index.ts b/packages/time-series/lib/commands/index.ts index 356b0416648..d10bc840a21 100644 --- a/packages/time-series/lib/commands/index.ts +++ b/packages/time-series/lib/commands/index.ts @@ -127,6 +127,16 @@ export function transformTimestampArgument(timestamp: Timestamp): string { ).toString(); } +export function pushIgnoreArgument(args: RedisCommandArguments, ignore?: ADD.TsIgnoreOptions) { + if (ignore !== undefined) { + args.push( + 'IGNORE', + ignore.MAX_TIME_DIFF ? ignore.MAX_TIME_DIFF.toString() : '0', + ignore.MAX_VAL_DIFF ? ignore.MAX_VAL_DIFF.toString() : '0' + ) + } +} + export function pushRetentionArgument(args: RedisCommandArguments, retention?: number): RedisCommandArguments { if (retention !== undefined) { args.push( From c4935085a67e744bcab01bbf5bbcdb548d0f0919 Mon Sep 17 00:00:00 2001 From: Shaya Potter Date: Wed, 10 Jul 2024 14:07:27 +0300 Subject: [PATCH 2/3] remove optional fields, require them now and fix tests --- packages/time-series/lib/commands/ADD.spec.ts | 28 +++------------- packages/time-series/lib/commands/ADD.ts | 4 +-- .../time-series/lib/commands/ALTER.spec.ts | 30 ++++------------- .../time-series/lib/commands/CREATE.spec.ts | 32 ++++--------------- packages/time-series/lib/commands/index.ts | 6 +--- packages/time-series/lib/test-utils.ts | 5 +-- 6 files changed, 24 insertions(+), 81 deletions(-) diff --git a/packages/time-series/lib/commands/ADD.spec.ts b/packages/time-series/lib/commands/ADD.spec.ts index 21a9142c0af..07e67c1adec 100644 --- a/packages/time-series/lib/commands/ADD.spec.ts +++ b/packages/time-series/lib/commands/ADD.spec.ts @@ -57,34 +57,16 @@ describe('ADD', () => { ); }); - it('with IGNORE no values', () => { + it('with IGNORE', () => { assert.deepEqual( transformArguments('key', '*', 1, { - IGNORE: { } + IGNORE: { MAX_TIME_DIFF: 1, MAX_VAL_DIFF: 1} }), - ['TS.ADD', 'key', '*', '1', 'IGNORE', '0', '0'] + ['TS.ADD', 'key', '*', '1', 'IGNORE', '1', '1'] ) }); - - it('with IGNORE with MAX_TIME_DIFF', () => { - assert.deepEqual( - transformArguments('key', '*', 1, { - IGNORE: { MAX_TIME_DIFF: 1} - }), - ['TS.ADD', 'key', '*', '1', 'IGNORE', '1', '0'] - ) - }); - - it('with IGNORE with MAX_VAL_DIFF', () => { - assert.deepEqual( - transformArguments('key', '*', 1, { - IGNORE: { MAX_VAL_DIFF: 1} - }), - ['TS.ADD', 'key', '*', '1', 'IGNORE', '0', '1'] - ) - }); - - it('with RETENTION, ENCODING, CHUNK_SIZE, ON_DUPLICATE, LABELS', () => { + + it('with RETENTION, ENCODING, CHUNK_SIZE, ON_DUPLICATE, LABELS, IGNORE', () => { assert.deepEqual( transformArguments('key', '*', 1, { RETENTION: 1, diff --git a/packages/time-series/lib/commands/ADD.ts b/packages/time-series/lib/commands/ADD.ts index f5a3305d3c3..3ed185b9b75 100644 --- a/packages/time-series/lib/commands/ADD.ts +++ b/packages/time-series/lib/commands/ADD.ts @@ -12,8 +12,8 @@ import { } from '.'; export interface TsIgnoreOptions { - MAX_TIME_DIFF?: number; - MAX_VAL_DIFF?: number; + MAX_TIME_DIFF: number; + MAX_VAL_DIFF: number; } interface AddOptions { diff --git a/packages/time-series/lib/commands/ALTER.spec.ts b/packages/time-series/lib/commands/ALTER.spec.ts index 2de99b0cdd5..7add3eeec3a 100644 --- a/packages/time-series/lib/commands/ALTER.spec.ts +++ b/packages/time-series/lib/commands/ALTER.spec.ts @@ -48,32 +48,14 @@ describe('ALTER', () => { ); }); - it('with IGNORE no values', () => { + it('with IGNORE with MAX_TIME_DIFF', () => { assert.deepEqual( - transformArguments('key', { - IGNORE: { } - }), - ['TS.ALTER', 'key', 'IGNORE', '0', '0'] - ) - }); - - it('with IGNORE with MAX_TIME_DIFF', () => { - assert.deepEqual( - transformArguments('key', { - IGNORE: { MAX_TIME_DIFF: 1} - }), - ['TS.ALTER', 'key', 'IGNORE', '1', '0'] - ) - }); - - it('with IGNORE with MAX_VAL_DIFF', () => { - assert.deepEqual( - transformArguments('key', { - IGNORE: { MAX_VAL_DIFF: 1} - }), - ['TS.ALTER', 'key', 'IGNORE', '0', '1'] + transformArguments('key', { + IGNORE: { MAX_TIME_DIFF: 1, MAX_VAL_DIFF: 1} + }), + ['TS.ALTER', 'key', 'IGNORE', '1', '1'] ) - }); + }); it('with RETENTION, CHUNK_SIZE, DUPLICATE_POLICY, LABELS, IGNORE', () => { assert.deepEqual( diff --git a/packages/time-series/lib/commands/CREATE.spec.ts b/packages/time-series/lib/commands/CREATE.spec.ts index 95313e487af..ca711c823e2 100644 --- a/packages/time-series/lib/commands/CREATE.spec.ts +++ b/packages/time-series/lib/commands/CREATE.spec.ts @@ -56,33 +56,15 @@ describe('CREATE', () => { ['TS.CREATE', 'key', 'LABELS', 'label', 'value'] ); }); - - it('with IGNORE no values', () => { - assert.deepEqual( - transformArguments('key', { - IGNORE: { } - }), - ['TS.CREATE', 'key', 'IGNORE', '0', '0'] - ) - }); - + it('with IGNORE with MAX_TIME_DIFF', () => { - assert.deepEqual( - transformArguments('key', { - IGNORE: { MAX_TIME_DIFF: 1} - }), - ['TS.CREATE', 'IGNORE', '1', '0'] - ) + assert.deepEqual( + transformArguments('key', { + IGNORE: { MAX_TIME_DIFF: 1, MAX_VAL_DIFF: 1} + }), + ['TS.CREATE', 'IGNORE', '1', '1'] + ) }); - - it('with IGNORE with MAX_VAL_DIFF', () => { - assert.deepEqual( - transformArguments('key', { - IGNORE: { MAX_VAL_DIFF: 1} - }), - ['TS.CREATE', 'IGNORE', '0', '1'] - ) - }); it('with RETENTION, ENCODING, CHUNK_SIZE, DUPLICATE_POLICY, LABELS, IGNORE', () => { assert.deepEqual( diff --git a/packages/time-series/lib/commands/index.ts b/packages/time-series/lib/commands/index.ts index d10bc840a21..ca382498060 100644 --- a/packages/time-series/lib/commands/index.ts +++ b/packages/time-series/lib/commands/index.ts @@ -129,11 +129,7 @@ export function transformTimestampArgument(timestamp: Timestamp): string { export function pushIgnoreArgument(args: RedisCommandArguments, ignore?: ADD.TsIgnoreOptions) { if (ignore !== undefined) { - args.push( - 'IGNORE', - ignore.MAX_TIME_DIFF ? ignore.MAX_TIME_DIFF.toString() : '0', - ignore.MAX_VAL_DIFF ? ignore.MAX_VAL_DIFF.toString() : '0' - ) + args.push('IGNORE', ignore.MAX_TIME_DIFF.toString(), ignore.MAX_VAL_DIFF.toString()); } } diff --git a/packages/time-series/lib/test-utils.ts b/packages/time-series/lib/test-utils.ts index 6d534ccccef..2ad8af900fb 100644 --- a/packages/time-series/lib/test-utils.ts +++ b/packages/time-series/lib/test-utils.ts @@ -2,8 +2,9 @@ import TestUtils from '@redis/test-utils'; import TimeSeries from '.'; export default new TestUtils({ - dockerImageName: 'redislabs/redistimeseries', - dockerImageVersionArgument: 'timeseries-version' + dockerImageName: 'redis/redis-stack-server', + dockerImageVersionArgument: 'timeseries-version', + defaultDockerVersion: '7.4.0-rc2' }); export const GLOBAL = { From 28ed44a4a3356940d3d2667941fab494d3970ff1 Mon Sep 17 00:00:00 2001 From: Shaya Potter Date: Wed, 10 Jul 2024 14:31:51 +0300 Subject: [PATCH 3/3] wip --- packages/time-series/lib/commands/CREATE.spec.ts | 2 +- packages/time-series/lib/test-utils.ts | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/time-series/lib/commands/CREATE.spec.ts b/packages/time-series/lib/commands/CREATE.spec.ts index ca711c823e2..eb7a1c6a637 100644 --- a/packages/time-series/lib/commands/CREATE.spec.ts +++ b/packages/time-series/lib/commands/CREATE.spec.ts @@ -62,7 +62,7 @@ describe('CREATE', () => { transformArguments('key', { IGNORE: { MAX_TIME_DIFF: 1, MAX_VAL_DIFF: 1} }), - ['TS.CREATE', 'IGNORE', '1', '1'] + ['TS.CREATE', 'key', 'IGNORE', '1', '1'] ) }); diff --git a/packages/time-series/lib/test-utils.ts b/packages/time-series/lib/test-utils.ts index 2ad8af900fb..6d534ccccef 100644 --- a/packages/time-series/lib/test-utils.ts +++ b/packages/time-series/lib/test-utils.ts @@ -2,9 +2,8 @@ import TestUtils from '@redis/test-utils'; import TimeSeries from '.'; export default new TestUtils({ - dockerImageName: 'redis/redis-stack-server', - dockerImageVersionArgument: 'timeseries-version', - defaultDockerVersion: '7.4.0-rc2' + dockerImageName: 'redislabs/redistimeseries', + dockerImageVersionArgument: 'timeseries-version' }); export const GLOBAL = {