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

Python: add OBJECT REFCOUNT command #1485

Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Python: Added OBJECT FREQ command ([#1472](https://github.com/aws/glide-for-redis/pull/1472))
* Python: Added OBJECT IDLETIME command ([#1474](https://github.com/aws/glide-for-redis/pull/1474))
* Node: Added RENAMENX command ([#1483](https://github.com/aws/glide-for-redis/pull/1483))
* Python: Added OBJECT REFCOUNT command ([#1485](https://github.com/aws/glide-for-redis/pull/1485))

## 0.4.0 (2024-05-26)

Expand Down
22 changes: 22 additions & 0 deletions python/python/glide/async_commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3587,3 +3587,25 @@ async def object_idletime(self, key: str) -> Optional[int]:
Optional[int],
await self._execute_command(RequestType.ObjectIdleTime, [key]),
)

async def object_refcount(self, key: str) -> Optional[int]:
"""
Returns the reference count of the object stored at `key`.

See https://valkey.io/commands/object-refcount for more details.

Args:
key (str): The key of the object to get the reference count of.

Returns:
Optional[int]: If `key` exists, returns the reference count of the object stored at `key` as an integer.
Otherwise, returns None.

Examples:
>>> await client.object_refcount("my_hash")
2 # "my_hash" has a reference count of 2.
"""
return cast(
Optional[int],
await self._execute_command(RequestType.ObjectRefCount, [key]),
)
15 changes: 15 additions & 0 deletions python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -2504,6 +2504,21 @@ def object_idletime(self: TTransaction, key: str) -> TTransaction:
"""
return self.append_command(RequestType.ObjectIdleTime, [key])

def object_refcount(self: TTransaction, key: str) -> TTransaction:
"""
Returns the reference count of the object stored at `key`.

See https://valkey.io/commands/object-refcount for more details.

Args:
key (str): The key of the object to get the reference count of.

Command response:
Optional[int]: If `key` exists, returns the reference count of the object stored at `key` as an integer.
Otherwise, returns None.
"""
return self.append_command(RequestType.ObjectRefCount, [key])


class Transaction(BaseTransaction):
"""
Expand Down
11 changes: 11 additions & 0 deletions python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3426,6 +3426,17 @@ async def test_object_idletime(self, redis_client: TRedisClient):
idletime = await redis_client.object_idletime(string_key)
assert idletime is not None and idletime > 0

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_object_refcount(self, redis_client: TRedisClient):
string_key = get_random_string(10)
non_existing_key = get_random_string(10)

assert await redis_client.object_refcount(non_existing_key) is None
assert await redis_client.set(string_key, "foo") == OK
refcount = await redis_client.object_refcount(string_key)
assert refcount is not None and refcount >= 0


class TestMultiKeyCommandCrossSlot:
@pytest.mark.parametrize("cluster_mode", [True])
Expand Down
20 changes: 10 additions & 10 deletions python/python/tests/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ async def test_transaction_object_commands(
transaction = ClusterTransaction() if cluster_mode else Transaction()
transaction.set(string_key, "foo")
transaction.object_encoding(string_key)
transaction.object_refcount(string_key)
# OBJECT FREQ requires a LFU maxmemory-policy
transaction.config_set({maxmemory_policy_key: "allkeys-lfu"})
transaction.object_freq(string_key)
Expand All @@ -529,15 +530,14 @@ async def test_transaction_object_commands(
assert response is not None
assert response[0] == OK # transaction.set(string_key, "foo")
assert response[1] == "embstr" # transaction.object_encoding(string_key)
assert (
response[2] == OK
) # transaction.config_set({maxmemory_policy_key: "allkeys-lfu"})
assert cast(int, response[3]) >= 0 # transaction.object_freq(string_key)
assert (
response[4] == OK
) # transaction.config_set({maxmemory_policy_key: "allkeys-random"})
assert (
cast(int, response[5]) >= 0
) # transaction.object_idletime(string_key)
# transaction.object_refcount(string_key)
assert cast(int, response[2]) >= 0
# transaction.config_set({maxmemory_policy_key: "allkeys-lfu"})
assert response[3] == OK
assert cast(int, response[4]) >= 0 # transaction.object_freq(string_key)
# transaction.config_set({maxmemory_policy_key: "allkeys-random"})
assert response[5] == OK
# transaction.object_idletime(string_key)
assert cast(int, response[6]) >= 0
finally:
await redis_client.config_set({maxmemory_policy_key: maxmemory_policy})
Loading