Skip to content

Commit

Permalink
Node: added zpopmax command. (#1009)
Browse files Browse the repository at this point in the history
* Node: added zpopmax command.

* update CHANGELOG.md file
  • Loading branch information
Adan Wattad authored Feb 21, 2024
1 parent fd54e7c commit 38544ea
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 9 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* Python, Node: Added ZPOPMIN command ([#975](https://github.com/aws/glide-for-redis/pull/975), [#1008](https://github.com/aws/glide-for-redis/pull/1008))
* Node: Added STRLEN command ([#993](https://github.com/aws/glide-for-redis/pull/993))
* Node: Added LINDEX command ([#999](https://github.com/aws/glide-for-redis/pull/999))
* Python: Added ZPOPMAX command ([#996](https://github.com/aws/glide-for-redis/pull/996))
* Python, Node: Added ZPOPMAX command ([#996](https://github.com/aws/glide-for-redis/pull/996), [#1009](https://github.com/aws/glide-for-redis/pull/1009))

#### Features
* Python, Node: Added support in Lua Scripts ([#775](https://github.com/aws/glide-for-redis/pull/775), [#860](https://github.com/aws/glide-for-redis/pull/860))
Expand Down
21 changes: 20 additions & 1 deletion node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
createZadd,
createZcard,
createZcount,
createZpopmax,
createZpopmin,
createZrem,
createZscore,
Expand Down Expand Up @@ -1108,9 +1109,9 @@ export class BaseClient {
*
* @param key - The key of the sorted set.
* @param count - Specifies the quantity of members to pop. If not specified, pops one member.
* If `count` is higher than the sorted set's cardinality, returns all members and their scores.
* @returns A map of the removed members and their scores, ordered from the one with the lowest score to the one with the highest.
* If `key` doesn't exist, it will be treated as an empty sorted set and the command returns an empty map.
* If `count` is higher than the sorted set's cardinality, returns all members and their scores.
*/
public zpopmin(
key: string,
Expand All @@ -1119,6 +1120,24 @@ export class BaseClient {
return this.createWritePromise(createZpopmin(key, count));
}

/** Removes and returns the members with the highest scores from the sorted set stored at `key`.
* If `count` is provided, up to `count` members with the highest scores are removed and returned.
* Otherwise, only one member with the highest score is removed and returned.
* See https://redis.io/commands/zpopmax for more details.
*
* @param key - The key of the sorted set.
* @param count - Specifies the quantity of members to pop. If not specified, pops one member.
* @returns A map of the removed members and their scores, ordered from the one with the highest score to the one with the lowest.
* If `key` doesn't exist, it will be treated as an empty sorted set and the command returns an empty map.
* If `count` is higher than the sorted set's cardinality, returns all members and their scores, ordered from highest to lowest.
*/
public zpopmax(
key: string,
count?: number
): Promise<Record<string, number>> {
return this.createWritePromise(createZpopmax(key, count));
}

private readonly MAP_READ_FROM_STRATEGY: Record<
ReadFrom,
connection_request.ReadFrom
Expand Down
8 changes: 8 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,3 +855,11 @@ export function createZpopmin(key: string, count?: number): redis_request.Comman
const args: string[] = count == undefined ? [key] : [key, count.toString()];
return createCommand(RequestType.ZPopMin, args);
}

/**
* @internal
*/
export function createZpopmax(key: string, count?: number): redis_request.Command {
const args: string[] = count == undefined ? [key] : [key, count.toString()];
return createCommand(RequestType.ZPopMax, args);
}
19 changes: 18 additions & 1 deletion node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
createZadd,
createZcard,
createZcount,
createZpopmax,
createZpopmin,
createZrem,
createZscore,
Expand Down Expand Up @@ -874,15 +875,31 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
*
* @param key - The key of the sorted set.
* @param count - Specifies the quantity of members to pop. If not specified, pops one member.
* If `count` is higher than the sorted set's cardinality, returns all members and their scores.
*
* Command Response - A map of the removed members and their scores, ordered from the one with the lowest score to the one with the highest.
* If `key` doesn't exist, it will be treated as an empty sorted set and the command returns an empty map.
* If `count` is higher than the sorted set's cardinality, returns all members and their scores.
*/
public zpopmin(key: string, count?: number): T {
return this.addAndReturn(createZpopmin(key, count));
}

/** Removes and returns the members with the highest scores from the sorted set stored at `key`.
* If `count` is provided, up to `count` members with the highest scores are removed and returned.
* Otherwise, only one member with the highest score is removed and returned.
* See https://redis.io/commands/zpopmax for more details.
*
* @param key - The key of the sorted set.
* @param count - Specifies the quantity of members to pop. If not specified, pops one member.
*
* Command Response - A map of the removed members and their scores, ordered from the one with the highest score to the one with the lowest.
* If `key` doesn't exist, it will be treated as an empty sorted set and the command returns an empty map.
* If `count` is higher than the sorted set's cardinality, returns all members and their scores, ordered from highest to lowest.
*/
public zpopmax(key: string, count?: number): T {
return this.addAndReturn(createZpopmax(key, count));
}

/** Executes a single command, without checking inputs. Every part of the command, including subcommands,
* should be added as a separate value in args.
*
Expand Down
21 changes: 21 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1597,6 +1597,27 @@ export function runBaseTests<Context>(config: {
},
config.timeout
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`zpopmax test_%p`,
async (protocol) => {
await runTest(async (client: BaseClient) => {
const key = uuidv4();
const membersScores = { a: 1, b: 2, c: 3 };
expect(await client.zadd(key, membersScores)).toEqual(3);
expect(await client.zpopmax(key)).toEqual({ c: 3.0 });
expect(await client.zpopmax(key, 3)).toEqual({
b: 2.0,
a: 1.0,
});
expect(await client.zpopmax(key)).toEqual({});
expect(await client.set(key, "value")).toEqual("OK");
await expect(client.zpopmax(key)).rejects.toThrow();
expect(await client.zpopmax("notExsitingKey")).toEqual({});
}, protocol);
},
config.timeout
);
}

export function runCommonTests<Context>(config: {
Expand Down
14 changes: 8 additions & 6 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,20 +131,22 @@ export function transactionTest(
args.push(1);
baseTransaction.smembers(key7);
args.push(["bar"]);
baseTransaction.zadd(key8, { member1: 1, member2: 2 });
args.push(2);
baseTransaction.zadd(key8, { member1: 1, member2: 2, member3: 3.5 });
args.push(3);
baseTransaction.zaddIncr(key8, "member2", 1);
args.push(3);
baseTransaction.zrem(key8, ["member1"]);
args.push(1);
baseTransaction.zcard(key8);
args.push(1);
args.push(2);
baseTransaction.zscore(key8, "member2");
args.push(3.0);
baseTransaction.zcount(key8, { bound: 2 }, "positiveInfinity");
args.push(1);
baseTransaction.zpopmin(key8)
args.push({"member2": 3.0})
args.push(2);
baseTransaction.zpopmin(key8);
args.push({"member2": 3.0});
baseTransaction.zpopmax(key8);
args.push({"member3": 3.5});
return args;
}

Expand Down

0 comments on commit 38544ea

Please sign in to comment.