Skip to content

Commit

Permalink
add GetValidFieldCount method
Browse files Browse the repository at this point in the history
  • Loading branch information
jjz921024 committed Jan 11, 2025
1 parent 473db0c commit 0f9007d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 24 deletions.
56 changes: 32 additions & 24 deletions src/types/redis_hash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,8 @@ rocksdb::Status Hash::Size(engine::Context &ctx, const Slice &user_key, uint64_t
HashMetadata metadata(false);
rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata);
if (!s.ok()) return s;
// if field expiration is disabled,
// the size field in metadata is the length of hash
if (!metadata.IsFieldExpirationEnabled()) {
*size = metadata.size;
return rocksdb::Status::OK();
}

// otherwise, we have to check each field to calc the length
std::string prefix_key = InternalKey(ns_key, "", metadata.version, storage_->IsSlotIdEncoded()).Encode();
std::string next_version_prefix_key =
InternalKey(ns_key, "", metadata.version + 1, storage_->IsSlotIdEncoded()).Encode();

rocksdb::ReadOptions read_options = ctx.DefaultScanOptions();
rocksdb::Slice upper_bound(next_version_prefix_key);
read_options.iterate_upper_bound = &upper_bound;

auto iter = util::UniqueIterator(ctx, read_options);
for (iter->Seek(prefix_key); iter->Valid() && iter->key().starts_with(prefix_key); iter->Next()) {
uint64_t expire = 0;
auto value = iter->value().ToString();
if (!decodeExpireFromValue(metadata, &value, expire).ok()) {
continue;
}
*size += 1;
}
size += GetValidFieldCount(ctx, ns_key, metadata);
return rocksdb::Status::OK();
}

Expand Down Expand Up @@ -734,6 +711,37 @@ bool Hash::IsFieldExpired(const Slice &metadata_key, const Slice &value) {
return expire != 0 && expire < util::GetTimeStampMS();
}

uint64_t Hash::GetValidFieldCount(engine::Context &ctx, const Slice &ns_key, const HashMetadata &metadata) {
if (metadata.Expired()) {
return 0;
}
// if field expiration is disabled,
// the size field in metadata is the length of hash
if (!metadata.IsFieldExpirationEnabled()) {
return metadata.size;
}

std::string prefix_key = InternalKey(ns_key, "", metadata.version, storage_->IsSlotIdEncoded()).Encode();
std::string next_version_prefix_key =
InternalKey(ns_key, "", metadata.version + 1, storage_->IsSlotIdEncoded()).Encode();

rocksdb::ReadOptions read_options = ctx.DefaultScanOptions();
rocksdb::Slice upper_bound(next_version_prefix_key);
read_options.iterate_upper_bound = &upper_bound;

// count the num of expired field
uint64_t expired_field_num = 0;
auto iter = util::UniqueIterator(ctx, read_options);
for (iter->Seek(prefix_key); iter->Valid() && iter->key().starts_with(prefix_key); iter->Next()) {
uint64_t expire = 0;
auto value = iter->value().ToString();
if (!decodeExpireFromValue(metadata, &value, expire).ok()) {
expired_field_num += 1;
}
}
return metadata.size - expired_field_num;
}

bool Hash::ExistValidField(engine::Context &ctx, const Slice &ns_key, const HashMetadata &metadata) {
if (metadata.Expired()) {
return false;
Expand Down
1 change: 1 addition & 0 deletions src/types/redis_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class Hash : public SubKeyScanner {
std::vector<int8_t> *ret);
rocksdb::Status TTLFields(engine::Context &ctx, const Slice &user_key, const std::vector<Slice> &fields,
std::vector<int64_t> *ret);
uint64_t GetValidFieldCount(engine::Context &ctx, const Slice &ns_key, const HashMetadata &metadata);
bool ExistValidField(engine::Context &ctx, const Slice &ns_key, const HashMetadata &metadata);
static bool IsFieldExpired(const Slice &metadata_key, const Slice &value);

Expand Down

0 comments on commit 0f9007d

Please sign in to comment.