blob: 330a8a7778d96f7dbb80cbf45e8f993cf374033a [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#include "disk_stats.h"
#include <memory>
#include <string>
#include "db_util.h"
#include "rocksdb/status.h"
#include "storage/redis_metadata.h"
#include "types/redis_zset.h"
namespace redis {
rocksdb::Status Disk::GetApproximateSizes(const Metadata &metadata, const Slice &ns_key,
rocksdb::ColumnFamilyHandle *column_family, uint64_t *key_size,
Slice subkeyleft, Slice subkeyright) {
std::string prefix_key = InternalKey(ns_key, subkeyleft, metadata.version, storage_->IsSlotIdEncoded()).Encode();
std::string next_version_prefix_key =
InternalKey(ns_key, subkeyright, metadata.version + 1, storage_->IsSlotIdEncoded()).Encode();
auto key_range = rocksdb::Range(prefix_key, next_version_prefix_key);
uint64_t tmp_size = 0;
rocksdb::Status s = storage_->GetDB()->GetApproximateSizes(option_, column_family, &key_range, 1, &tmp_size);
if (!s.ok()) return s;
*key_size += tmp_size;
return rocksdb::Status::OK();
}
rocksdb::Status Disk::GetKeySize(engine::Context &ctx, const Slice &user_key, RedisType type, uint64_t *key_size) {
*key_size = 0;
std::string ns_key = AppendNamespacePrefix(user_key);
switch (type) {
case RedisType::kRedisString:
return GetStringSize(ns_key, key_size);
case RedisType::kRedisHash:
return GetHashSize(ctx, ns_key, key_size);
case RedisType::kRedisBitmap:
return GetBitmapSize(ctx, ns_key, key_size);
case RedisType::kRedisList:
return GetListSize(ctx, ns_key, key_size);
case RedisType::kRedisSet:
return GetSetSize(ctx, ns_key, key_size);
case RedisType::kRedisSortedint:
return GetSortedintSize(ctx, ns_key, key_size);
case RedisType::kRedisZSet:
return GetZsetSize(ctx, ns_key, key_size);
case RedisType::kRedisStream:
return GetStreamSize(ctx, ns_key, key_size);
default:
return rocksdb::Status::NotFound("Not found ", user_key);
}
}
rocksdb::Status Disk::GetStringSize(const Slice &ns_key, uint64_t *key_size) {
auto limit = ns_key.ToString() + static_cast<char>(0);
auto key_range = rocksdb::Range(Slice(ns_key), Slice(limit));
return storage_->GetDB()->GetApproximateSizes(option_, metadata_cf_handle_, &key_range, 1, key_size);
}
rocksdb::Status Disk::GetHashSize(engine::Context &ctx, const Slice &ns_key, uint64_t *key_size) {
HashMetadata metadata(false);
rocksdb::Status s = Database::GetMetadata(ctx, {kRedisHash}, ns_key, &metadata);
if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
return GetApproximateSizes(metadata, ns_key, storage_->GetCFHandle(ColumnFamilyID::PrimarySubkey), key_size);
}
rocksdb::Status Disk::GetSetSize(engine::Context &ctx, const Slice &ns_key, uint64_t *key_size) {
SetMetadata metadata(false);
rocksdb::Status s = Database::GetMetadata(ctx, {kRedisSet}, ns_key, &metadata);
if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
return GetApproximateSizes(metadata, ns_key, storage_->GetCFHandle(ColumnFamilyID::PrimarySubkey), key_size);
}
rocksdb::Status Disk::GetListSize(engine::Context &ctx, const Slice &ns_key, uint64_t *key_size) {
ListMetadata metadata(false);
rocksdb::Status s = Database::GetMetadata(ctx, {kRedisList}, ns_key, &metadata);
if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
std::string buf;
PutFixed64(&buf, metadata.head);
return GetApproximateSizes(metadata, ns_key, storage_->GetCFHandle(ColumnFamilyID::PrimarySubkey), key_size, buf);
}
rocksdb::Status Disk::GetZsetSize(engine::Context &ctx, const Slice &ns_key, uint64_t *key_size) {
ZSetMetadata metadata(false);
rocksdb::Status s = Database::GetMetadata(ctx, {kRedisZSet}, ns_key, &metadata);
if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
std::string score_bytes;
PutDouble(&score_bytes, kMinScore);
s = GetApproximateSizes(metadata, ns_key, storage_->GetCFHandle(ColumnFamilyID::SecondarySubkey), key_size,
score_bytes, score_bytes);
if (!s.ok()) return s;
return GetApproximateSizes(metadata, ns_key, storage_->GetCFHandle(ColumnFamilyID::PrimarySubkey), key_size);
}
rocksdb::Status Disk::GetBitmapSize(engine::Context &ctx, const Slice &ns_key, uint64_t *key_size) {
BitmapMetadata metadata(false);
rocksdb::Status s = Database::GetMetadata(ctx, {kRedisBitmap}, ns_key, &metadata);
if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
return GetApproximateSizes(metadata, ns_key, storage_->GetCFHandle(ColumnFamilyID::PrimarySubkey), key_size,
std::to_string(0), std::to_string(0));
}
rocksdb::Status Disk::GetSortedintSize(engine::Context &ctx, const Slice &ns_key, uint64_t *key_size) {
SortedintMetadata metadata(false);
rocksdb::Status s = Database::GetMetadata(ctx, {kRedisSortedint}, ns_key, &metadata);
if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
std::string start_buf;
PutFixed64(&start_buf, 0);
return GetApproximateSizes(metadata, ns_key, storage_->GetCFHandle(ColumnFamilyID::PrimarySubkey), key_size,
start_buf, start_buf);
}
rocksdb::Status Disk::GetStreamSize(engine::Context &ctx, const Slice &ns_key, uint64_t *key_size) {
StreamMetadata metadata(false);
rocksdb::Status s = Database::GetMetadata(ctx, {kRedisStream}, ns_key, &metadata);
if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
return GetApproximateSizes(metadata, ns_key, storage_->GetCFHandle(ColumnFamilyID::Stream), key_size);
}
} // namespace redis