@@ -121,7 +121,14 @@ rocksdb::Status Hash::IncrBy(engine::Context &ctx, const Slice &user_key, const
121121 s = batch->PutLogData (log_data.Encode ());
122122 if (!s.ok ()) return s;
123123 s = batch->Put (sub_key, std::to_string (*new_value));
124+
125+ // if key expired we need to clean the ttl
124126 if (!s.ok ()) return s;
127+ if (expired) {
128+ auto sub_key_expire = GetSubKeyExpireInternalKey (user_key, field, metadata.version );
129+ s = batch->Delete (sub_key_expire);
130+ if (!s.ok ()) return s;
131+ }
125132 if (!exists) {
126133 metadata.size += 1 ;
127134 std::string bytes;
@@ -179,6 +186,15 @@ rocksdb::Status Hash::IncrByFloat(engine::Context &ctx, const Slice &user_key, c
179186 if (!s.ok ()) return s;
180187 s = batch->Put (sub_key, std::to_string (*new_value));
181188 if (!s.ok ()) return s;
189+
190+ // if key expired we need to clean the ttl
191+ if (!s.ok ()) return s;
192+ if (expired) {
193+ auto sub_key_expire = GetSubKeyExpireInternalKey (user_key, field, metadata.version );
194+ s = batch->Delete (sub_key_expire);
195+ if (!s.ok ()) return s;
196+ }
197+
182198 if (!exists) {
183199 metadata.size += 1 ;
184200 std::string bytes;
@@ -343,36 +359,38 @@ rocksdb::Status Hash::MSet(engine::Context &ctx, const Slice &user_key, const st
343359 const rocksdb::Slice field_key = keys[field_index];
344360 bool exists = false ;
345361
346- if (metadata.size > 0 ) {
347- rocksdb::Status &field_status = statuses_vector[field_index];
348- if (!field_status.ok () && !field_status.IsNotFound ()) {
349- return field_status;
350- }
351- if (field_status.ok ()) {
352- if (nx || values_vector[field_index] == values[field_index]) {
353- continue ;
354- }
355- exists = true ;
356- }
362+ rocksdb::Status &field_status = statuses_vector[field_index];
363+ if (!field_status.ok () && !field_status.IsNotFound ()) {
364+ return field_status;
357365 }
366+ if (field_status.ok ()) {
367+ if (nx || values_vector[field_index] == values[field_index]) {
368+ continue ;
369+ }
358370
359- if (!exists) {
360- added++;
371+ exists = true ;
361372 }
362373
363- s = batch->Put (field_key, values[field_index]);
364- if (!s.ok ()) return s;
365374 uint64_t expire_at = expire_ats[field_index];
366375 rocksdb::Status &expire_status = expire_statuses[field_index];
367376 if (!expire_status.ok () && !expire_status.IsNotFound ()) {
368377 return expire_status;
369378 }
370- // this key was once expired but the expire time exists may block the read
379+
380+ // try expired as not exists
371381 if (expire_at != NoExpireTime && expire_at < util::GetTimeStampMS ()) {
382+ exists = false ;
372383 auto sub_key_expire = GetSubKeyExpireInternalKey (user_key, origin_keys[field_index], metadata.version );
373384 s = batch->Delete (sub_key_expire);
374385 if (!s.ok ()) return s;
375386 }
387+
388+ if (!exists) {
389+ added++;
390+ }
391+
392+ s = batch->Put (field_key, values[field_index]);
393+ if (!s.ok ()) return s;
376394 }
377395
378396 if (added > 0 || ttl_updated) {
@@ -419,6 +437,8 @@ rocksdb::Status Hash::RangeByLex(engine::Context &ctx, const Slice &user_key, co
419437 iter->SeekForPrev (start_key);
420438 }
421439 }
440+
441+ auto current_timestamp_ms = util::GetTimeStampMS ();
422442 int64_t pos = 0 ;
423443 for (; iter->Valid () && iter->key ().starts_with (prefix_key); (!spec.reversed ? iter->Next () : iter->Prev ())) {
424444 InternalKey ikey (iter->key (), storage_->IsSlotIdEncoded ());
@@ -438,6 +458,14 @@ rocksdb::Status Hash::RangeByLex(engine::Context &ctx, const Slice &user_key, co
438458 }
439459 if (spec.offset >= 0 && pos++ < spec.offset ) continue ;
440460
461+ uint64_t expire_at = NoExpireTime;
462+ auto s = GetSubKeyExpireTimestampMS (ctx, user_key, ikey.GetSubKey (), metadata.version , &expire_at);
463+ if (!s.ok () && !s.IsNotFound ()) {
464+ return s;
465+ }
466+ if (expire_at != NoExpireTime && expire_at < current_timestamp_ms) {
467+ continue ;
468+ }
441469 field_values->emplace_back (ikey.GetSubKey ().ToString (), iter->value ().ToString ());
442470 if (spec.count > 0 && field_values->size () >= static_cast <unsigned >(spec.count )) break ;
443471 }
0 commit comments