8
8
from quixstreams .state .metadata import SEPARATOR
9
9
from quixstreams .state .recovery import ChangelogProducer
10
10
from quixstreams .state .rocksdb .cache import TimestampsCache
11
- from quixstreams .state .rocksdb .metadata import (
12
- LATEST_TIMESTAMP_KEY ,
13
- LATEST_TIMESTAMPS_CF_NAME ,
14
- )
15
11
from quixstreams .state .serialization import (
16
12
DumpsFunc ,
17
13
LoadsFunc ,
30
26
31
27
DAYS_7 = 7 * 24 * 60 * 60 * 1000
32
28
29
+ MIN_ELIGIBLE_TIMESTAMPS_CF_NAME = "__min-eligible-timestamps__"
30
+ MIN_ELIGIBLE_TIMESTAMPS_KEY = b"__min_eligible_timestamps__"
31
+
33
32
34
33
class TimestampedPartitionTransaction (PartitionTransaction ):
35
34
"""
@@ -56,9 +55,9 @@ def __init__(
56
55
self ._partition : TimestampedStorePartition = cast (
57
56
"TimestampedStorePartition" , self ._partition
58
57
)
59
- self ._latest_timestamps : TimestampsCache = TimestampsCache (
60
- key = LATEST_TIMESTAMP_KEY ,
61
- cf_name = LATEST_TIMESTAMPS_CF_NAME ,
58
+ self ._min_eligible_timestamps : TimestampsCache = TimestampsCache (
59
+ key = MIN_ELIGIBLE_TIMESTAMPS_KEY ,
60
+ cf_name = MIN_ELIGIBLE_TIMESTAMPS_CF_NAME ,
62
61
)
63
62
64
63
@validate_transaction_status (PartitionTransactionStatus .STARTED )
@@ -86,12 +85,11 @@ def get_last(
86
85
"""
87
86
88
87
prefix = self ._ensure_bytes (prefix )
89
- latest_timestamp = self ._get_latest_timestamp (prefix , timestamp )
90
-
91
- # Negative retention is not allowed
92
- lower_bound = self ._serialize_key (
93
- max (latest_timestamp - retention_ms , 0 ), prefix
88
+ min_eligible_timestamp = self ._get_min_eligible_timestamp (
89
+ prefix , timestamp , retention_ms
94
90
)
91
+
92
+ lower_bound = self ._serialize_key (min_eligible_timestamp , prefix )
95
93
# +1 because upper bound is exclusive
96
94
upper_bound = self ._serialize_key (timestamp + 1 , prefix )
97
95
@@ -172,10 +170,12 @@ def _expire(
172
170
:param cf_name: Column family name.
173
171
"""
174
172
175
- latest_timestamp = self ._get_latest_timestamp (prefix , timestamp )
176
- self ._set_timestamp (prefix , latest_timestamp )
173
+ min_eligible_timestamp = self ._get_min_eligible_timestamp (
174
+ prefix , timestamp , retention_ms
175
+ )
176
+ self ._set_min_eligible_timestamp (prefix , min_eligible_timestamp )
177
177
178
- key = self ._serialize_key (max ( timestamp - retention_ms , 0 ) , prefix )
178
+ key = self ._serialize_key (min_eligible_timestamp , prefix )
179
179
180
180
cached = self ._update_cache .get_updates (cf_name = cf_name ).get (prefix , {})
181
181
# Cast to list to avoid RuntimeError: dictionary changed size during iteration
@@ -203,23 +203,19 @@ def _serialize_key(self, key: Union[int, bytes], prefix: bytes) -> bytes:
203
203
return prefix + SEPARATOR + key
204
204
raise ValueError (f"Invalid key type: { type (key )} " )
205
205
206
- def _get_latest_timestamp (self , prefix : bytes , timestamp : int ) -> Any :
207
- """
208
- Get the latest timestamp for a given prefix.
209
-
210
- If the timestamp is not found in the cache, it is fetched from the store.
211
- """
212
- cache = self ._latest_timestamps
206
+ def _get_min_eligible_timestamp (
207
+ self , prefix : bytes , timestamp : int , retention_ms : int
208
+ ) -> Any :
209
+ cache = self ._min_eligible_timestamps
213
210
ts = (
214
211
cache .timestamps .get (prefix )
215
212
or self .get (key = cache .key , prefix = prefix , cf_name = cache .cf_name )
216
213
or 0
217
214
)
218
- cache .timestamps [prefix ] = latest_timestamp = max (ts , timestamp )
219
- return latest_timestamp
215
+ return max (ts , timestamp - retention_ms )
220
216
221
- def _set_timestamp (self , prefix : bytes , timestamp : int ) -> None :
222
- cache = self ._latest_timestamps
217
+ def _set_min_eligible_timestamp (self , prefix : bytes , timestamp : int ) -> None :
218
+ cache = self ._min_eligible_timestamps
223
219
cache .timestamps [prefix ] = timestamp
224
220
self .set (key = cache .key , value = timestamp , prefix = prefix , cf_name = cache .cf_name )
225
221
@@ -233,7 +229,7 @@ class TimestampedStorePartition(RocksDBStorePartition):
233
229
"""
234
230
235
231
partition_transaction_class = TimestampedPartitionTransaction
236
- additional_column_families = (LATEST_TIMESTAMPS_CF_NAME ,)
232
+ additional_column_families = (MIN_ELIGIBLE_TIMESTAMPS_CF_NAME ,)
237
233
238
234
239
235
class TimestampedStore (RocksDBStore ):
0 commit comments