Skip to content

Commit 0db996a

Browse files
committed
Optimize TimestampedPartitionTransaction._expire
1 parent ff4d3e2 commit 0db996a

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

quixstreams/state/rocksdb/timestamped.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections import deque
12
from typing import Any, Optional, Union, cast
23

34
from quixstreams.state.base.transaction import (
@@ -183,19 +184,25 @@ def _expire(self) -> None:
183184
RocksDB store within the current transaction.
184185
"""
185186
updates = self._update_cache.get_updates()
187+
# Accumulate the expired keys separately to avoid
188+
# mutating the update cache during iteration
189+
keys_to_delete: deque[tuple[bytes, bytes]] = deque()
190+
186191
for prefix, cached in updates.items():
187192
min_eligible_timestamp = self._get_min_eligible_timestamp(prefix)
188193

189194
key = self._serialize_key(min_eligible_timestamp, prefix)
190-
191-
# Cast to list to avoid RuntimeError: dictionary changed size during iteration
192-
for cached_key in list(cached):
195+
for cached_key in cached:
193196
if cached_key < key:
194-
self._update_cache.delete(cached_key, prefix)
197+
keys_to_delete.append((cached_key, prefix))
195198

196199
stored = self._partition.iter_items(lower_bound=prefix, upper_bound=key)
197200
for stored_key, _ in stored:
198-
self._update_cache.delete(stored_key, prefix)
201+
keys_to_delete.append((stored_key, prefix))
202+
203+
# Mark the expired keys as deleted in the update cache
204+
for key, prefix in keys_to_delete:
205+
self._update_cache.delete(key, prefix)
199206

200207
def _ensure_bytes(self, prefix: Any) -> bytes:
201208
if isinstance(prefix, bytes):

0 commit comments

Comments
 (0)