Skip to content

Commit

Permalink
Node: Add binary variant to sorted set commands - part 1. (valkey-io#…
Browse files Browse the repository at this point in the history
…2190)

* Add binary variant to sorted set commands - part 1.

Signed-off-by: Yury-Fridlyand <[email protected]>
  • Loading branch information
Yury-Fridlyand authored Aug 28, 2024
1 parent 015d5a9 commit 9565313
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 153 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#### Changes
* Node: Added binary variant to sorted set commands - part 1 ([#2190](https://github.com/valkey-io/valkey-glide/pull/2190))
* Node: Added binary variant to HASH commands ([#2194](https://github.com/valkey-io/valkey-glide/pull/2194))
* Node: Added binary variant to server management commands ([#2179](https://github.com/valkey-io/valkey-glide/pull/2179))
* Node: Added/updated binary variant to connection management commands and WATCH/UNWATCH ([#2160](https://github.com/valkey-io/valkey-glide/pull/2160))
Expand Down
141 changes: 89 additions & 52 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3337,7 +3337,7 @@ export class BaseClient {
* @see {@link https://valkey.io/commands/ttl/|valkey.io} for details.
*
* @param key - The key to return its timeout.
* @returns TTL in seconds, -2 if `key` does not exist or -1 if `key` exists but has no associated expire.
* @returns TTL in seconds, `-2` if `key` does not exist or `-1` if `key` exists but has no associated expire.
*
* @example
* ```typescript
Expand Down Expand Up @@ -3495,16 +3495,17 @@ export class BaseClient {
return this.createWritePromise(createXRevRange(key, end, start, count));
}

/** Adds members with their scores to the sorted set stored at `key`.
/**
* Adds members with their scores to the sorted set stored at `key`.
* If a member is already a part of the sorted set, its score is updated.
*
* @see {@link https://valkey.io/commands/zadd/|valkey.io} for more details.
*
* @param key - The key of the sorted set.
* @param membersScoresMap - A mapping of members to their corresponding scores.
* @param options - The ZAdd options.
* @param options - (Optional) The ZAdd options - see {@link ZAddOptions}.
* @returns The number of elements added to the sorted set.
* If `changed` is set, returns the number of elements updated in the sorted set.
* If {@link ZAddOptions.changed|changed} is set, returns the number of elements updated in the sorted set.
*
* @example
* ```typescript
Expand All @@ -3531,7 +3532,8 @@ export class BaseClient {
);
}

/** Increments the score of member in the sorted set stored at `key` by `increment`.
/**
* Increments the score of member in the sorted set stored at `key` by `increment`.
* If `member` does not exist in the sorted set, it is added with `increment` as its score (as if its previous score was 0.0).
* If `key` does not exist, a new sorted set with the specified member as its sole member is created.
*
Expand All @@ -3540,7 +3542,7 @@ export class BaseClient {
* @param key - The key of the sorted set.
* @param member - A member in the sorted set to increment.
* @param increment - The score to increment the member.
* @param options - The ZAdd options.
* @param options - (Optional) The ZAdd options - see {@link ZAddOptions}.
* @returns The score of the member.
* If there was a conflict with the options, the operation aborts and null is returned.
*
Expand Down Expand Up @@ -3597,13 +3599,14 @@ export class BaseClient {
return this.createWritePromise(createZRem(key, members));
}

/** Returns the cardinality (number of elements) of the sorted set stored at `key`.
/**
* Returns the cardinality (number of elements) of the sorted set stored at `key`.
*
* @see {@link https://valkey.io/commands/zcard/|valkey.io} for more details.
*
* @param key - The key of the sorted set.
* @returns The number of elements in the sorted set.
* If `key` does not exist, it is treated as an empty sorted set, and this command returns 0.
* If `key` does not exist, it is treated as an empty sorted set, and this command returns `0`.
*
* @example
* ```typescript
Expand All @@ -3619,7 +3622,7 @@ export class BaseClient {
* console.log(result); // Output: 0
* ```
*/
public async zcard(key: string): Promise<number> {
public async zcard(key: GlideString): Promise<number> {
return this.createWritePromise(createZCard(key));
}

Expand All @@ -3641,7 +3644,10 @@ export class BaseClient {
* console.log(cardinality); // Output: 3 - The intersection of the sorted sets at "key1" and "key2" has a cardinality of 3.
* ```
*/
public async zintercard(keys: string[], limit?: number): Promise<number> {
public async zintercard(
keys: GlideString[],
limit?: number,
): Promise<number> {
return this.createWritePromise(createZInterCard(keys, limit));
}

Expand All @@ -3654,6 +3660,7 @@ export class BaseClient {
* @remarks Since Valkey version 6.2.0.
*
* @param keys - The keys of the sorted sets.
* @param options - (Optional) See {@link DecoderOption}.
* @returns An `array` of elements representing the difference between the sorted sets.
* If the first key does not exist, it is treated as an empty sorted set, and the command returns an empty `array`.
*
Expand All @@ -3666,8 +3673,11 @@ export class BaseClient {
* console.log(result); // Output: ["member1"] - "member1" is in "zset1" but not "zset2" or "zset3".
* ```
*/
public async zdiff(keys: string[]): Promise<string[]> {
return this.createWritePromise(createZDiff(keys));
public async zdiff(
keys: GlideString[],
options?: DecoderOption,
): Promise<GlideString[]> {
return this.createWritePromise(createZDiff(keys), options);
}

/**
Expand All @@ -3679,6 +3689,7 @@ export class BaseClient {
* @remarks Since Valkey version 6.2.0.
*
* @param keys - The keys of the sorted sets.
* @param options - (Optional) See {@link DecoderOption}.
* @returns A map of elements and their scores representing the difference between the sorted sets.
* If the first key does not exist, it is treated as an empty sorted set, and the command returns an empty `array`.
*
Expand All @@ -3692,9 +3703,11 @@ export class BaseClient {
* ```
*/
public async zdiffWithScores(
keys: string[],
keys: GlideString[],
options?: DecoderOption,
): Promise<Record<string, number>> {
return this.createWritePromise(createZDiffWithScores(keys));
// TODO GlideString in Record and add a test
return this.createWritePromise(createZDiffWithScores(keys), options);
}

/**
Expand Down Expand Up @@ -3722,8 +3735,8 @@ export class BaseClient {
* ```
*/
public async zdiffstore(
destination: string,
keys: string[],
destination: GlideString,
keys: GlideString[],
): Promise<number> {
return this.createWritePromise(createZDiffStore(destination, keys));
}
Expand Down Expand Up @@ -3823,16 +3836,17 @@ export class BaseClient {
return this.createWritePromise(createZMScore(key, members));
}

/** Returns the number of members in the sorted set stored at `key` with scores between `minScore` and `maxScore`.
/**
* Returns the number of members in the sorted set stored at `key` with scores between `minScore` and `maxScore`.
*
* @see {@link https://valkey.io/commands/zcount/|valkey.io} for more details.
*
* @param key - The key of the sorted set.
* @param minScore - The minimum score to count from. Can be positive/negative infinity, or specific score and inclusivity.
* @param maxScore - The maximum score to count up to. Can be positive/negative infinity, or specific score and inclusivity.
* @returns The number of members in the specified score range.
* If `key` does not exist, it is treated as an empty sorted set, and the command returns 0.
* If `minScore` is greater than `maxScore`, 0 is returned.
* If `key` does not exist, it is treated as an empty sorted set, and the command returns `0`.
* If `minScore` is greater than `maxScore`, `0` is returned.
*
* @example
* ```typescript
Expand All @@ -3849,7 +3863,7 @@ export class BaseClient {
* ```
*/
public async zcount(
key: string,
key: GlideString,
minScore: Boundary<number>,
maxScore: Boundary<number>,
): Promise<number> {
Expand Down Expand Up @@ -3998,26 +4012,33 @@ export class BaseClient {
*
* @param destination - The key of the destination sorted set.
* @param keys - The keys of the sorted sets with possible formats:
* string[] - for keys only.
* KeyWeight[] - for weighted keys with score multipliers.
* - `GlideString[]` - for keys only.
* - `KeyWeight[]` - for weighted keys with score multipliers.
* @param aggregationType - (Optional) Specifies the aggregation strategy to apply when combining the scores of elements. See {@link AggregationType}.
* If `aggregationType` is not specified, defaults to `AggregationType.SUM`.
* @returns The number of elements in the resulting sorted set stored at `destination`.
*
* @example
* ```typescript
* // Example usage of zinterstore command with an existing key
* await client.zadd("key1", {"member1": 10.5, "member2": 8.2})
* await client.zadd("key2", {"member1": 9.5})
* await client.zinterstore("my_sorted_set", ["key1", "key2"]) // Output: 1 - Indicates that the sorted set "my_sorted_set" contains one element.
* await client.zrangeWithScores("my_sorted_set", RangeByIndex(0, -1)) // Output: {'member1': 20} - "member1" is now stored in "my_sorted_set" with score of 20.
* await client.zinterstore("my_sorted_set", ["key1", "key2"] , AggregationType.MAX ) // Output: 1 - Indicates that the sorted set "my_sorted_set" contains one element, and it's score is the maximum score between the sets.
* await client.zrangeWithScores("my_sorted_set", RangeByIndex(0, -1)) // Output: {'member1': 10.5} - "member1" is now stored in "my_sorted_set" with score of 10.5.
*
* // use `zinterstore` with default aggregation and weights
* console.log(await client.zinterstore("my_sorted_set", ["key1", "key2"]))
* // Output: 1 - Indicates that the sorted set "my_sorted_set" contains one element.
* console.log(await client.zrangeWithScores("my_sorted_set", {start: 0, stop: -1}))
* // Output: {'member1': 20} - "member1" is now stored in "my_sorted_set" with score of 20.
*
* // use `zinterstore` with default weights
* console.log(await client.zinterstore("my_sorted_set", ["key1", "key2"] , AggregationType.MAX))
* // Output: 1 - Indicates that the sorted set "my_sorted_set" contains one element, and it's score is the maximum score between the sets.
* console.log(await client.zrangeWithScores("my_sorted_set", {start: 0, stop: -1}))
* // Output: {'member1': 10.5} - "member1" is now stored in "my_sorted_set" with score of 10.5.
* ```
*/
public async zinterstore(
destination: string,
keys: string[] | KeyWeight[],
destination: GlideString,
keys: GlideString[] | KeyWeight[],
aggregationType?: AggregationType,
): Promise<number> {
return this.createWritePromise(
Expand All @@ -4037,6 +4058,7 @@ export class BaseClient {
* @see {@link https://valkey.io/commands/zinter/|valkey.io} for details.
*
* @param keys - The keys of the sorted sets.
* @param options - (Optional) See {@link DecoderOption}.
* @returns The resulting array of intersecting elements.
*
* @example
Expand All @@ -4047,8 +4069,11 @@ export class BaseClient {
* console.log(result); // Output: ['member1']
* ```
*/
public async zinter(keys: string[]): Promise<string[]> {
return this.createWritePromise(createZInter(keys));
public async zinter(
keys: GlideString[],
options?: DecoderOption,
): Promise<GlideString[]> {
return this.createWritePromise(createZInter(keys), options);
}

/**
Expand All @@ -4063,10 +4088,12 @@ export class BaseClient {
* @remarks Since Valkey version 6.2.0.
*
* @param keys - The keys of the sorted sets with possible formats:
* - string[] - for keys only.
* - KeyWeight[] - for weighted keys with score multipliers.
* @param aggregationType - (Optional) Specifies the aggregation strategy to apply when combining the scores of elements. See {@link AggregationType}.
* If `aggregationType` is not specified, defaults to `AggregationType.SUM`.
* - `GlideString[]` - for keys only.
* - `KeyWeight[]` - for weighted keys with score multipliers.
* @param options - (Optional) Additional parameters:
* - (Optional) `aggregationType`: the aggregation strategy to apply when combining the scores of elements.
* If `aggregationType` is not specified, defaults to `AggregationType.SUM`. See {@link AggregationType}.
* - (Optional) `decoder`: see {@link DecoderOption}.
* @returns The resulting sorted set with scores.
*
* @example
Expand All @@ -4080,11 +4107,13 @@ export class BaseClient {
* ```
*/
public async zinterWithScores(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
keys: GlideString[] | KeyWeight[],
options?: { aggregationType?: AggregationType } & DecoderOption,
): Promise<Record<string, number>> {
// TODO Record with GlideString and add tests
return this.createWritePromise(
createZInter(keys, aggregationType, true),
createZInter(keys, options?.aggregationType, true),
options,
);
}

Expand Down Expand Up @@ -4341,6 +4370,7 @@ export class BaseClient {
* @param keys - The keys of the sorted sets.
* @param timeout - The number of seconds to wait for a blocking operation to complete. A value of
* `0` will block indefinitely. Since 6.0.0: timeout is interpreted as a double instead of an integer.
* @param options - (Optional) See {@link DecoderOption}.
* @returns An `array` containing the key where the member was popped out, the member, itself, and the member score.
* If no member could be popped and the `timeout` expired, returns `null`.
*
Expand All @@ -4351,10 +4381,11 @@ export class BaseClient {
* ```
*/
public async bzpopmin(
keys: string[],
keys: GlideString[],
timeout: number,
): Promise<[string, string, number] | null> {
return this.createWritePromise(createBZPopMin(keys, timeout));
options?: DecoderOption,
): Promise<[GlideString, GlideString, number] | null> {
return this.createWritePromise(createBZPopMin(keys, timeout), options);
}

/** Removes and returns the members with the highest scores from the sorted set stored at `key`.
Expand Down Expand Up @@ -4402,6 +4433,7 @@ export class BaseClient {
* @param keys - The keys of the sorted sets.
* @param timeout - The number of seconds to wait for a blocking operation to complete. A value of
* `0` will block indefinitely. Since 6.0.0: timeout is interpreted as a double instead of an integer.
* @param options - (Optional) See {@link DecoderOption}.
* @returns An `array` containing the key where the member was popped out, the member, itself, and the member score.
* If no member could be popped and the `timeout` expired, returns `null`.
*
Expand All @@ -4412,10 +4444,11 @@ export class BaseClient {
* ```
*/
public async bzpopmax(
keys: string[],
keys: GlideString[],
timeout: number,
): Promise<[string, string, number] | null> {
return this.createWritePromise(createBZPopMax(keys, timeout));
options?: DecoderOption,
): Promise<[GlideString, GlideString, number] | null> {
return this.createWritePromise(createBZPopMax(keys, timeout), options);
}

/**
Expand All @@ -4424,7 +4457,7 @@ export class BaseClient {
* @see {@link https://valkey.io/commands/pttl/|valkey.io} for more details.
*
* @param key - The key to return its timeout.
* @returns TTL in milliseconds. -2 if `key` does not exist, -1 if `key` exists but has no associated expire.
* @returns TTL in milliseconds, `-2` if `key` does not exist, `-1` if `key` exists but has no associated expire.
*
* @example
* ```typescript
Expand Down Expand Up @@ -6163,7 +6196,9 @@ export class BaseClient {
* {@link ScoreFilter.MAX} to pop the member with the lowest/highest score accordingly.
* @param timeout - The number of seconds to wait for a blocking operation to complete.
* A value of 0 will block indefinitely.
* @param count - (Optional) The number of elements to pop. If not supplied, only one element will be popped.
* @param options - (Optional) Additional parameters:
* - (Optional) `count`: the number of elements to pop. If not supplied, only one element will be popped.
* - (Optional) `decoder`: see {@link DecoderOption}.
* @returns A two-element `array` containing the key name of the set from which the element
* was popped, and a member-score `Record` of the popped element.
* If no member could be popped, returns `null`.
Expand All @@ -6177,13 +6212,15 @@ export class BaseClient {
* ```
*/
public async bzmpop(
keys: string[],
keys: GlideString[],
modifier: ScoreFilter,
timeout: number,
count?: number,
): Promise<[string, [Record<string, number>]] | null> {
options?: { count?: number } & DecoderOption,
): Promise<[string, Record<string, number>] | null> {
// TODO GlideString in Record
return this.createWritePromise(
createBZMPop(keys, modifier, timeout, count),
createBZMPop(keys, modifier, timeout, options?.count),
options,
);
}

Expand Down Expand Up @@ -6213,9 +6250,9 @@ export class BaseClient {
* ```
*/
public async zincrby(
key: string,
key: GlideString,
increment: number,
member: string,
member: GlideString,
): Promise<number> {
return this.createWritePromise(createZIncrBy(key, increment, member));
}
Expand Down
Loading

0 comments on commit 9565313

Please sign in to comment.