Skip to content

Commit aaccae2

Browse files
committed
Optimize dependencies profiles
Fix some bugs Write tests for FIFOCache and Cache Optimize some operations Write FIFOCache
1 parent 49c5ffd commit aaccae2

15 files changed

+984
-201
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
/target
33
__pycache__
44
*.so
5-
/.caches.rs
5+
/.coverage
6+
/.pytest_cache

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ version = "1.0.0"
4141
version = "0.12.3"
4242
default-features = false
4343

44+
[profile.release.package."*"]
45+
codegen-units = 1 # better optimizations
46+
4447
[build-dependencies.pyo3-build-config]
4548
version = "0.24.1"
4649
features = ["resolve-config"]

pyproject.toml

+4
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ Homepage = 'https://github.com/awolverp/cachebox'
4444
[project.optional-dependencies]
4545
tests = [
4646
"pytest",
47+
"pytest-asyncio",
4748
"coverage",
4849
]
4950

51+
[tool.pytest.ini_options]
52+
asyncio_default_fixture_loop_scope = "function"
53+
5054
[tool.maturin]
5155
python-source = "python"
5256
features = ["pyo3/extension-module"]

python/cachebox/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from ._cachebox import (
22
Cache as Cache,
3+
FIFOCache as FIFOCache,
34
BaseCacheImpl as BaseCacheImpl,
5+
IteratorView as IteratorView,
46
)

python/cachebox/_cachebox.py

+71-35
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,26 @@
66
VT = typing.TypeVar("VT")
77
DT = typing.TypeVar("DT")
88

9-
_sential = object()
109

11-
12-
def _items_to_str(items, length, max_len=50):
13-
if length <= max_len:
10+
def _items_to_str(items, length):
11+
if length <= 50:
1412
return "{" + ", ".join(f"{k}: {v}" for k, v in items) + "}"
1513

1614
c = 0
1715
left = []
18-
right = []
1916

2017
while c < length:
2118
k, v = next(items)
2219

23-
if c <= 20:
20+
if c <= 50:
2421
left.append(f"{k}: {v}")
2522

26-
elif (length - c) <= 20:
27-
right.append(f"{k}: {v}")
23+
else:
24+
break
2825

2926
c += 1
3027

31-
return "{" + ", ".join(left) + " ... truncated ... " + ", ".join(right) + "}"
28+
return "{%s, ... %d more ...}" % (", ".join(left), length - c)
3229

3330

3431
class BaseCacheImpl(typing.Generic[KT, VT]):
@@ -129,13 +126,19 @@ def insert(self, key: KT, value: VT) -> typing.Optional[VT]:
129126

130127
def get(self, key: KT, default: typing.Optional[DT] = None) -> typing.Union[VT, DT]:
131128
"""Equals to `self[key]`, but returns `default` if the cache don't have this key present."""
132-
return self._raw.get(key, default)
129+
try:
130+
return self._raw.get(key)
131+
except _core.CoreKeyError:
132+
return default
133133

134134
def pop(self, key: KT, default: typing.Optional[DT] = None) -> typing.Union[VT, DT]:
135135
"""
136136
Removes specified key and return the corresponding value. If the key is not found, returns the `default`.
137137
"""
138-
return self._raw.pop(key, default)
138+
try:
139+
return self._raw.remove(key)
140+
except _core.CoreKeyError:
141+
return default
139142

