From 4ccaf889791eda6c800a42c73c90fd7fa46e7786 Mon Sep 17 00:00:00 2001 From: iWw Date: Tue, 9 Dec 2025 03:49:37 +0800 Subject: [PATCH] fix: bugs in zpopmin/zpopmax; --- .../Commands/SortedSetCommands.swift | 21 ++++++++++--------- .../Commands/SortedSetCommandsTests.swift | 4 ++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Sources/RediStack/Commands/SortedSetCommands.swift b/Sources/RediStack/Commands/SortedSetCommands.swift index 81766393..91733f56 100644 --- a/Sources/RediStack/Commands/SortedSetCommands.swift +++ b/Sources/RediStack/Commands/SortedSetCommands.swift @@ -561,8 +561,8 @@ extension RedisClient { /// - key: The key identifying the sorted set in Redis. /// - count: The max number of elements to pop from the set. /// - Returns: A list of elements popped from the sorted set with their associated score. - public func zpopmin(from key: RedisKey, max count: Int) -> EventLoopFuture<[(RESPValue, Double)]> { - _zpop(command: "ZPOPMIN", count, key) + public func zpopmin(from key: RedisKey, max count: Int, scoreIsFirst: Bool = false) -> EventLoopFuture<[(RESPValue, Double)]> { + _zpop(command: "ZPOPMIN", count, key, scoreIsFirst: scoreIsFirst) } /// Removes the element from a sorted set with the lowest score. @@ -570,8 +570,8 @@ extension RedisClient { /// See [https://redis.io/commands/zpopmin](https://redis.io/commands/zpopmin) /// - Parameter key: The key identifying the sorted set in Redis. /// - Returns: The element and its associated score that was popped from the sorted set, or `nil` if set was empty. - public func zpopmin(from key: RedisKey) -> EventLoopFuture<(RESPValue, Double)?> { - _zpop(command: "ZPOPMIN", nil, key) + public func zpopmin(from key: RedisKey, scoreIsFirst: Bool = false) -> EventLoopFuture<(RESPValue, Double)?> { + _zpop(command: "ZPOPMIN", nil, key, scoreIsFirst: scoreIsFirst) .map { $0.count > 0 ? $0[0] : nil } } @@ -582,8 +582,8 @@ extension RedisClient { /// - key: The key identifying the sorted set in Redis. /// - count: The max number of elements to pop from the set. /// - Returns: A list of elements popped from the sorted set with their associated score. - public func zpopmax(from key: RedisKey, max count: Int) -> EventLoopFuture<[(RESPValue, Double)]> { - _zpop(command: "ZPOPMAX", count, key) + public func zpopmax(from key: RedisKey, max count: Int, scoreIsFirst: Bool = false) -> EventLoopFuture<[(RESPValue, Double)]> { + _zpop(command: "ZPOPMAX", count, key, scoreIsFirst: scoreIsFirst) } /// Removes the element from a sorted set with the highest score. @@ -591,15 +591,16 @@ extension RedisClient { /// See [https://redis.io/commands/zpopmax](https://redis.io/commands/zpopmax) /// - Parameter key: The key identifying the sorted set in Redis. /// - Returns: The element and its associated score that was popped from the sorted set, or `nil` if set was empty. - public func zpopmax(from key: RedisKey) -> EventLoopFuture<(RESPValue, Double)?> { - _zpop(command: "ZPOPMAX", nil, key) + public func zpopmax(from key: RedisKey, scoreIsFirst: Bool = false) -> EventLoopFuture<(RESPValue, Double)?> { + _zpop(command: "ZPOPMAX", nil, key, scoreIsFirst: scoreIsFirst) .map { $0.count > 0 ? $0[0] : nil } } func _zpop( command: String, _ count: Int?, - _ key: RedisKey + _ key: RedisKey, + scoreIsFirst: Bool ) -> EventLoopFuture<[(RESPValue, Double)]> { var args: [RESPValue] = [.init(from: key)] @@ -611,7 +612,7 @@ extension RedisClient { return send(command: command, with: args) .tryConverting(to: [RESPValue].self) - .flatMapThrowing { try Self._mapSortedSetResponse($0, scoreIsFirst: true) } + .flatMapThrowing { try Self._mapSortedSetResponse($0, scoreIsFirst: scoreIsFirst) } } } diff --git a/Tests/RediStackIntegrationTests/Commands/SortedSetCommandsTests.swift b/Tests/RediStackIntegrationTests/Commands/SortedSetCommandsTests.swift index ee221fd0..af75d49f 100644 --- a/Tests/RediStackIntegrationTests/Commands/SortedSetCommandsTests.swift +++ b/Tests/RediStackIntegrationTests/Commands/SortedSetCommandsTests.swift @@ -555,6 +555,10 @@ extension SortedSetCommandsTests { XCTAssertEqual(elements.count, 5) XCTAssertEqual(elements, elements.sorted(by: <)) + + // test when score is not first + let value = try self.connection.zpopmin(from: #function, scoreIsFirst: false).wait() + XCTAssertEqual(value?.1, 1) } func test_zrevrange_realworld() throws {