Skip to content

Commit

Permalink
Node: Add ZLEXCOUNT command (valkey-io#2022)
Browse files Browse the repository at this point in the history
* Node: Add ZLEXCOUNT

Signed-off-by: Andrew Carbonetto <andrew.carbonetto@improving.com>

---------

Signed-off-by: Andrew Carbonetto <andrew.carbonetto@improving.com>
  • Loading branch information
acarbonetto authored Jul 31, 2024
1 parent 74ef177 commit d785b95
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 47 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* Node: Added ZINCRBY command ([#2009](https://github.com/valkey-io/valkey-glide/pull/2009))
* Node: Added BZMPOP command ([#2018](https://github.com/valkey-io/valkey-glide/pull/2018))
* Node: Added PFMERGE command ([#2053](https://github.com/valkey-io/valkey-glide/pull/2053))
* Node: Added ZLEXCOUNT command ([#2022](https://github.com/valkey-io/valkey-glide/pull/2022))

#### Breaking Changes
* Node: (Refactor) Convert classes to types ([#2005](https://github.com/valkey-io/valkey-glide/pull/2005))
Expand Down
6 changes: 4 additions & 2 deletions node/npm/glide/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ function initialize() {
InsertPosition,
SetOptions,
ZaddOptions,
ScoreBoundry,
InfScoreBoundary,
ScoreBoundary,
UpdateOptions,
ProtocolVersion,
RangeByIndex,
Expand Down Expand Up @@ -204,7 +205,8 @@ function initialize() {
InsertPosition,
SetOptions,
ZaddOptions,
ScoreBoundry,
InfScoreBoundary,
ScoreBoundary,
UpdateOptions,
ProtocolVersion,
RangeByIndex,
Expand Down
41 changes: 37 additions & 4 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ import {
createZIncrBy,
createZInterCard,
createZInterstore,
createZLexCount,
createZMPop,
createZMScore,
createZPopMax,
Expand Down Expand Up @@ -2855,7 +2856,7 @@ export class BaseClient {
* @example
* ```typescript
* // Example usage of the zcount method to count members in a sorted set within a score range
* const result = await client.zcount("my_sorted_set", { bound: 5.0, isInclusive: true }, "positiveInfinity");
* const result = await client.zcount("my_sorted_set", { bound: 5.0, isInclusive: true }, InfScoreBoundary.PositiveInfinity);
* console.log(result); // Output: 2 - Indicates that there are 2 members with scores between 5.0 (inclusive) and +inf in the sorted set "my_sorted_set".
* ```
*
Expand Down Expand Up @@ -2899,7 +2900,7 @@ export class BaseClient {
* ```typescript
* // Example usage of zrange method to retrieve members within a score range in ascending order
* const result = await client.zrange("my_sorted_set", {
* start: "negativeInfinity",
* start: InfScoreBoundary.NegativeInfinity,
* stop: { value: 3, isInclusive: false },
* type: "byScore",
* });
Expand Down Expand Up @@ -2941,7 +2942,7 @@ export class BaseClient {
* ```typescript
* // Example usage of zrangeWithScores method to retrieve members within a score range with their scores
* const result = await client.zrangeWithScores("my_sorted_set", {
* start: "negativeInfinity",
* start: InfScoreBoundary.NegativeInfinity,
* stop: { value: 3, isInclusive: false },
* type: "byScore",
* });
Expand Down Expand Up @@ -3271,7 +3272,7 @@ export class BaseClient {
* @example
* ```typescript
* // Example usage of zremRangeByScore method to remove members from a sorted set based on score range
* const result = await client.zremRangeByScore("my_sorted_set", { bound: 5.0, isInclusive: true }, "positiveInfinity");
* const result = await client.zremRangeByScore("my_sorted_set", { bound: 5.0, isInclusive: true }, InfScoreBoundary.PositiveInfinity);
* console.log(result); // Output: 2 - Indicates that 2 members with scores between 5.0 (inclusive) and +inf have been removed from the sorted set "my_sorted_set".
* ```
*
Expand All @@ -3292,6 +3293,38 @@ export class BaseClient {
);
}

/**
* Returns the number of members in the sorted set stored at 'key' with scores between 'minLex' and 'maxLex'.
*
* See https://valkey.io/commands/zlexcount/ for more details.
*
* @param key - The key of the sorted set.
* @param minLex - The minimum lex to count from. Can be positive/negative infinity, or a specific lex and inclusivity.
* @param maxLex - The maximum lex to count up to. Can be positive/negative infinity, or a specific lex and inclusivity.
* @returns The number of members in the specified lex range.
* If 'key' does not exist, it is treated as an empty sorted set, and the command returns '0'.
* If maxLex is less than minLex, '0' is returned.
*
* @example
* ```typescript
* const result = await client.zlexcount("my_sorted_set", {value: "c"}, InfScoreBoundary.PositiveInfinity);
* console.log(result); // Output: 2 - Indicates that there are 2 members with lex scores between "c" (inclusive) and positive infinity in the sorted set "my_sorted_set".
* ```
*
* @example
* ```typescript
* const result = await client.zlexcount("my_sorted_set", {value: "c"}, {value: "k", isInclusive: false});
* console.log(result); // Output: 1 - Indicates that there is one member with a lex score between "c" (inclusive) and "k" (exclusive) in the sorted set "my_sorted_set".
* ```
*/
public async zlexcount(
key: string,
minLex: ScoreBoundary<string>,
maxLex: ScoreBoundary<string>,
): Promise<number> {
return this.createWritePromise(createZLexCount(key, minLex, maxLex));
}

/** Returns the rank of `member` in the sorted set stored at `key`, with scores ordered from low to high.
* See https://valkey.io/commands/zrank for more details.
* To get the rank of `member` with its score, see `zrankWithScore`.
Expand Down
46 changes: 39 additions & 7 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1503,15 +1503,25 @@ export function createZMScore(
return createCommand(RequestType.ZMScore, [key, ...members]);
}

export type ScoreBoundary<T> =
export enum InfScoreBoundary {
/**
* Positive infinity bound for sorted set.
*/
| `positiveInfinity`
PositiveInfinity = "+",
/**
* Negative infinity bound for sorted set.
*/
| `negativeInfinity`
NegativeInfinity = "-",
}

/**
* Defines where to insert new elements into a list.
*/
export type ScoreBoundary<T> =
/**
* Represents an lower/upper boundary in a sorted set.
*/
| InfScoreBoundary
/**
* Represents a specific numeric score boundary in a sorted set.
*/
Expand Down Expand Up @@ -1591,10 +1601,16 @@ function getScoreBoundaryArg(
score: ScoreBoundary<number> | ScoreBoundary<string>,
isLex: boolean = false,
): string {
if (score == "positiveInfinity") {
return isLex ? "+" : "+inf";
} else if (score == "negativeInfinity") {
return isLex ? "-" : "-inf";
if (score == InfScoreBoundary.PositiveInfinity) {
return (
InfScoreBoundary.PositiveInfinity.toString() + (isLex ? "" : "inf")
);
}

if (score == InfScoreBoundary.NegativeInfinity) {
return (
InfScoreBoundary.NegativeInfinity.toString() + (isLex ? "" : "inf")
);
}

if (score.isInclusive == false) {
Expand Down Expand Up @@ -1800,6 +1816,22 @@ export function createPersist(key: string): command_request.Command {
return createCommand(RequestType.Persist, [key]);
}

/**
* @internal
*/
export function createZLexCount(
key: string,
minLex: ScoreBoundary<string>,
maxLex: ScoreBoundary<string>,
): command_request.Command {
const args = [
key,
getScoreBoundaryArg(minLex, true),
getScoreBoundaryArg(maxLex, true),
];
return createCommand(RequestType.ZLexCount, args);
}

export function createZRank(
key: string,
member: string,
Expand Down
22 changes: 22 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ import {
createZIncrBy,
createZInterCard,
createZInterstore,
createZLexCount,
createZMPop,
createZMScore,
createZPopMax,
Expand Down Expand Up @@ -1793,6 +1794,27 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
);
}

/**
* Returns the number of members in the sorted set stored at 'key' with scores between 'minLex' and 'maxLex'.
*
* See https://valkey.io/commands/zlexcount/ for more details.
*
* @param key - The key of the sorted set.
* @param minLex - The minimum lex to count from. Can be positive/negative infinity, or a specific lex and inclusivity.
* @param maxLex - The maximum lex to count up to. Can be positive/negative infinity, or a specific lex and inclusivity.
*
* Command Response - The number of members in the specified lex range.
* If 'key' does not exist, it is treated as an empty sorted set, and the command returns '0'.
* If maxLex is less than minLex, '0' is returned.
*/
public zlexcount(
key: string,
minLex: ScoreBoundary<string>,
maxLex: ScoreBoundary<string>,
): T {
return this.addAndReturn(createZLexCount(key, minLex, maxLex));
}

/** Returns the rank of `member` in the sorted set stored at `key`, with scores ordered from low to high.
* See https://valkey.io/commands/zrank for more details.
* To get the rank of `member` with its score, see `zrankWithScore`.
Expand Down
Loading

0 comments on commit d785b95

Please sign in to comment.