@@ -259,6 +259,16 @@ rocksdb::Status Database::TTL(engine::Context &ctx, const Slice &user_key, int64
259
259
Metadata metadata (kRedisNone , false );
260
260
s = metadata.Decode (value);
261
261
if (!s.ok ()) return s;
262
+ if (metadata.Type () == kRedisHash ) {
263
+ HashMetadata hash_metadata (false );
264
+ s = hash_metadata.Decode (value);
265
+ if (!s.ok ()) return s;
266
+ redis::Hash hash_db (storage_, namespace_);
267
+ if (!hash_db.ExistValidField (ctx, ns_key, hash_metadata)) {
268
+ *ttl = -2 ;
269
+ return rocksdb::Status::OK ();
270
+ }
271
+ }
262
272
*ttl = metadata.TTL ();
263
273
264
274
return rocksdb::Status::OK ();
@@ -603,7 +613,7 @@ rocksdb::Status SubKeyScanner::Scan(engine::Context &ctx, RedisType type, const
603
613
std::string raw_value;
604
614
Slice rest;
605
615
606
- rocksdb::Status s = GetMetadata (ctx, {type}, ns_key, &metadata);
616
+ rocksdb::Status s = GetMetadata (ctx, {type}, ns_key, &raw_value, & metadata, &rest );
607
617
if (!s.ok ()) return s;
608
618
609
619
// for hash type, we should filter expired field if encoding is with_ttl
@@ -613,7 +623,7 @@ rocksdb::Status SubKeyScanner::Scan(engine::Context &ctx, RedisType type, const
613
623
if (!GetFixed8 (&rest, reinterpret_cast <uint8_t *>(&field_encoding))) {
614
624
return rocksdb::Status::InvalidArgument ();
615
625
}
616
- if (uint8_t ( field_encoding) > 1 ) {
626
+ if (field_encoding > HashSubkeyEncoding::VALUE_WITH_TTL ) {
617
627
return rocksdb::Status::InvalidArgument (" unexpected subkey encoding version" );
618
628
}
619
629
if (field_encoding == HashSubkeyEncoding::VALUE_WITH_TTL) {
@@ -700,7 +710,17 @@ rocksdb::Status Database::existsInternal(engine::Context &ctx, const std::vector
700
710
Metadata metadata (kRedisNone , false );
701
711
s = metadata.Decode (value);
702
712
if (!s.ok ()) return s;
703
- if (!metadata.Expired ()) *ret += 1 ;
713
+ if (metadata.Expired ()) continue ;
714
+ if (metadata.Type () == kRedisHash ) {
715
+ HashMetadata hash_metadata (false );
716
+ s = hash_metadata.Decode (value);
717
+ if (!s.ok ()) return s;
718
+ redis::Hash hash_db (storage_, namespace_);
719
+ if (!hash_db.ExistValidField (ctx, key, hash_metadata)) {
720
+ continue ;
721
+ }
722
+ }
723
+ *ret += 1 ;
704
724
}
705
725
}
706
726
return rocksdb::Status::OK ();
@@ -717,6 +737,16 @@ rocksdb::Status Database::typeInternal(engine::Context &ctx, const Slice &key, R
717
737
if (!s.ok ()) return s.IsNotFound () ? rocksdb::Status::OK () : s;
718
738
if (metadata.Expired ()) {
719
739
*type = kRedisNone ;
740
+ } else if (metadata.Type () == kRedisHash ) {
741
+ HashMetadata hash_metadata (false );
742
+ s = hash_metadata.Decode (value);
743
+ if (!s.ok ()) return s;
744
+ redis::Hash hash_db (storage_, namespace_);
745
+ if (hash_db.ExistValidField (ctx, key, hash_metadata)) {
746
+ *type = metadata.Type ();
747
+ } else {
748
+ *type = kRedisNone ;
749
+ }
720
750
} else {
721
751
*type = metadata.Type ();
722
752
}
0 commit comments