Skip to content

Commit

Permalink
Add a field indicate whether the expiration time of field is included
Browse files Browse the repository at this point in the history
  • Loading branch information
jjz921024 committed Jul 16, 2024
1 parent 28b8601 commit d188c7b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 14 deletions.
4 changes: 2 additions & 2 deletions src/storage/redis_db.cc
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ rocksdb::Status SubKeyScanner::Scan(RedisType type, const Slice &user_key, const
InternalKey ikey(iter->key(), storage_->IsSlotIdEncoded());
auto value = iter->value().ToString();
// filter expired hash field
if (type == kRedisHash && (static_cast<HashMetadata*>(&metadata))->IsEncodedFieldHasTTL()) {
if (type == kRedisHash && (static_cast<HashMetadata*>(&metadata))->is_ttl_field_encoded) {
uint64_t expire = 0;
rocksdb::Slice data(value.data(), value.size());
GetFixed64(&data, &expire);
Expand Down Expand Up @@ -662,7 +662,7 @@ rocksdb::Status Database::typeInternal(const Slice &key, RedisType *type) {
if (!s.ok()) return s;
if (metadata.Expired()) {
*type = kRedisNone;
} else if (metadata.Type() == kRedisHash && (static_cast<HashMetadata*>(&metadata))->IsEncodedFieldHasTTL()) {
} else if (metadata.Type() == kRedisHash && (static_cast<HashMetadata*>(&metadata))->is_ttl_field_encoded) {
redis::Hash hash_db(storage_, namespace_);
auto [_, user_key] = ExtractNamespaceKey(key, storage_->IsSlotIdEncoded());
std::vector<FieldValue> field_values;
Expand Down
23 changes: 21 additions & 2 deletions src/storage/redis_metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,27 @@ bool Metadata::IsEmptyableType() const {

bool Metadata::Expired() const { return ExpireAt(util::GetTimeStampMS()); }

bool HashMetadata::IsEncodedFieldHasTTL() const {
return flags & METADATA_HASH_FIELD_EXPIRE_MASK;
void HashMetadata::Encode(std::string *dst) const {
Metadata::Encode(dst);
if (is_ttl_field_encoded) {
uint8_t flag = 0;
flag |= METADATA_HASH_FIELD_EXPIRE_MASK;
PutFixed8(dst, flag);
}
}

rocksdb::Status HashMetadata::Decode(Slice *input) {
if (auto s = Metadata::Decode(input); !s.ok()) {
return s;
}

if (input->size() >= 1) {
uint8_t flag = 0;
GetFixed8(input, &flag);
is_ttl_field_encoded = flag &= METADATA_HASH_FIELD_EXPIRE_MASK;
}

return rocksdb::Status::OK();
}

ListMetadata::ListMetadata(bool generate_version)
Expand Down
7 changes: 5 additions & 2 deletions src/storage/redis_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ class InternalKey {
};

constexpr uint8_t METADATA_64BIT_ENCODING_MASK = 0x80;
constexpr uint8_t METADATA_HASH_FIELD_EXPIRE_MASK = 0x40;
constexpr uint8_t METADATA_TYPE_MASK = 0x0f;
constexpr uint8_t METADATA_HASH_FIELD_EXPIRE_MASK = 0x01;

class Metadata {
public:
Expand Down Expand Up @@ -203,9 +203,12 @@ class Metadata {

class HashMetadata : public Metadata {
public:
bool is_ttl_field_encoded;
explicit HashMetadata(bool generate_version = true) : Metadata(kRedisHash, generate_version) {}

bool IsEncodedFieldHasTTL() const;
void Encode(std::string *dst) const override;
using Metadata::Decode;
rocksdb::Status Decode(Slice *input) override;
};

class SetMetadata : public Metadata {
Expand Down
16 changes: 8 additions & 8 deletions src/types/redis_hash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ rocksdb::Status Hash::Size(const Slice &user_key, uint64_t *size) {
HashMetadata metadata(false);
rocksdb::Status s = GetMetadata(Database::GetOptions{}, ns_key, &metadata);
if (!s.ok()) return s;
if (!metadata.IsEncodedFieldHasTTL()) {
if (!metadata.is_ttl_field_encoded) {
*size = metadata.size;
} else {
std::vector<FieldValue> field_values;
Expand Down Expand Up @@ -113,7 +113,7 @@ rocksdb::Status Hash::IncrBy(const Slice &user_key, const Slice &field, int64_t
WriteBatchLogData log_data(kRedisHash);
batch->PutLogData(log_data.Encode());
auto value_str = std::to_string(*new_value);
if (metadata.IsEncodedFieldHasTTL()) {
if (metadata.is_ttl_field_encoded) {
encodeFieldAndTTL(&value_str, expire);
}
batch->Put(sub_key, value_str);
Expand Down Expand Up @@ -164,7 +164,7 @@ rocksdb::Status Hash::IncrByFloat(const Slice &user_key, const Slice &field, dou
WriteBatchLogData log_data(kRedisHash);
batch->PutLogData(log_data.Encode());
auto value_str = std::to_string(*new_value);
if (metadata.IsEncodedFieldHasTTL()) {
if (metadata.is_ttl_field_encoded) {
encodeFieldAndTTL(&value_str, expire);
}
batch->Put(sub_key, value_str);
Expand Down Expand Up @@ -308,7 +308,7 @@ rocksdb::Status Hash::MSet(const Slice &user_key, const std::vector<FieldValue>
}

auto value = it->value;
if (metadata.IsEncodedFieldHasTTL()) {
if (metadata.is_ttl_field_encoded) {
encodeFieldAndTTL(&value, expire);
}
batch->Put(sub_key, value);
Expand Down Expand Up @@ -545,8 +545,8 @@ rocksdb::Status Hash::ExpireFields(const Slice &user_key, uint64_t expire_ms,
}

// convert rest field encoding
if (!metadata.IsEncodedFieldHasTTL()) {
metadata.flags |= METADATA_HASH_FIELD_EXPIRE_MASK;
if (!metadata.is_ttl_field_encoded) {
metadata.is_ttl_field_encoded = true;

std::unordered_set<std::string_view> field_set;
for (auto field : fields) {
Expand Down Expand Up @@ -636,7 +636,7 @@ rocksdb::Status Hash::TTLFields(const Slice &user_key, const std::vector<Slice>
}

bool Hash::IsFieldExpired(Metadata &metadata, const Slice &value) {
if (!(static_cast<HashMetadata*>(&metadata))->IsEncodedFieldHasTTL()) {
if (!(static_cast<HashMetadata*>(&metadata))->is_ttl_field_encoded) {
return false;
}
uint64_t expire = 0;
Expand All @@ -646,7 +646,7 @@ bool Hash::IsFieldExpired(Metadata &metadata, const Slice &value) {
}

rocksdb::Status Hash::decodeFieldAndTTL(const HashMetadata &metadata, std::string *value, uint64_t &expire) {
if (!metadata.IsEncodedFieldHasTTL()) {
if (!metadata.is_ttl_field_encoded) {
return rocksdb::Status::OK();
}
rocksdb::Slice data(value->data(), value->size());
Expand Down

0 comments on commit d188c7b

Please sign in to comment.