Skip to content
Open
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
8 changes: 4 additions & 4 deletions python/packages/purview/agent_framework_purview/_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ async def set(self, key: str, value: Any, ttl_seconds: int | None = None) -> Non
expiry = time.time() + ttl
size = self._estimate_size(value)

# Remove old entry if exists
if key in self._cache:
old_size = self._cache[key][2]
self._current_size_bytes -= old_size
# Remove the old entry so eviction cannot count its size again.
old_entry = self._cache.pop(key, None)
if old_entry is not None:
self._current_size_bytes -= old_entry[2]

# Evict if needed
self._evict_if_needed(size)
Expand Down
19 changes: 19 additions & 0 deletions python/packages/purview/tests/purview/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import asyncio

import pytest

from agent_framework_purview._cache import (
InMemoryCacheProvider,
create_protection_scopes_cache_key,
Expand Down Expand Up @@ -65,6 +67,23 @@ async def test_cache_update_existing_key(self) -> None:

assert result == "value2"

async def test_cache_growing_update_evicts_other_entries(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""Replacing the earliest-expiring entry must only subtract its size once."""
monkeypatch.setattr("agent_framework_purview._cache.time.time", lambda: 1000.0)
cache = InMemoryCacheProvider(max_size_bytes=20)

# JSON string quotes add two bytes to each value's estimated size.
await cache.set("older", "a" * 6, ttl_seconds=10)
await cache.set("newer", "b" * 6, ttl_seconds=20)
await cache.set("older", "c" * 14, ttl_seconds=30)

assert await cache.get("older") == "c" * 14
assert await cache.get("newer") is None
assert cache._current_size_bytes == 16

await cache.remove("older")
assert cache._current_size_bytes == 0

async def test_cache_remove(self) -> None:
"""Test removing a cache entry."""
cache = InMemoryCacheProvider()
Expand Down
Loading