Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node: added zpopmax command. #1009

Merged
merged 2 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading