Skip to content

Commit 6851e3e

Browse files
authored
Annotate LRUCache (#3395)
1 parent 4c05d38 commit 6851e3e

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

xarray/backends/file_manager.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import contextlib
2+
import io
23
import threading
34
import warnings
4-
from typing import Any, Dict
5+
from typing import Any, Dict, cast
56

67
from ..core import utils
78
from ..core.options import OPTIONS
89
from .locks import acquire
910
from .lru_cache import LRUCache
1011

1112
# Global cache for storing open files.
12-
FILE_CACHE = LRUCache(OPTIONS["file_cache_maxsize"], on_evict=lambda k, v: v.close())
13+
FILE_CACHE: LRUCache[str, io.IOBase] = LRUCache(
14+
maxsize=cast(int, OPTIONS["file_cache_maxsize"]), on_evict=lambda k, v: v.close()
15+
)
1316
assert FILE_CACHE.maxsize, "file cache must be at least size one"
1417

1518

xarray/backends/lru_cache.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import collections
2-
import collections.abc
31
import threading
2+
from collections import OrderedDict
3+
from typing import Any, Callable, Iterator, MutableMapping, Optional, TypeVar
44

5+
K = TypeVar("K")
6+
V = TypeVar("V")
57

6-
class LRUCache(collections.abc.MutableMapping):
8+
9+
class LRUCache(MutableMapping[K, V]):
710
"""Thread-safe LRUCache based on an OrderedDict.
811
912
All dict operations (__getitem__, __setitem__, __contains__) update the
@@ -18,7 +21,14 @@ class LRUCache(collections.abc.MutableMapping):
1821
the cache, e.g., ``cache.maxsize = new_size``.
1922
"""
2023

21-
def __init__(self, maxsize, on_evict=None):
24+
_cache: "OrderedDict[K, V]"
25+
_maxsize: int
26+
_lock: threading.RLock
27+
_on_evict: Optional[Callable[[K, V], Any]]
28+
29+
__slots__ = ("_cache", "_lock", "_maxsize", "_on_evict")
30+
31+
def __init__(self, maxsize: int, on_evict: Callable[[K, V], Any] = None):
2232
"""
2333
Parameters
2434
----------
@@ -33,25 +43,26 @@ def __init__(self, maxsize, on_evict=None):
3343
if maxsize < 0:
3444
raise ValueError("maxsize must be non-negative")
3545
self._maxsize = maxsize
36-
self._on_evict = on_evict
37-
self._cache = collections.OrderedDict()
46+
self._cache = OrderedDict()
3847
self._lock = threading.RLock()
48+
self._on_evict = on_evict
3949

40-
def __getitem__(self, key):
50+
def __getitem__(self, key: K) -> V:
4151
# record recent use of the key by moving it to the front of the list
4252
with self._lock:
4353
value = self._cache[key]
4454
self._cache.move_to_end(key)
4555
return value
4656

47-
def _enforce_size_limit(self, capacity):
48-
"""Shrink the cache if necessary, evicting the oldest items."""
57+
def _enforce_size_limit(self, capacity: int) -> None:
58+
"""Shrink the cache if necessary, evicting the oldest items.
59+
"""
4960
while len(self._cache) > capacity:
5061
key, value = self._cache.popitem(last=False)
5162
if self._on_evict is not None:
5263
self._on_evict(key, value)
5364

54-
def __setitem__(self, key, value):
65+
def __setitem__(self, key: K, value: V) -> None:
5566
with self._lock:
5667
if key in self._cache:
5768
# insert the new value at the end
@@ -65,24 +76,24 @@ def __setitem__(self, key, value):
6576
# not saving, immediately evict
6677
self._on_evict(key, value)
6778

68-
def __delitem__(self, key):
79+
def __delitem__(self, key: K) -> None:
6980
del self._cache[key]
7081

71-
def __iter__(self):
82+
def __iter__(self) -> Iterator[K]:
7283
# create a list, so accessing the cache during iteration cannot change
7384
# the iteration order
7485
return iter(list(self._cache))
7586

76-
def __len__(self):
87+
def __len__(self) -> int:
7788
return len(self._cache)
7889

7990
@property
80-
def maxsize(self):
91+
def maxsize(self) -> int:
8192
"""Maximum number of items can be held in the cache."""
8293
return self._maxsize
8394

8495
@maxsize.setter
85-
def maxsize(self, size):
96+
def maxsize(self, size: int) -> None:
8697
"""Resize the cache, evicting the oldest items if necessary."""
8798
if size < 0:
8899
raise ValueError("maxsize must be non-negative")

0 commit comments

Comments
 (0)