Skip to content

Commit 7017ce1

Browse files
authored
LRUStoreCache: cache "contains" by contains checks (#1499)
* cache "contains" by contains checks * updated the test_cache_keys counts * release notes
1 parent f542fca commit 7017ce1

File tree

4 files changed

+18
-12
lines changed

4 files changed

+18
-12
lines changed

docs/release.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ Maintenance
2727
* Add ``docs`` requirements to ``pyproject.toml``
2828
By :user:`John A. Kirkham <jakirkham>` :issue:`1494`.
2929

30+
* Fixed caching issue in ``LRUStoreCache``.
31+
By :user:`Mads R. B. Kristensen <madsbk>` :issue:`1499`.
32+
3033
.. _release_2.16.0:
3134

3235
2.16.0

zarr/_storage/v3.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ def __init__(self, store, max_size: int):
509509
self._max_size = max_size
510510
self._current_size = 0
511511
self._keys_cache = None
512-
self._contains_cache = None
512+
self._contains_cache = {}
513513
self._listdir_cache: Dict[Path, Any] = dict()
514514
self._values_cache: Dict[Path, Any] = OrderedDict()
515515
self._mutex = Lock()

zarr/storage.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,7 +2393,7 @@ def __init__(self, store: StoreLike, max_size: int):
23932393
self._max_size = max_size
23942394
self._current_size = 0
23952395
self._keys_cache = None
2396-
self._contains_cache = None
2396+
self._contains_cache: Dict[Any, Any] = {}
23972397
self._listdir_cache: Dict[Path, Any] = dict()
23982398
self._values_cache: Dict[Path, Any] = OrderedDict()
23992399
self._mutex = Lock()
@@ -2434,9 +2434,9 @@ def __iter__(self):
24342434

24352435
def __contains__(self, key):
24362436
with self._mutex:
2437-
if self._contains_cache is None:
2438-
self._contains_cache = set(self._keys())
2439-
return key in self._contains_cache
2437+
if key not in self._contains_cache:
2438+
self._contains_cache[key] = key in self._store
2439+
return self._contains_cache[key]
24402440

24412441
def clear(self):
24422442
self._store.clear()
@@ -2506,7 +2506,7 @@ def invalidate_keys(self):
25062506

25072507
def _invalidate_keys(self):
25082508
self._keys_cache = None
2509-
self._contains_cache = None
2509+
self._contains_cache.clear()
25102510
self._listdir_cache.clear()
25112511

25122512
def _invalidate_value(self, key):

zarr/tests/test_storage.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,7 +2196,10 @@ def test_cache_keys(self):
21962196
assert keys == sorted(cache.keys())
21972197
assert 1 == store.counter["keys"]
21982198
assert foo_key in cache
2199-
assert 0 == store.counter["__contains__", foo_key]
2199+
assert 1 == store.counter["__contains__", foo_key]
2200+
# the next check for `foo_key` is cached
2201+
assert foo_key in cache
2202+
assert 1 == store.counter["__contains__", foo_key]
22002203
assert keys == sorted(cache)
22012204
assert 0 == store.counter["__iter__"]
22022205
assert 1 == store.counter["keys"]
@@ -2215,23 +2218,23 @@ def test_cache_keys(self):
22152218
keys = sorted(cache.keys())
22162219
assert keys == [bar_key, baz_key, foo_key]
22172220
assert 3 == store.counter["keys"]
2218-
assert 0 == store.counter["__contains__", foo_key]
2221+
assert 1 == store.counter["__contains__", foo_key]
22192222
assert 0 == store.counter["__iter__"]
22202223
cache.invalidate_keys()
22212224
keys = sorted(cache)
22222225
assert keys == [bar_key, baz_key, foo_key]
22232226
assert 4 == store.counter["keys"]
2224-
assert 0 == store.counter["__contains__", foo_key]
2227+
assert 1 == store.counter["__contains__", foo_key]
22252228
assert 0 == store.counter["__iter__"]
22262229
cache.invalidate_keys()
22272230
assert foo_key in cache
2228-
assert 5 == store.counter["keys"]
2229-
assert 0 == store.counter["__contains__", foo_key]
2231+
assert 4 == store.counter["keys"]
2232+
assert 2 == store.counter["__contains__", foo_key]
22302233
assert 0 == store.counter["__iter__"]
22312234

22322235
# check these would get counted if called directly
22332236
assert foo_key in store
2234-
assert 1 == store.counter["__contains__", foo_key]
2237+
assert 3 == store.counter["__contains__", foo_key]
22352238
assert keys == sorted(store)
22362239
assert 1 == store.counter["__iter__"]
22372240

0 commit comments

Comments
 (0)