Skip to content

Commit 3874253

Browse files
authored
Fix cache eviction bug in ParallelStoreReader (#34)
1 parent 6961864 commit 3874253

2 files changed

Lines changed: 24 additions & 7 deletions

File tree

src/obspec_utils/obspec.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -607,15 +607,19 @@ def _get_chunks(self, chunk_indices: list[int]) -> dict[int, bytes]:
607607
# Store in cache
608608
for chunk_idx, data in zip(needed, results):
609609
self._cache[chunk_idx] = bytes(data)
610-
# Move to end (most recently used)
611-
self._cache.move_to_end(chunk_idx)
612610

613-
# Evict oldest if over capacity
614-
while len(self._cache) > self._max_cached_chunks:
615-
self._cache.popitem(last=False)
611+
# Mark all requested chunks as recently used
612+
for i in chunk_indices:
613+
self._cache.move_to_end(i)
616614

617-
# Return requested chunks from cache
618-
return {i: self._cache[i] for i in chunk_indices}
615+
# Build return dict before eviction
616+
result = {i: self._cache[i] for i in chunk_indices}
617+
618+
# Evict oldest if over capacity
619+
while len(self._cache) > self._max_cached_chunks:
620+
self._cache.popitem(last=False)
621+
622+
return result
619623

620624
def read(self, size: int = -1, /) -> bytes:
621625
"""

tests/test_parallel_reader.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,16 @@ def test_parallel_reader_caching():
4141
# First chunk refetched
4242
reader.seek(0)
4343
assert reader.read(4) == b"0123"
44+
45+
46+
def test_parallel_reader_read_spanning_more_chunks_than_cache():
47+
"""Read spanning more chunks than max_cached_chunks should succeed."""
48+
memstore = MemoryStore()
49+
# 20 bytes = 5 chunks of 4 bytes each
50+
memstore.put("test.txt", b"0123456789ABCDEFGHIJ")
51+
52+
reader = ParallelStoreReader(
53+
memstore, "test.txt", chunk_size=4, max_cached_chunks=2
54+
)
55+
56+
assert reader.read(20) == b"0123456789ABCDEFGHIJ"

0 commit comments

Comments
 (0)