140143
def setdefault(self, key: KT, default: typing.Optional[DT] = None) -> typing.Union[VT, DT]:
141144
"""
@@ -165,22 +168,28 @@ def __setitem__(self, key: KT, value: VT) -> None:
165168
self.insert(key, value)
166169

167170
def __getitem__(self, key: KT) -> VT:
168-
val = self._raw.get(key, _sential)
169-
if val is _sential:
170-
raise KeyError(key)
171-
172-
return val
171+
try:
172+
return self._raw.get(key)
173+
except _core.CoreKeyError:
174+
raise KeyError(key) from None
173175

174176
def __delitem__(self, key: KT) -> None:
175-
val = self._raw.pop(key, _sential)
176-
if val is _sential:
177-
raise KeyError(key)
177+
try:
178+
self._raw.remove(key)
179+
except _core.CoreKeyError:
180+
raise KeyError(key) from None
178181

179182
def __eq__(self, other) -> bool:
180-
return self._raw == other
183+
if not isinstance(other, Cache):
184+
return False
185+
186+
return self._raw == other._raw
181187

182188
def __ne__(self, other) -> bool:
183-
return self._raw != other
189+
if not isinstance(other, Cache):
190+
return False
191+
192+
return self._raw != other._raw
184193

185194
def shrink_to_fit(self) -> None:
186195
"""Shrinks the cache to fit len(self) elements."""
@@ -278,16 +287,25 @@ def insert(self, key: KT, value: VT) -> typing.Optional[VT]:
278287
return self._raw.insert(key, value)
279288

280289
def get(self, key: KT, default: typing.Optional[DT] = None) -> typing.Union[VT, DT]:
281-
return self._raw.get(key, default)
290+
try:
291+
return self._raw.get(key)
292+
except _core.CoreKeyError:
293+
return default
282294

283295
def pop(self, key: KT, default: typing.Optional[DT] = None) -> typing.Union[VT, DT]:
284-
return self._raw.pop(key, default)
296+
try:
297+
return self._raw.remove(key)
298+
except _core.CoreKeyError:
299+
return default
285300

286301
def setdefault(self, key: KT, default: typing.Optional[DT] = None) -> typing.Union[VT, DT]:
287302
return self._raw.setdefault(key, default)
288303

289304
def popitem(self) -> typing.Tuple[KT, VT]:
290-
return self._raw.popitem()
305+
try:
306+
return self._raw.popitem()
307+
except _core.CoreKeyError:
308+
raise KeyError() from None
291309

292310
def drain(self, n: int) -> int:
293311
if n == 0:
@@ -296,7 +314,7 @@ def drain(self, n: int) -> int:
296314
for i in range(n):
297315
try:
298316
self._raw.popitem()
299-
except KeyError:
317+
except _core.CoreKeyError:
300318
return i
301319

302320
return i
@@ -311,22 +329,28 @@ def __setitem__(self, key: KT, value: VT) -> None:
311329
self.insert(key, value)
312330

313331
def __getitem__(self, key: KT) -> VT:
314-
val = self._raw.get(key, _sential)
315-
if val is _sential:
316-
raise KeyError(key)
317-
318-
return val
332+
try:
333+
return self._raw.get(key)
334+
except _core.CoreKeyError:
335+
raise KeyError(key) from None
319336

320337
def __delitem__(self, key: KT) -> None:
321-
val = self._raw.pop(key, _sential)
322-
if val is _sential:
323-
raise KeyError(key)
338+
try:
339+
self._raw.remove(key)
340+
except _core.CoreKeyError:
341+
raise KeyError(key) from None
324342

325343
def __eq__(self, other) -> bool:
326-
return self._raw == other
344+
if not isinstance(other, FIFOCache):
345+
return False
346+
347+
return self._raw == other._raw
327348

328349
def __ne__(self, other) -> bool:
329-
return self._raw != other
350+
if not isinstance(other, FIFOCache):
351+
return False
352+
353+
return self._raw != other._raw
330354

331355
def shrink_to_fit(self) -> None:
332356
self._raw.shrink_to_fit()
@@ -343,6 +367,18 @@ def keys(self) -> IteratorView[KT]:
343367
def values(self) -> IteratorView[VT]:
344368
return IteratorView(self._raw.items(), lambda x: x[1])
345369

370+
def first(self, n: int = 0) -> typing.Optional[KT]:
371+
if n < 0:
372+
n = len(self._raw) + n
373+
374+
if n < 0:
375+
return None
376+
377+
return self._raw.get_index(n)
378+
379+
def last(self) -> typing.Optional[KT]:
380+
return self._raw.get_index(len(self._raw) - 1)
381+
346382
def __iter__(self) -> IteratorView[KT]:
347383
return self.keys()
348384

python/tests/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)