This is an automated email from the ASF dual-hosted git repository.

twice pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new b5233c0e Return string instead of output pointer in metadata (#1671)
b5233c0e is described below

commit b5233c0e9a078316bd8c4b508c855819dde695a0
Author: Twice <[email protected]>
AuthorDate: Sun Aug 13 07:28:41 2023 +0800

    Return string instead of output pointer in metadata (#1671)
---
 src/cluster/redis_slot.cc      |   4 +-
 src/cluster/redis_slot.h       |   4 +-
 src/cluster/slot_migrate.cc    |  17 ++----
 src/commands/cmd_server.cc     |   3 +-
 src/common/db_util.h           |  12 ++++
 src/stats/disk_stats.cc        |   9 ++-
 src/storage/batch_extractor.cc |   4 +-
 src/storage/compact_filter.cc  |   9 ++-
 src/storage/redis_db.cc        |  85 ++++++++++++---------------
 src/storage/redis_db.h         |   2 +-
 src/storage/redis_metadata.cc  |  50 +++++++++-------
 src/storage/redis_metadata.h   |   9 +--
 src/storage/storage.cc         |   4 +-
 src/types/redis_bitmap.cc      |  68 +++++++++++-----------
 src/types/redis_geo.cc         |   3 +-
 src/types/redis_hash.cc        |  62 ++++++++------------
 src/types/redis_list.cc        | 105 ++++++++++++++--------------------
 src/types/redis_set.cc         |  45 ++++++---------
 src/types/redis_sortedint.cc   |  46 +++++++--------
 src/types/redis_stream.cc      |  55 +++++++-----------
 src/types/redis_string.cc      |  48 ++++++----------
 src/types/redis_zset.cc        | 127 ++++++++++++++++++-----------------------
 tests/cppunit/compact_test.cc  |   5 +-
 tests/cppunit/metadata_test.cc |  10 +---
 utils/kvrocks2redis/parser.cc  |  12 ++--
 25 files changed, 353 insertions(+), 445 deletions(-)

diff --git a/src/cluster/redis_slot.cc b/src/cluster/redis_slot.cc
index 3843eb0f..0523f782 100644
--- a/src/cluster/redis_slot.cc
+++ b/src/cluster/redis_slot.cc
@@ -53,7 +53,7 @@ uint16_t Crc16(const char *buf, size_t len) {
   return crc;
 }
 
-uint16_t GetSlotIdFromKey(const std::string &key) {
+uint16_t GetSlotIdFromKey(std::string_view key) {
   auto tag = GetTagFromKey(key);
   if (tag.empty()) {
     tag = key;
@@ -63,7 +63,7 @@ uint16_t GetSlotIdFromKey(const std::string &key) {
   return crc & HASH_SLOTS_MASK;
 }
 
-std::string GetTagFromKey(const std::string &key) {
+std::string_view GetTagFromKey(std::string_view key) {
   auto left_pos = key.find('{');
   if (left_pos == std::string::npos) return {};
 
diff --git a/src/cluster/redis_slot.h b/src/cluster/redis_slot.h
index 297fd7c3..0cdf174c 100644
--- a/src/cluster/redis_slot.h
+++ b/src/cluster/redis_slot.h
@@ -28,5 +28,5 @@ constexpr const uint16_t HASH_SLOTS_SIZE = HASH_SLOTS_MASK + 
1;  // 16384
 constexpr const uint16_t HASH_SLOTS_MAX_ITERATIONS = 50;
 
 uint16_t Crc16(const char *buf, size_t len);
-uint16_t GetSlotIdFromKey(const std::string &key);
-std::string GetTagFromKey(const std::string &key);
+uint16_t GetSlotIdFromKey(std::string_view key);
+std::string_view GetTagFromKey(std::string_view key);
diff --git a/src/cluster/slot_migrate.cc b/src/cluster/slot_migrate.cc
index 7f08f85a..307c426f 100644
--- a/src/cluster/slot_migrate.cc
+++ b/src/cluster/slot_migrate.cc
@@ -313,8 +313,7 @@ Status SlotMigrator::sendSnapshot() {
   auto iter = 
util::UniqueIterator(storage_->GetDB()->NewIterator(read_options, cf_handle));
 
   // Construct key prefix to iterate the keys belong to the target slot
-  std::string prefix;
-  ComposeSlotKeyPrefix(namespace_, slot, &prefix);
+  std::string prefix = ComposeSlotKeyPrefix(namespace_, slot);
   LOG(INFO) << "[migrate] Iterate keys of slot, key's prefix: " << prefix;
 
   // Seek to the beginning of keys start with 'prefix' and iterate all these 
keys
@@ -331,8 +330,7 @@ Status SlotMigrator::sendSnapshot() {
     }
 
     // Get user key
-    std::string ns, user_key;
-    ExtractNamespaceKey(iter->key(), &ns, &user_key, true);
+    auto [_, user_key] = ExtractNamespaceKey(iter->key(), true);
 
     // Add key's constructed commands to restore_cmds, send pipeline or not 
according to task's max_pipeline_size
     auto result = migrateOneKey(user_key, iter->value(), &restore_cmds);
@@ -665,9 +663,8 @@ Status SlotMigrator::migrateComplexKey(const rocksdb::Slice 
&key, const Metadata
   auto iter = 
util::UniqueIterator(storage_->GetDB()->NewIterator(read_options));
 
   // Construct key prefix to iterate values of the complex type user key
-  std::string slot_key, prefix_subkey;
-  AppendNamespacePrefix(key, &slot_key);
-  InternalKey(slot_key, "", metadata.version, true).Encode(&prefix_subkey);
+  std::string slot_key = AppendNamespacePrefix(key);
+  std::string prefix_subkey = InternalKey(slot_key, "", metadata.version, 
true).Encode();
   int item_count = 0;
 
   for (iter->Seek(prefix_subkey); iter->Valid(); iter->Next()) {
@@ -766,11 +763,9 @@ Status SlotMigrator::migrateStream(const Slice &key, const 
StreamMetadata &metad
   auto iter = util::UniqueIterator(
       storage_->GetDB()->NewIterator(read_options, 
storage_->GetCFHandle(engine::kStreamColumnFamilyName)));
 
-  std::string ns_key;
-  AppendNamespacePrefix(key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(key);
   // Construct key prefix to iterate values of the stream
-  std::string prefix_key;
-  InternalKey(ns_key, "", metadata.version, true).Encode(&prefix_key);
+  std::string prefix_key = InternalKey(ns_key, "", metadata.version, 
true).Encode();
 
   std::vector<std::string> user_cmd = {type_to_cmd[metadata.Type()], 
key.ToString()};
 
diff --git a/src/commands/cmd_server.cc b/src/commands/cmd_server.cc
index e8545c49..95dd0086 100644
--- a/src/commands/cmd_server.cc
+++ b/src/commands/cmd_server.cc
@@ -814,8 +814,7 @@ class CommandCompact : public Commander {
     auto ns = conn->GetNamespace();
 
     if (ns != kDefaultNamespace) {
-      std::string prefix;
-      ComposeNamespaceKey(ns, "", &prefix, false);
+      std::string prefix = ComposeNamespaceKey(ns, "", false);
 
       redis::Database redis_db(svr->storage, conn->GetNamespace());
       auto s = redis_db.FindKeyRangeWithPrefix(prefix, std::string(), 
&begin_key, &end_key);
diff --git a/src/common/db_util.h b/src/common/db_util.h
index e394a9f6..788c9685 100644
--- a/src/common/db_util.h
+++ b/src/common/db_util.h
@@ -22,6 +22,7 @@
 
 #include <memory>
 
+#include "fmt/ostream.h"
 #include "rocksdb/db.h"
 #include "rocksdb/iterator.h"
 #include "rocksdb/utilities/backup_engine.h"
@@ -103,3 +104,14 @@ inline StatusOr<std::unique_ptr<rocksdb::BackupEngine>> 
BackupEngineOpen(rocksdb
 }
 
 }  // namespace util
+
+namespace rocksdb {
+
+inline std::ostream& operator<<(std::ostream& os, const Slice& slice) {
+  return os << std::string_view{slice.data(), slice.size()};
+}
+
+}  // namespace rocksdb
+
+template <>
+struct fmt::formatter<rocksdb::Slice> : fmt::ostream_formatter {};
diff --git a/src/stats/disk_stats.cc b/src/stats/disk_stats.cc
index 73032f7e..a5e946eb 100644
--- a/src/stats/disk_stats.cc
+++ b/src/stats/disk_stats.cc
@@ -33,9 +33,9 @@ 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, next_version_prefix_key;
-  InternalKey(ns_key, subkeyleft, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, subkeyright, metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  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);
@@ -46,8 +46,7 @@ rocksdb::Status Disk::GetApproximateSizes(const Metadata 
&metadata, const Slice
 
 rocksdb::Status Disk::GetKeySize(const Slice &user_key, RedisType type, 
uint64_t *key_size) {
   *key_size = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   switch (type) {
     case RedisType::kRedisString:
       return GetStringSize(ns_key, key_size);
diff --git a/src/storage/batch_extractor.cc b/src/storage/batch_extractor.cc
index 16f02bbc..7430e1ce 100644
--- a/src/storage/batch_extractor.cc
+++ b/src/storage/batch_extractor.cc
@@ -52,7 +52,7 @@ rocksdb::Status WriteBatchExtractor::PutCF(uint32_t 
column_family_id, const Slic
   std::vector<std::string> command_args;
 
   if (column_family_id == kColumnFamilyIDMetadata) {
-    ExtractNamespaceKey(key, &ns, &user_key, is_slot_id_encoded_);
+    std::tie(ns, user_key) = ExtractNamespaceKey<std::string>(key, 
is_slot_id_encoded_);
     if (slot_id_ >= 0 && static_cast<uint16_t>(slot_id_) != 
GetSlotIdFromKey(user_key)) {
       return rocksdb::Status::OK();
     }
@@ -272,7 +272,7 @@ rocksdb::Status WriteBatchExtractor::DeleteCF(uint32_t 
column_family_id, const S
 
   if (column_family_id == kColumnFamilyIDMetadata) {
     std::string user_key;
-    ExtractNamespaceKey(key, &ns, &user_key, is_slot_id_encoded_);
+    std::tie(ns, user_key) = ExtractNamespaceKey<std::string>(key, 
is_slot_id_encoded_);
 
     if (slot_id_ >= 0 && static_cast<uint16_t>(slot_id_) != 
GetSlotIdFromKey(user_key)) {
       return rocksdb::Status::OK();
diff --git a/src/storage/compact_filter.cc b/src/storage/compact_filter.cc
index 984c618b..d7888089 100644
--- a/src/storage/compact_filter.cc
+++ b/src/storage/compact_filter.cc
@@ -25,6 +25,7 @@
 #include <string>
 #include <utility>
 
+#include "db_util.h"
 #include "time_util.h"
 #include "types/redis_bitmap.h"
 
@@ -34,10 +35,10 @@ using rocksdb::Slice;
 
 bool MetadataFilter::Filter(int level, const Slice &key, const Slice &value, 
std::string *new_value,
                             bool *modified) const {
-  std::string ns, user_key, bytes = value.ToString();
+  std::string bytes = value.ToString();
   Metadata metadata(kRedisNone, false);
   rocksdb::Status s = metadata.Decode(bytes);
-  ExtractNamespaceKey(key, &ns, &user_key, stor_->IsSlotIdEncoded());
+  auto [ns, user_key] = ExtractNamespaceKey(key, stor_->IsSlotIdEncoded());
   if (!s.ok()) {
     LOG(WARNING) << "[compact_filter/metadata] Failed to decode,"
                  << ", namespace: " << ns << ", key: " << user_key << ", err: 
" << s.ToString();
@@ -50,13 +51,11 @@ bool MetadataFilter::Filter(int level, const Slice &key, 
const Slice &value, std
 }
 
 Status SubKeyFilter::GetMetadata(const InternalKey &ikey, Metadata *metadata) 
const {
-  std::string metadata_key;
-
   auto db = stor_->GetDB();
   const auto cf_handles = stor_->GetCFHandles();
   // storage close the would delete the column family handler and DB
   if (!db || cf_handles->size() < 2) return {Status::NotOK, "storage is 
closed"};
-  ComposeNamespaceKey(ikey.GetNamespace(), ikey.GetKey(), &metadata_key, 
stor_->IsSlotIdEncoded());
+  std::string metadata_key = ComposeNamespaceKey(ikey.GetNamespace(), 
ikey.GetKey(), stor_->IsSlotIdEncoded());
 
   if (cached_key_.empty() || metadata_key != cached_key_) {
     std::string bytes;
diff --git a/src/storage/redis_db.cc b/src/storage/redis_db.cc
index 27f9e847..14d6a352 100644
--- a/src/storage/redis_db.cc
+++ b/src/storage/redis_db.cc
@@ -70,14 +70,12 @@ rocksdb::Status Database::GetRawMetadata(const Slice 
&ns_key, std::string *bytes
 }
 
 rocksdb::Status Database::GetRawMetadataByUserKey(const Slice &user_key, 
std::string *bytes) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   return GetRawMetadata(ns_key, bytes);
 }
 
 rocksdb::Status Database::Expire(const Slice &user_key, uint64_t timestamp) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   std::string value;
   Metadata metadata(kRedisNone, false);
@@ -108,8 +106,7 @@ rocksdb::Status Database::Expire(const Slice &user_key, 
uint64_t timestamp) {
 }
 
 rocksdb::Status Database::Del(const Slice &user_key) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   std::string value;
   LockGuard guard(storage_->GetLockManager(), ns_key);
@@ -130,9 +127,9 @@ rocksdb::Status Database::Exists(const std::vector<Slice> 
&keys, int *ret) {
   read_options.snapshot = ss.GetSnapShot();
 
   rocksdb::Status s;
-  std::string ns_key, value;
+  std::string value;
   for (const auto &key : keys) {
-    AppendNamespacePrefix(key, &ns_key);
+    std::string ns_key = AppendNamespacePrefix(key);
     s = storage_->Get(read_options, metadata_cf_handle_, ns_key, &value);
     if (s.ok()) {
       Metadata metadata(kRedisNone, false);
@@ -144,8 +141,7 @@ rocksdb::Status Database::Exists(const std::vector<Slice> 
&keys, int *ret) {
 }
 
 rocksdb::Status Database::TTL(const Slice &user_key, int64_t *ttl) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   *ttl = -2;  // ttl is -2 when the key does not exist or expired
   LatestSnapShot ss(storage_);
@@ -166,16 +162,16 @@ void Database::GetKeyNumStats(const std::string &prefix, 
KeyNumStats *stats) { K
 
 void Database::Keys(const std::string &prefix, std::vector<std::string> *keys, 
KeyNumStats *stats) {
   uint16_t slot_id = 0;
-  std::string ns_prefix, ns, user_key, value;
+  std::string ns_prefix, value;
   if (namespace_ != kDefaultNamespace || keys != nullptr) {
     if (storage_->IsSlotIdEncoded()) {
-      ComposeNamespaceKey(namespace_, "", &ns_prefix, false);
+      ns_prefix = ComposeNamespaceKey(namespace_, "", false);
       if (!prefix.empty()) {
         PutFixed16(&ns_prefix, slot_id);
         ns_prefix.append(prefix);
       }
     } else {
-      AppendNamespacePrefix(prefix, &ns_prefix);
+      ns_prefix = AppendNamespacePrefix(prefix);
     }
   }
 
@@ -207,8 +203,8 @@ void Database::Keys(const std::string &prefix, 
std::vector<std::string> *keys, K
         }
       }
       if (keys) {
-        ExtractNamespaceKey(iter->key(), &ns, &user_key, 
storage_->IsSlotIdEncoded());
-        keys->emplace_back(user_key);
+        auto [_, user_key] = ExtractNamespaceKey(iter->key(), 
storage_->IsSlotIdEncoded());
+        keys->emplace_back(user_key.ToString());
       }
     }
 
@@ -216,7 +212,7 @@ void Database::Keys(const std::string &prefix, 
std::vector<std::string> *keys, K
     if (prefix.empty()) break;
     if (++slot_id >= HASH_SLOTS_SIZE) break;
 
-    ComposeNamespaceKey(namespace_, "", &ns_prefix, false);
+    ns_prefix = ComposeNamespaceKey(namespace_, "", false);
     PutFixed16(&ns_prefix, slot_id);
     ns_prefix.append(prefix);
   }
@@ -231,23 +227,24 @@ rocksdb::Status Database::Scan(const std::string &cursor, 
uint64_t limit, const
   end_cursor->clear();
   uint64_t cnt = 0;
   uint16_t slot_start = 0;
-  std::string ns_prefix, ns_cursor, ns, user_key, value, index_key;
+  std::string ns_prefix;
+  std::string user_key;
 
   LatestSnapShot ss(storage_);
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   read_options.snapshot = ss.GetSnapShot();
   auto iter = util::UniqueIterator(storage_, read_options, 
metadata_cf_handle_);
 
-  AppendNamespacePrefix(cursor, &ns_cursor);
+  std::string ns_cursor = AppendNamespacePrefix(cursor);
   if (storage_->IsSlotIdEncoded()) {
     slot_start = cursor.empty() ? 0 : GetSlotIdFromKey(cursor);
-    ComposeNamespaceKey(namespace_, "", &ns_prefix, false);
+    ns_prefix = ComposeNamespaceKey(namespace_, "", false);
     if (!prefix.empty()) {
       PutFixed16(&ns_prefix, slot_start);
       ns_prefix.append(prefix);
     }
   } else {
-    AppendNamespacePrefix(prefix, &ns_prefix);
+    ns_prefix = AppendNamespacePrefix(prefix);
   }
 
   if (!cursor.empty()) {
@@ -268,10 +265,10 @@ rocksdb::Status Database::Scan(const std::string &cursor, 
uint64_t limit, const
         break;
       }
       Metadata metadata(kRedisNone, false);
-      value = iter->value().ToString();
+      std::string value = iter->value().ToString();
       metadata.Decode(value);
       if (metadata.Expired()) continue;
-      ExtractNamespaceKey(iter->key(), &ns, &user_key, 
storage_->IsSlotIdEncoded());
+      std::tie(std::ignore, user_key) = 
ExtractNamespaceKey<std::string>(iter->key(), storage_->IsSlotIdEncoded());
       keys->emplace_back(user_key);
       cnt++;
     }
@@ -294,7 +291,7 @@ rocksdb::Status Database::Scan(const std::string &cursor, 
uint64_t limit, const
     if (slot_id > slot_start + HASH_SLOTS_MAX_ITERATIONS) {
       if (keys->empty()) {
         if (iter->Valid()) {
-          ExtractNamespaceKey(iter->key(), &ns, &user_key, 
storage_->IsSlotIdEncoded());
+          std::tie(std::ignore, user_key) = 
ExtractNamespaceKey<std::string>(iter->key(), storage_->IsSlotIdEncoded());
           auto res = std::mismatch(prefix.begin(), prefix.end(), 
user_key.begin());
           if (res.first == prefix.end()) {
             keys->emplace_back(user_key);
@@ -308,7 +305,7 @@ rocksdb::Status Database::Scan(const std::string &cursor, 
uint64_t limit, const
       break;
     }
 
-    ComposeNamespaceKey(namespace_, "", &ns_prefix, false);
+    ns_prefix = ComposeNamespaceKey(namespace_, "", false);
     PutFixed16(&ns_prefix, slot_id);
     ns_prefix.append(prefix);
     iter->Seek(ns_prefix);
@@ -340,8 +337,8 @@ rocksdb::Status Database::RandomKey(const std::string 
&cursor, std::string *key)
 }
 
 rocksdb::Status Database::FlushDB() {
-  std::string prefix, begin_key, end_key;
-  ComposeNamespaceKey(namespace_, "", &prefix, false);
+  std::string begin_key, end_key;
+  std::string prefix = ComposeNamespaceKey(namespace_, "", false);
   auto s = FindKeyRangeWithPrefix(prefix, std::string(), &begin_key, &end_key);
   if (!s.ok()) {
     return rocksdb::Status::OK();
@@ -379,8 +376,7 @@ rocksdb::Status Database::FlushAll() {
 rocksdb::Status Database::Dump(const Slice &user_key, std::vector<std::string> 
*infos) {
   infos->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LatestSnapShot ss(storage_);
   rocksdb::ReadOptions read_options;
@@ -431,8 +427,7 @@ rocksdb::Status Database::Dump(const Slice &user_key, 
std::vector<std::string> *
 }
 
 rocksdb::Status Database::Type(const Slice &user_key, RedisType *type) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   *type = kRedisNone;
   LatestSnapShot ss(storage_);
@@ -452,8 +447,8 @@ rocksdb::Status Database::Type(const Slice &user_key, 
RedisType *type) {
   return rocksdb::Status::OK();
 }
 
-void Database::AppendNamespacePrefix(const Slice &user_key, std::string 
*output) {
-  ComposeNamespaceKey(namespace_, user_key, output, 
storage_->IsSlotIdEncoded());
+std::string Database::AppendNamespacePrefix(const Slice &user_key) {
+  return ComposeNamespaceKey(namespace_, user_key, 
storage_->IsSlotIdEncoded());
 }
 
 rocksdb::Status Database::FindKeyRangeWithPrefix(const std::string &prefix, 
const std::string &prefix_end,
@@ -509,9 +504,8 @@ rocksdb::Status Database::ClearKeysOfSlot(const 
rocksdb::Slice &ns, int slot) {
     return rocksdb::Status::Aborted("It is not in cluster mode");
   }
 
-  std::string prefix, prefix_end;
-  ComposeSlotKeyPrefix(ns, slot, &prefix);
-  ComposeSlotKeyPrefix(ns, slot + 1, &prefix_end);
+  std::string prefix = ComposeSlotKeyPrefix(ns, slot);
+  std::string prefix_end = ComposeSlotKeyPrefix(ns, slot + 1);
   auto s = storage_->DeleteRange(prefix, prefix_end);
   if (!s.ok()) {
     return s;
@@ -528,8 +522,7 @@ rocksdb::Status Database::GetSlotKeysInfo(int slot, 
std::map<int, uint64_t> *slo
   auto iter = util::UniqueIterator(storage_, read_options, 
metadata_cf_handle_);
   bool end = false;
   for (int i = 0; i < HASH_SLOTS_SIZE; i++) {
-    std::string prefix;
-    ComposeSlotKeyPrefix(namespace_, i, &prefix);
+    std::string prefix = ComposeSlotKeyPrefix(namespace_, i);
     uint64_t total = 0;
     int cnt = 0;
     if (slot != -1 && i != slot) {
@@ -544,9 +537,8 @@ rocksdb::Status Database::GetSlotKeysInfo(int slot, 
std::map<int, uint64_t> *slo
       if (slot != -1 && count > 0 && !end) {
         // Get user key
         if (cnt < count) {
-          std::string ns, user_key;
-          ExtractNamespaceKey(iter->key(), &ns, &user_key, true);
-          keys->push_back(user_key);
+          auto [_, user_key] = ExtractNamespaceKey(iter->key(), true);
+          keys->emplace_back(user_key.ToString());
           cnt++;
         }
       }
@@ -562,8 +554,7 @@ rocksdb::Status SubKeyScanner::Scan(RedisType type, const 
Slice &user_key, const
                                     const std::string &subkey_prefix, 
std::vector<std::string> *keys,
                                     std::vector<std::string> *values) {
   uint64_t cnt = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   Metadata metadata(type, false);
   rocksdb::Status s = GetMetadata(type, ns_key, &metadata);
   if (!s.ok()) return s;
@@ -572,16 +563,12 @@ rocksdb::Status SubKeyScanner::Scan(RedisType type, const 
Slice &user_key, const
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   read_options.snapshot = ss.GetSnapShot();
   auto iter = util::UniqueIterator(storage_, read_options);
-  std::string match_prefix_key;
-  if (!subkey_prefix.empty()) {
-    InternalKey(ns_key, subkey_prefix, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&match_prefix_key);
-  } else {
-    InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&match_prefix_key);
-  }
+  std::string match_prefix_key =
+      InternalKey(ns_key, subkey_prefix, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
 
   std::string start_key;
   if (!cursor.empty()) {
-    InternalKey(ns_key, cursor, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
+    start_key = InternalKey(ns_key, cursor, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   } else {
     start_key = match_prefix_key;
   }
diff --git a/src/storage/redis_db.h b/src/storage/redis_db.h
index cbe10192..51adc6cd 100644
--- a/src/storage/redis_db.h
+++ b/src/storage/redis_db.h
@@ -50,7 +50,7 @@ class Database {
   rocksdb::Status Scan(const std::string &cursor, uint64_t limit, const 
std::string &prefix,
                        std::vector<std::string> *keys, std::string *end_cursor 
= nullptr);
   rocksdb::Status RandomKey(const std::string &cursor, std::string *key);
-  void AppendNamespacePrefix(const Slice &user_key, std::string *output);
+  std::string AppendNamespacePrefix(const Slice &user_key);
   rocksdb::Status FindKeyRangeWithPrefix(const std::string &prefix, const 
std::string &prefix_end, std::string *begin,
                                          std::string *end, 
rocksdb::ColumnFamilyHandle *cf_handle = nullptr);
   rocksdb::Status ClearKeysOfSlot(const rocksdb::Slice &ns, int slot);
diff --git a/src/storage/redis_metadata.cc b/src/storage/redis_metadata.cc
index 125f3081..4c6b6c5c 100644
--- a/src/storage/redis_metadata.cc
+++ b/src/storage/redis_metadata.cc
@@ -56,7 +56,7 @@ InternalKey::InternalKey(Slice input, bool slot_id_encoded) : 
slot_id_encoded_(s
 }
 
 InternalKey::InternalKey(Slice ns_key, Slice sub_key, uint64_t version, bool 
slot_id_encoded)
-    : slot_id_encoded_(slot_id_encoded) {
+    : sub_key_(sub_key), version_(version), slot_id_encoded_(slot_id_encoded) {
   uint8_t namespace_size = 0;
   GetFixed8(&ns_key, &namespace_size);
   namespace_ = Slice(ns_key.data(), namespace_size);
@@ -65,8 +65,6 @@ InternalKey::InternalKey(Slice ns_key, Slice sub_key, 
uint64_t version, bool slo
     GetFixed16(&ns_key, &slotid_);
   }
   key_ = ns_key;
-  sub_key_ = sub_key;
-  version_ = version;
 }
 
 Slice InternalKey::GetNamespace() const { return namespace_; }
@@ -77,15 +75,15 @@ Slice InternalKey::GetSubKey() const { return sub_key_; }
 
 uint64_t InternalKey::GetVersion() const { return version_; }
 
-void InternalKey::Encode(std::string *out) {
-  out->clear();
+std::string InternalKey::Encode() const {
+  std::string out;
   size_t pos = 0;
   size_t total = 1 + namespace_.size() + 4 + key_.size() + 8 + sub_key_.size();
   if (slot_id_encoded_) {
     total += 2;
   }
-  out->resize(total);
-  auto buf = out->data();
+  out.resize(total);
+  auto buf = out.data();
   EncodeFixed8(buf + pos, static_cast<uint8_t>(namespace_.size()));
   pos += 1;
   memcpy(buf + pos, namespace_.data(), namespace_.size());
@@ -102,6 +100,7 @@ void InternalKey::Encode(std::string *out) {
   pos += 8;
   memcpy(buf + pos, sub_key_.data(), sub_key_.size());
   // pos += sub_key_.size();
+  return out;
 }
 
 bool InternalKey::operator==(const InternalKey &that) const {
@@ -110,10 +109,11 @@ bool InternalKey::operator==(const InternalKey &that) 
const {
   return version_ == that.version_;
 }
 
-void ExtractNamespaceKey(Slice ns_key, std::string *ns, std::string *key, bool 
slot_id_encoded) {
+template <typename T>
+std::tuple<T, T> ExtractNamespaceKey(Slice ns_key, bool slot_id_encoded) {
   uint8_t namespace_size = 0;
   GetFixed8(&ns_key, &namespace_size);
-  *ns = ns_key.ToString().substr(0, namespace_size);
+  T ns(ns_key.data(), namespace_size);
   ns_key.remove_prefix(namespace_size);
 
   if (slot_id_encoded) {
@@ -121,30 +121,38 @@ void ExtractNamespaceKey(Slice ns_key, std::string *ns, 
std::string *key, bool s
     GetFixed16(&ns_key, &slot_id);
   }
 
-  *key = ns_key.ToString();
+  T key = {ns_key.data(), ns_key.size()};
+  return {ns, key};
 }
 
-void ComposeNamespaceKey(const Slice &ns, const Slice &key, std::string 
*ns_key, bool slot_id_encoded) {
-  ns_key->clear();
+template std::tuple<Slice, Slice> ExtractNamespaceKey<Slice>(Slice ns_key, 
bool slot_id_encoded);
+template std::tuple<std::string, std::string> 
ExtractNamespaceKey<std::string>(Slice ns_key, bool slot_id_encoded);
 
-  PutFixed8(ns_key, static_cast<uint8_t>(ns.size()));
-  ns_key->append(ns.data(), ns.size());
+std::string ComposeNamespaceKey(const Slice &ns, const Slice &key, bool 
slot_id_encoded) {
+  std::string ns_key;
+
+  PutFixed8(&ns_key, static_cast<uint8_t>(ns.size()));
+  ns_key.append(ns.data(), ns.size());
 
   if (slot_id_encoded) {
     auto slot_id = GetSlotIdFromKey(key.ToString());
-    PutFixed16(ns_key, slot_id);
+    PutFixed16(&ns_key, slot_id);
   }
 
-  ns_key->append(key.data(), key.size());
+  ns_key.append(key.data(), key.size());
+
+  return ns_key;
 }
 
-void ComposeSlotKeyPrefix(const Slice &ns, int slotid, std::string *output) {
-  output->clear();
+std::string ComposeSlotKeyPrefix(const Slice &ns, int slotid) {
+  std::string output;
+
+  PutFixed8(&output, static_cast<uint8_t>(ns.size()));
+  output.append(ns.data(), ns.size());
 
-  PutFixed8(output, static_cast<uint8_t>(ns.size()));
-  output->append(ns.data(), ns.size());
+  PutFixed16(&output, static_cast<uint16_t>(slotid));
 
-  PutFixed16(output, static_cast<uint16_t>(slotid));
+  return output;
 }
 
 Metadata::Metadata(RedisType type, bool generate_version, bool 
use_64bit_common_field)
diff --git a/src/storage/redis_metadata.h b/src/storage/redis_metadata.h
index 5407ff80..5f6d6848 100644
--- a/src/storage/redis_metadata.h
+++ b/src/storage/redis_metadata.h
@@ -73,9 +73,10 @@ struct KeyNumStats {
   uint64_t avg_ttl = 0;
 };
 
-void ExtractNamespaceKey(Slice ns_key, std::string *ns, std::string *key, bool 
slot_id_encoded);
-void ComposeNamespaceKey(const Slice &ns, const Slice &key, std::string 
*ns_key, bool slot_id_encoded);
-void ComposeSlotKeyPrefix(const Slice &ns, int slotid, std::string *output);
+template <typename T = Slice>
+[[nodiscard]] std::tuple<T, T> ExtractNamespaceKey(Slice ns_key, bool 
slot_id_encoded);
+[[nodiscard]] std::string ComposeNamespaceKey(const Slice &ns, const Slice 
&key, bool slot_id_encoded);
+[[nodiscard]] std::string ComposeSlotKeyPrefix(const Slice &ns, int slotid);
 
 class InternalKey {
  public:
@@ -87,7 +88,7 @@ class InternalKey {
   Slice GetKey() const;
   Slice GetSubKey() const;
   uint64_t GetVersion() const;
-  void Encode(std::string *out);
+  [[nodiscard]] std::string Encode() const;
   bool operator==(const InternalKey &that) const;
 
  private:
diff --git a/src/storage/storage.cc b/src/storage/storage.cc
index 4e06743a..d566da10 100644
--- a/src/storage/storage.cc
+++ b/src/storage/storage.cc
@@ -655,8 +655,8 @@ uint64_t Storage::GetTotalSize(const std::string &ns) {
     return sst_file_manager_->GetTotalSize();
   }
 
-  std::string prefix, begin_key, end_key;
-  ComposeNamespaceKey(ns, "", &prefix, false);
+  std::string begin_key, end_key;
+  std::string prefix = ComposeNamespaceKey(ns, "", false);
 
   redis::Database db(this, ns);
   uint64_t size = 0, total_size = 0;
diff --git a/src/types/redis_bitmap.cc b/src/types/redis_bitmap.cc
index 14ac636f..19db2209 100644
--- a/src/types/redis_bitmap.cc
+++ b/src/types/redis_bitmap.cc
@@ -63,8 +63,8 @@ rocksdb::Status Bitmap::GetMetadata(const Slice &ns_key, 
BitmapMetadata *metadat
 
 rocksdb::Status Bitmap::GetBit(const Slice &user_key, uint32_t offset, bool 
*bit) {
   *bit = false;
-  std::string ns_key, raw_value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string raw_value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   BitmapMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata, &raw_value);
@@ -79,8 +79,9 @@ rocksdb::Status Bitmap::GetBit(const Slice &user_key, 
uint32_t offset, bool *bit
   rocksdb::ReadOptions read_options;
   read_options.snapshot = ss.GetSnapShot();
   uint32_t index = (offset / kBitmapSegmentBits) * kBitmapSegmentBytes;
-  std::string sub_key, value;
-  InternalKey(ns_key, std::to_string(index), metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+  std::string value;
+  std::string sub_key =
+      InternalKey(ns_key, std::to_string(index), metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   s = storage_->Get(read_options, sub_key, &value);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
   uint32_t byte_index = (offset / 8) % kBitmapSegmentBytes;
@@ -94,8 +95,8 @@ rocksdb::Status Bitmap::GetBit(const Slice &user_key, 
uint32_t offset, bool *bit
 // according to the max size of the bitmap string to prevent OOM.
 rocksdb::Status Bitmap::GetString(const Slice &user_key, const uint32_t 
max_btos_size, std::string *value) {
   value->clear();
-  std::string ns_key, raw_value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string raw_value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   BitmapMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata, &raw_value);
@@ -105,9 +106,9 @@ rocksdb::Status Bitmap::GetString(const Slice &user_key, 
const uint32_t max_btos
   }
   value->assign(metadata.size, 0);
 
-  std::string fragment, prefix_key;
+  std::string fragment;
   fragment.reserve(kBitmapSegmentBytes * 2);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
+  std::string prefix_key = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -162,8 +163,8 @@ rocksdb::Status Bitmap::GetString(const Slice &user_key, 
const uint32_t max_btos
 }
 
 rocksdb::Status Bitmap::SetBit(const Slice &user_key, uint32_t offset, bool 
new_bit, bool *old_bit) {
-  std::string ns_key, raw_value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string raw_value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   BitmapMetadata metadata;
@@ -175,9 +176,10 @@ rocksdb::Status Bitmap::SetBit(const Slice &user_key, 
uint32_t offset, bool new_
     return bitmap_string_db.SetBit(ns_key, &raw_value, offset, new_bit, 
old_bit);
   }
 
-  std::string sub_key, value;
+  std::string value;
   uint32_t index = (offset / kBitmapSegmentBits) * kBitmapSegmentBytes;
-  InternalKey(ns_key, std::to_string(index), metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+  std::string sub_key =
+      InternalKey(ns_key, std::to_string(index), metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   if (s.ok()) {
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value);
     if (!s.ok() && !s.IsNotFound()) return s;
@@ -218,8 +220,8 @@ rocksdb::Status Bitmap::SetBit(const Slice &user_key, 
uint32_t offset, bool new_
 
 rocksdb::Status Bitmap::BitCount(const Slice &user_key, int64_t start, int64_t 
stop, uint32_t *cnt) {
   *cnt = 0;
-  std::string ns_key, raw_value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string raw_value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   BitmapMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata, &raw_value);
@@ -244,10 +246,11 @@ rocksdb::Status Bitmap::BitCount(const Slice &user_key, 
int64_t start, int64_t s
   uint32_t start_index = u_start / kBitmapSegmentBytes;
   uint32_t stop_index = u_stop / kBitmapSegmentBytes;
   // Don't use multi get to prevent large range query, and take too much memory
-  std::string sub_key, value;
+  std::string value;
   for (uint32_t i = start_index; i <= stop_index; i++) {
-    InternalKey(ns_key, std::to_string(i * kBitmapSegmentBytes), 
metadata.version, storage_->IsSlotIdEncoded())
-        .Encode(&sub_key);
+    std::string sub_key =
+        InternalKey(ns_key, std::to_string(i * kBitmapSegmentBytes), 
metadata.version, storage_->IsSlotIdEncoded())
+            .Encode();
     s = storage_->Get(read_options, sub_key, &value);
     if (!s.ok() && !s.IsNotFound()) return s;
     if (s.IsNotFound()) continue;
@@ -262,8 +265,8 @@ rocksdb::Status Bitmap::BitCount(const Slice &user_key, 
int64_t start, int64_t s
 
 rocksdb::Status Bitmap::BitPos(const Slice &user_key, bool bit, int64_t start, 
int64_t stop, bool stop_given,
                                int64_t *pos) {
-  std::string ns_key, raw_value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string raw_value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   BitmapMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata, &raw_value);
@@ -301,10 +304,11 @@ rocksdb::Status Bitmap::BitPos(const Slice &user_key, 
bool bit, int64_t start, i
   uint32_t start_index = u_start / kBitmapSegmentBytes;
   uint32_t stop_index = u_stop / kBitmapSegmentBytes;
   // Don't use multi get to prevent large range query, and take too much memory
-  std::string sub_key, value;
+  std::string value;
   for (uint32_t i = start_index; i <= stop_index; i++) {
-    InternalKey(ns_key, std::to_string(i * kBitmapSegmentBytes), 
metadata.version, storage_->IsSlotIdEncoded())
-        .Encode(&sub_key);
+    std::string sub_key =
+        InternalKey(ns_key, std::to_string(i * kBitmapSegmentBytes), 
metadata.version, storage_->IsSlotIdEncoded())
+            .Encode();
     s = storage_->Get(read_options, sub_key, &value);
     if (!s.ok() && !s.IsNotFound()) return s;
     if (s.IsNotFound()) {
@@ -335,8 +339,8 @@ rocksdb::Status Bitmap::BitPos(const Slice &user_key, bool 
bit, int64_t start, i
 
 rocksdb::Status Bitmap::BitOp(BitOpFlags op_flag, const std::string &op_name, 
const Slice &user_key,
                               const std::vector<Slice> &op_keys, int64_t *len) 
{
-  std::string ns_key, raw_value, ns_op_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string raw_value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
   LockGuard guard(storage_->GetLockManager(), ns_key);
 
   std::vector<std::pair<std::string, BitmapMetadata>> meta_pairs;
@@ -344,7 +348,7 @@ rocksdb::Status Bitmap::BitOp(BitOpFlags op_flag, const 
std::string &op_name, co
 
   for (const auto &op_key : op_keys) {
     BitmapMetadata metadata(false);
-    AppendNamespacePrefix(op_key, &ns_op_key);
+    std::string ns_op_key = AppendNamespacePrefix(op_key);
     auto s = GetMetadata(ns_op_key, &metadata, &raw_value);
     if (!s.ok()) {
       if (s.IsNotFound()) {
@@ -377,7 +381,7 @@ rocksdb::Status Bitmap::BitOp(BitOpFlags op_flag, const 
std::string &op_name, co
     uint64_t frag_numkeys = num_keys, stop_index = (max_size - 1) / 
kBitmapSegmentBytes;
     std::unique_ptr<unsigned char[]> frag_res(new unsigned 
char[kBitmapSegmentBytes]);
     uint16_t frag_maxlen = 0, frag_minlen = 0;
-    std::string sub_key, fragment;
+    std::string fragment;
     unsigned char output = 0, byte = 0;
     std::vector<std::string> fragments;
 
@@ -386,9 +390,9 @@ rocksdb::Status Bitmap::BitOp(BitOpFlags op_flag, const 
std::string &op_name, co
     read_options.snapshot = ss.GetSnapShot();
     for (uint64_t frag_index = 0; frag_index <= stop_index; frag_index++) {
       for (const auto &meta_pair : meta_pairs) {
-        InternalKey(meta_pair.first, std::to_string(frag_index * 
kBitmapSegmentBytes), meta_pair.second.version,
-                    storage_->IsSlotIdEncoded())
-            .Encode(&sub_key);
+        std::string sub_key = InternalKey(meta_pair.first, 
std::to_string(frag_index * kBitmapSegmentBytes),
+                                          meta_pair.second.version, 
storage_->IsSlotIdEncoded())
+                                  .Encode();
         auto s = storage_->Get(read_options, sub_key, &fragment);
         if (!s.ok() && !s.IsNotFound()) {
           return s;
@@ -505,9 +509,9 @@ rocksdb::Status Bitmap::BitOp(BitOpFlags op_flag, const 
std::string &op_name, co
             frag_maxlen = kBitmapSegmentBytes;
           }
         }
-        InternalKey(ns_key, std::to_string(frag_index * kBitmapSegmentBytes), 
res_metadata.version,
-                    storage_->IsSlotIdEncoded())
-            .Encode(&sub_key);
+        std::string sub_key = InternalKey(ns_key, std::to_string(frag_index * 
kBitmapSegmentBytes),
+                                          res_metadata.version, 
storage_->IsSlotIdEncoded())
+                                  .Encode();
         batch->Put(sub_key, Slice(reinterpret_cast<char *>(frag_res.get()), 
frag_maxlen));
       }
 
diff --git a/src/types/redis_geo.cc b/src/types/redis_geo.cc
index d5e1c78b..ef842784 100644
--- a/src/types/redis_geo.cc
+++ b/src/types/redis_geo.cc
@@ -121,8 +121,7 @@ rocksdb::Status Geo::SearchStore(const Slice &user_key, 
GeoShape geo_shape, Orig
     geo_shape.xy[1] = geo_point.latitude;
   }
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   ZSetMetadata metadata(false);
   rocksdb::Status s = ZSet::GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
diff --git a/src/types/redis_hash.cc b/src/types/redis_hash.cc
index e9a48d94..c2e348cf 100644
--- a/src/types/redis_hash.cc
+++ b/src/types/redis_hash.cc
@@ -40,8 +40,7 @@ rocksdb::Status Hash::GetMetadata(const Slice &ns_key, 
HashMetadata *metadata) {
 rocksdb::Status Hash::Size(const Slice &user_key, uint64_t *size) {
   *size = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   HashMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s;
@@ -50,16 +49,14 @@ rocksdb::Status Hash::Size(const Slice &user_key, uint64_t 
*size) {
 }
 
 rocksdb::Status Hash::Get(const Slice &user_key, const Slice &field, 
std::string *value) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   HashMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s;
   LatestSnapShot ss(storage_);
   rocksdb::ReadOptions read_options;
   read_options.snapshot = ss.GetSnapShot();
-  std::string sub_key;
-  InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+  std::string sub_key = InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   return storage_->Get(read_options, sub_key, value);
 }
 
@@ -67,16 +64,14 @@ rocksdb::Status Hash::IncrBy(const Slice &user_key, const 
Slice &field, int64_t
   bool exists = false;
   int64_t old_value = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   HashMetadata metadata;
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok() && !s.IsNotFound()) return s;
 
-  std::string sub_key;
-  InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+  std::string sub_key = InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   if (s.ok()) {
     std::string value_bytes;
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value_bytes);
@@ -116,16 +111,14 @@ rocksdb::Status Hash::IncrByFloat(const Slice &user_key, 
const Slice &field, dou
   bool exists = false;
   double old_value = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   HashMetadata metadata;
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok() && !s.IsNotFound()) return s;
 
-  std::string sub_key;
-  InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+  std::string sub_key = InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   if (s.ok()) {
     std::string value_bytes;
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value_bytes);
@@ -163,8 +156,7 @@ rocksdb::Status Hash::MGet(const Slice &user_key, const 
std::vector<Slice> &fiel
   values->clear();
   statuses->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   HashMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) {
@@ -181,7 +173,7 @@ rocksdb::Status Hash::MGet(const Slice &user_key, const 
std::vector<Slice> &fiel
   sub_keys.resize(fields.size());
   for (size_t i = 0; i < fields.size(); i++) {
     auto &field = fields[i];
-    InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&(sub_keys[i]));
+    sub_keys[i] = InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     keys.emplace_back(sub_keys[i]);
   }
 
@@ -205,8 +197,7 @@ rocksdb::Status Hash::Set(const Slice &user_key, const 
Slice &field, const Slice
 
 rocksdb::Status Hash::Delete(const Slice &user_key, const std::vector<Slice> 
&fields, uint64_t *deleted_cnt) {
   *deleted_cnt = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   HashMetadata metadata(false);
   auto batch = storage_->GetWriteBatchBase();
@@ -216,13 +207,13 @@ rocksdb::Status Hash::Delete(const Slice &user_key, const 
std::vector<Slice> &fi
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
-  std::string sub_key, value;
+  std::string value;
   std::unordered_set<std::string_view> field_set;
   for (const auto &field : fields) {
     if (!field_set.emplace(field.ToStringView()).second) {
       continue;
     }
-    InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value);
     if (s.ok()) {
       *deleted_cnt += 1;
@@ -242,8 +233,7 @@ rocksdb::Status Hash::Delete(const Slice &user_key, const 
std::vector<Slice> &fi
 rocksdb::Status Hash::MSet(const Slice &user_key, const 
std::vector<FieldValue> &field_values, bool nx,
                            uint64_t *added_cnt) {
   *added_cnt = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   HashMetadata metadata;
@@ -261,8 +251,7 @@ rocksdb::Status Hash::MSet(const Slice &user_key, const 
std::vector<FieldValue>
     }
 
     bool exists = false;
-    std::string sub_key;
-    InternalKey(ns_key, it->field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, it->field, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
 
     if (metadata.size > 0) {
       std::string field_value;
@@ -298,17 +287,16 @@ rocksdb::Status Hash::RangeByLex(const Slice &user_key, 
const RangeLexSpec &spec
   if (spec.count == 0) {
     return rocksdb::Status::OK();
   }
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   HashMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
   std::string start_member = spec.reversed ? spec.max : spec.min;
-  std::string start_key, prefix_key, next_version_prefix_key;
-  InternalKey(ns_key, start_member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  std::string start_key = InternalKey(ns_key, start_member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  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 = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
   read_options.snapshot = ss.GetSnapShot();
@@ -355,15 +343,14 @@ rocksdb::Status Hash::RangeByLex(const Slice &user_key, 
const RangeLexSpec &spec
 rocksdb::Status Hash::GetAll(const Slice &user_key, std::vector<FieldValue> 
*field_values, HashFetchType type) {
   field_values->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   HashMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
-  std::string prefix_key, next_version_prefix_key;
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  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 = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -397,8 +384,7 @@ rocksdb::Status Hash::RandField(const Slice &user_key, 
int64_t command_count, st
   uint64_t count = (command_count >= 0) ? static_cast<uint64_t>(command_count) 
: static_cast<uint64_t>(-command_count);
   bool unique = (command_count >= 0);
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   HashMetadata metadata(/*generate_version=*/false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s;
diff --git a/src/types/redis_list.cc b/src/types/redis_list.cc
index 4ac6b6b9..688da498 100644
--- a/src/types/redis_list.cc
+++ b/src/types/redis_list.cc
@@ -34,8 +34,7 @@ rocksdb::Status List::GetMetadata(const Slice &ns_key, 
ListMetadata *metadata) {
 rocksdb::Status List::Size(const Slice &user_key, uint64_t *size) {
   *size = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   ListMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
@@ -54,8 +53,7 @@ rocksdb::Status List::PushX(const Slice &user_key, const 
std::vector<Slice> &ele
 rocksdb::Status List::push(const Slice &user_key, const std::vector<Slice> 
&elems, bool create_if_missing, bool left,
                            uint64_t *new_size) {
   *new_size = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   ListMetadata metadata;
   auto batch = storage_->GetWriteBatchBase();
@@ -69,9 +67,9 @@ rocksdb::Status List::push(const Slice &user_key, const 
std::vector<Slice> &elem
   }
   uint64_t index = left ? metadata.head - 1 : metadata.tail;
   for (const auto &elem : elems) {
-    std::string index_buf, sub_key;
+    std::string index_buf;
     PutFixed64(&index_buf, index);
-    InternalKey(ns_key, index_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, index_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     batch->Put(sub_key, elem);
     left ? --index : ++index;
   }
@@ -103,8 +101,7 @@ rocksdb::Status List::PopMulti(const rocksdb::Slice 
&user_key, bool left, uint32
                                std::vector<std::string> *elems) {
   elems->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ListMetadata metadata(false);
@@ -120,8 +117,7 @@ rocksdb::Status List::PopMulti(const rocksdb::Slice 
&user_key, bool left, uint32
     uint64_t index = left ? metadata.head : metadata.tail - 1;
     std::string buf;
     PutFixed64(&buf, index);
-    std::string sub_key;
-    InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     std::string elem;
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &elem);
     if (!s.ok()) {
@@ -169,8 +165,7 @@ rocksdb::Status List::PopMulti(const rocksdb::Slice 
&user_key, bool left, uint32
 rocksdb::Status List::Rem(const Slice &user_key, int count, const Slice &elem, 
uint64_t *removed_cnt) {
   *removed_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ListMetadata metadata(false);
@@ -178,11 +173,11 @@ rocksdb::Status List::Rem(const Slice &user_key, int 
count, const Slice &elem, u
   if (!s.ok()) return s;
 
   uint64_t index = count >= 0 ? metadata.head : metadata.tail - 1;
-  std::string buf, start_key, prefix, next_version_prefix;
+  std::string buf;
   PutFixed64(&buf, index);
-  InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix);
+  std::string start_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string prefix = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string next_version_prefix = InternalKey(ns_key, "", metadata.version + 
1, storage_->IsSlotIdEncoded()).Encode();
 
   bool reversed = count < 0;
   std::vector<uint64_t> to_delete_indexes;
@@ -216,7 +211,6 @@ rocksdb::Status List::Rem(const Slice &user_key, int count, 
const Slice &elem, u
   if (to_delete_indexes.size() == metadata.size) {
     batch->Delete(metadata_cf_handle_, ns_key);
   } else {
-    std::string to_update_key, to_delete_key;
     uint64_t min_to_delete_index = !reversed ? to_delete_indexes[0] : 
to_delete_indexes[to_delete_indexes.size() - 1];
     uint64_t max_to_delete_index = !reversed ? 
to_delete_indexes[to_delete_indexes.size() - 1] : to_delete_indexes[0];
     uint64_t left_part_len = max_to_delete_index - metadata.head;
@@ -224,14 +218,14 @@ rocksdb::Status List::Rem(const Slice &user_key, int 
count, const Slice &elem, u
     reversed = left_part_len <= right_part_len;
     buf.clear();
     PutFixed64(&buf, reversed ? max_to_delete_index : min_to_delete_index);
-    InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
+    start_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     size_t processed = 0;
     for (iter->Seek(start_key); iter->Valid() && 
iter->key().starts_with(prefix);
          !reversed ? iter->Next() : iter->Prev()) {
       if (iter->value() != elem || processed >= to_delete_indexes.size()) {
         buf.clear();
         PutFixed64(&buf, reversed ? max_to_delete_index-- : 
min_to_delete_index++);
-        InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&to_update_key);
+        std::string to_update_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
         batch->Put(to_update_key, iter->value());
       } else {
         processed++;
@@ -241,7 +235,7 @@ rocksdb::Status List::Rem(const Slice &user_key, int count, 
const Slice &elem, u
     for (uint64_t idx = 0; idx < to_delete_indexes.size(); ++idx) {
       buf.clear();
       PutFixed64(&buf, reversed ? (metadata.head + idx) : (metadata.tail - 1 - 
idx));
-      InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&to_delete_key);
+      std::string to_delete_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
       batch->Delete(to_delete_key);
     }
     if (reversed) {
@@ -261,20 +255,19 @@ rocksdb::Status List::Rem(const Slice &user_key, int 
count, const Slice &elem, u
 
 rocksdb::Status List::Insert(const Slice &user_key, const Slice &pivot, const 
Slice &elem, bool before, int *new_size) {
   *new_size = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ListMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s;
 
-  std::string buf, start_key, prefix, next_version_prefix;
+  std::string buf;
   uint64_t pivot_index = metadata.head - 1;
   PutFixed64(&buf, metadata.head);
-  InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix);
+  std::string start_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string prefix = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string next_version_prefix = InternalKey(ns_key, "", metadata.version + 
1, storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -315,12 +308,12 @@ rocksdb::Status List::Insert(const Slice &user_key, const 
Slice &pivot, const Sl
   for (; iter->Valid() && iter->key().starts_with(prefix); !reversed ? 
iter->Next() : iter->Prev()) {
     buf.clear();
     PutFixed64(&buf, reversed ? --pivot_index : ++pivot_index);
-    InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&to_update_key);
+    to_update_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     batch->Put(to_update_key, iter->value());
   }
   buf.clear();
   PutFixed64(&buf, new_elem_index);
-  InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&to_update_key);
+  to_update_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   batch->Put(to_update_key, elem);
 
   if (reversed) {
@@ -340,8 +333,7 @@ rocksdb::Status List::Insert(const Slice &user_key, const 
Slice &pivot, const Sl
 rocksdb::Status List::Index(const Slice &user_key, int index, std::string 
*elem) {
   elem->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   ListMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s;
@@ -354,8 +346,7 @@ rocksdb::Status List::Index(const Slice &user_key, int 
index, std::string *elem)
   read_options.snapshot = ss.GetSnapShot();
   std::string buf;
   PutFixed64(&buf, metadata.head + index);
-  std::string sub_key;
-  InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+  std::string sub_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   return storage_->Get(read_options, sub_key, elem);
 }
 
@@ -367,8 +358,7 @@ rocksdb::Status List::Index(const Slice &user_key, int 
index, std::string *elem)
 rocksdb::Status List::Range(const Slice &user_key, int start, int stop, 
std::vector<std::string> *elems) {
   elems->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   ListMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
@@ -380,10 +370,9 @@ rocksdb::Status List::Range(const Slice &user_key, int 
start, int stop, std::vec
 
   std::string buf;
   PutFixed64(&buf, metadata.head + start);
-  std::string start_key, prefix, next_version_prefix;
-  InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix);
+  std::string start_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string prefix = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string next_version_prefix = InternalKey(ns_key, "", metadata.version + 
1, storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -405,8 +394,7 @@ rocksdb::Status List::Range(const Slice &user_key, int 
start, int stop, std::vec
 }
 
 rocksdb::Status List::Set(const Slice &user_key, int index, Slice elem) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ListMetadata metadata(false);
@@ -417,9 +405,9 @@ rocksdb::Status List::Set(const Slice &user_key, int index, 
Slice elem) {
     return rocksdb::Status::InvalidArgument("index out of range");
   }
 
-  std::string buf, value, sub_key;
+  std::string buf, value;
   PutFixed64(&buf, metadata.head + index);
-  InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+  std::string sub_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value);
   if (!s.ok()) {
     return s;
@@ -442,8 +430,7 @@ rocksdb::Status List::LMove(const rocksdb::Slice &src, 
const rocksdb::Slice &dst
 }
 
 rocksdb::Status List::lmoveOnSingleList(const rocksdb::Slice &src, bool 
src_left, bool dst_left, std::string *elem) {
-  std::string ns_key;
-  AppendNamespacePrefix(src, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(src);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ListMetadata metadata(false);
@@ -457,8 +444,8 @@ rocksdb::Status List::lmoveOnSingleList(const 
rocksdb::Slice &src, bool src_left
   uint64_t curr_index = src_left ? metadata.head : metadata.tail - 1;
   std::string curr_index_buf;
   PutFixed64(&curr_index_buf, curr_index);
-  std::string curr_sub_key;
-  InternalKey(ns_key, curr_index_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&curr_sub_key);
+  std::string curr_sub_key =
+      InternalKey(ns_key, curr_index_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   s = storage_->Get(rocksdb::ReadOptions(), curr_sub_key, elem);
   if (!s.ok()) {
     return s;
@@ -492,8 +479,7 @@ rocksdb::Status List::lmoveOnSingleList(const 
rocksdb::Slice &src, bool src_left
   uint64_t new_index = src_left ? metadata.tail - 1 : metadata.head;
   std::string new_index_buf;
   PutFixed64(&new_index_buf, new_index);
-  std::string new_sub_key;
-  InternalKey(ns_key, new_index_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&new_sub_key);
+  std::string new_sub_key = InternalKey(ns_key, new_index_buf, 
metadata.version, storage_->IsSlotIdEncoded()).Encode();
   batch->Put(new_sub_key, *elem);
 
   std::string bytes;
@@ -505,10 +491,8 @@ rocksdb::Status List::lmoveOnSingleList(const 
rocksdb::Slice &src, bool src_left
 
 rocksdb::Status List::lmoveOnTwoLists(const rocksdb::Slice &src, const 
rocksdb::Slice &dst, bool src_left,
                                       bool dst_left, std::string *elem) {
-  std::string src_ns_key;
-  AppendNamespacePrefix(src, &src_ns_key);
-  std::string dst_ns_key;
-  AppendNamespacePrefix(dst, &dst_ns_key);
+  std::string src_ns_key = AppendNamespacePrefix(src);
+  std::string dst_ns_key = AppendNamespacePrefix(dst);
 
   std::vector<std::string> lock_keys{src_ns_key, dst_ns_key};
   MultiLockGuard guard(storage_->GetLockManager(), lock_keys);
@@ -534,8 +518,8 @@ rocksdb::Status List::lmoveOnTwoLists(const rocksdb::Slice 
&src, const rocksdb::
   uint64_t src_index = src_left ? src_metadata.head : src_metadata.tail - 1;
   std::string src_buf;
   PutFixed64(&src_buf, src_index);
-  std::string src_sub_key;
-  InternalKey(src_ns_key, src_buf, src_metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&src_sub_key);
+  std::string src_sub_key =
+      InternalKey(src_ns_key, src_buf, src_metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   s = storage_->Get(rocksdb::ReadOptions(), src_sub_key, elem);
   if (!s.ok()) {
     return s;
@@ -555,8 +539,8 @@ rocksdb::Status List::lmoveOnTwoLists(const rocksdb::Slice 
&src, const rocksdb::
   uint64_t dst_index = dst_left ? dst_metadata.head - 1 : dst_metadata.tail;
   std::string dst_buf;
   PutFixed64(&dst_buf, dst_index);
-  std::string dst_sub_key;
-  InternalKey(dst_ns_key, dst_buf, dst_metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&dst_sub_key);
+  std::string dst_sub_key =
+      InternalKey(dst_ns_key, dst_buf, dst_metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   batch->Put(dst_sub_key, *elem);
   dst_left ? --dst_metadata.head : ++dst_metadata.tail;
 
@@ -571,8 +555,7 @@ rocksdb::Status List::lmoveOnTwoLists(const rocksdb::Slice 
&src, const rocksdb::
 // Caution: trim the big list may block the server
 rocksdb::Status List::Trim(const Slice &user_key, int start, int stop) {
   uint32_t trim_cnt = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ListMetadata metadata(false);
@@ -597,8 +580,7 @@ rocksdb::Status List::Trim(const Slice &user_key, int 
start, int stop) {
   for (uint64_t i = metadata.head; i < left_index; i++) {
     std::string buf;
     PutFixed64(&buf, i);
-    std::string sub_key;
-    InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     batch->Delete(sub_key);
     metadata.head++;
     trim_cnt++;
@@ -607,8 +589,7 @@ rocksdb::Status List::Trim(const Slice &user_key, int 
start, int stop) {
   for (uint64_t i = right_index; i < tail; i++) {
     std::string buf;
     PutFixed64(&buf, i);
-    std::string sub_key;
-    InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     batch->Delete(sub_key);
     metadata.tail--;
     trim_cnt++;
diff --git a/src/types/redis_set.cc b/src/types/redis_set.cc
index 16a916be..420904cb 100644
--- a/src/types/redis_set.cc
+++ b/src/types/redis_set.cc
@@ -34,17 +34,15 @@ rocksdb::Status Set::GetMetadata(const Slice &ns_key, 
SetMetadata *metadata) {
 
 // Make sure members are uniq before use Overwrite
 rocksdb::Status Set::Overwrite(Slice user_key, const std::vector<std::string> 
&members) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   SetMetadata metadata;
   auto batch = storage_->GetWriteBatchBase();
   WriteBatchLogData log_data(kRedisSet);
   batch->PutLogData(log_data.Encode());
-  std::string sub_key;
   for (const auto &member : members) {
-    InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     batch->Put(sub_key, Slice());
   }
   metadata.size = static_cast<uint32_t>(members.size());
@@ -57,8 +55,7 @@ rocksdb::Status Set::Overwrite(Slice user_key, const 
std::vector<std::string> &m
 rocksdb::Status Set::Add(const Slice &user_key, const std::vector<Slice> 
&members, uint64_t *added_cnt) {
   *added_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   SetMetadata metadata;
@@ -69,13 +66,12 @@ rocksdb::Status Set::Add(const Slice &user_key, const 
std::vector<Slice> &member
   auto batch = storage_->GetWriteBatchBase();
   WriteBatchLogData log_data(kRedisSet);
   batch->PutLogData(log_data.Encode());
-  std::string sub_key;
   std::unordered_set<std::string_view> mset;
   for (const auto &member : members) {
     if (!mset.insert(member.ToStringView()).second) {
       continue;
     }
-    InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value);
     if (s.ok()) continue;
     batch->Put(sub_key, Slice());
@@ -93,15 +89,14 @@ rocksdb::Status Set::Add(const Slice &user_key, const 
std::vector<Slice> &member
 rocksdb::Status Set::Remove(const Slice &user_key, const std::vector<Slice> 
&members, uint64_t *removed_cnt) {
   *removed_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   SetMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
-  std::string value, sub_key;
+  std::string value;
   auto batch = storage_->GetWriteBatchBase();
   WriteBatchLogData log_data(kRedisSet);
   batch->PutLogData(log_data.Encode());
@@ -110,7 +105,7 @@ rocksdb::Status Set::Remove(const Slice &user_key, const 
std::vector<Slice> &mem
     if (!mset.insert(member.ToStringView()).second) {
       continue;
     }
-    InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value);
     if (!s.ok()) continue;
     batch->Delete(sub_key);
@@ -131,8 +126,7 @@ rocksdb::Status Set::Remove(const Slice &user_key, const 
std::vector<Slice> &mem
 
 rocksdb::Status Set::Card(const Slice &user_key, uint64_t *size) {
   *size = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   SetMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
@@ -144,16 +138,14 @@ rocksdb::Status Set::Card(const Slice &user_key, uint64_t 
*size) {
 rocksdb::Status Set::Members(const Slice &user_key, std::vector<std::string> 
*members) {
   members->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   SetMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
-  std::string prefix, next_version_prefix;
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix);
+  std::string prefix = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string next_version_prefix = InternalKey(ns_key, "", metadata.version + 
1, storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -180,8 +172,7 @@ rocksdb::Status Set::IsMember(const Slice &user_key, const 
Slice &member, bool *
 rocksdb::Status Set::MIsMember(const Slice &user_key, const std::vector<Slice> 
&members, std::vector<int> *exists) {
   exists->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   SetMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
@@ -190,9 +181,9 @@ rocksdb::Status Set::MIsMember(const Slice &user_key, const 
std::vector<Slice> &
   rocksdb::ReadOptions read_options;
   LatestSnapShot ss(storage_);
   read_options.snapshot = ss.GetSnapShot();
-  std::string sub_key, value;
+  std::string value;
   for (const auto &member : members) {
-    InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     s = storage_->Get(read_options, sub_key, &value);
     if (!s.ok() && !s.IsNotFound()) return s;
     if (s.IsNotFound()) {
@@ -209,8 +200,7 @@ rocksdb::Status Set::Take(const Slice &user_key, 
std::vector<std::string> *membe
   members->clear();
   if (count <= 0) return rocksdb::Status::OK();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   std::optional<LockGuard> lock_guard;
   if (pop) lock_guard.emplace(storage_->GetLockManager(), ns_key);
@@ -223,9 +213,8 @@ rocksdb::Status Set::Take(const Slice &user_key, 
std::vector<std::string> *membe
   WriteBatchLogData log_data(kRedisSet);
   batch->PutLogData(log_data.Encode());
 
-  std::string prefix, next_version_prefix;
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix);
+  std::string prefix = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string next_version_prefix = InternalKey(ns_key, "", metadata.version + 
1, storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
diff --git a/src/types/redis_sortedint.cc b/src/types/redis_sortedint.cc
index ab8b8a2d..76ad31fc 100644
--- a/src/types/redis_sortedint.cc
+++ b/src/types/redis_sortedint.cc
@@ -35,8 +35,7 @@ rocksdb::Status Sortedint::GetMetadata(const Slice &ns_key, 
SortedintMetadata *m
 rocksdb::Status Sortedint::Add(const Slice &user_key, const 
std::vector<uint64_t> &ids, uint64_t *added_cnt) {
   *added_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   SortedintMetadata metadata;
@@ -47,11 +46,10 @@ rocksdb::Status Sortedint::Add(const Slice &user_key, const 
std::vector<uint64_t
   auto batch = storage_->GetWriteBatchBase();
   WriteBatchLogData log_data(kRedisSortedint);
   batch->PutLogData(log_data.Encode());
-  std::string sub_key;
   for (const auto id : ids) {
     std::string id_buf;
     PutFixed64(&id_buf, id);
-    InternalKey(ns_key, id_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, id_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value);
     if (s.ok()) continue;
     batch->Put(sub_key, Slice());
@@ -70,22 +68,21 @@ rocksdb::Status Sortedint::Add(const Slice &user_key, const 
std::vector<uint64_t
 rocksdb::Status Sortedint::Remove(const Slice &user_key, const 
std::vector<uint64_t> &ids, uint64_t *removed_cnt) {
   *removed_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   SortedintMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
-  std::string value, sub_key;
+  std::string value;
   auto batch = storage_->GetWriteBatchBase();
   WriteBatchLogData log_data(kRedisSortedint);
   batch->PutLogData(log_data.Encode());
   for (const auto id : ids) {
     std::string id_buf;
     PutFixed64(&id_buf, id);
-    InternalKey(ns_key, id_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, id_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     s = storage_->Get(rocksdb::ReadOptions(), sub_key, &value);
     if (!s.ok()) continue;
     batch->Delete(sub_key);
@@ -101,8 +98,7 @@ rocksdb::Status Sortedint::Remove(const Slice &user_key, 
const std::vector<uint6
 
 rocksdb::Status Sortedint::Card(const Slice &user_key, uint64_t *size) {
   *size = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   SortedintMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
@@ -115,22 +111,21 @@ rocksdb::Status Sortedint::Range(const Slice &user_key, 
uint64_t cursor_id, uint
                                  bool reversed, std::vector<uint64_t> *ids) {
   ids->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   SortedintMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
-  std::string prefix, next_version_prefix, start_key, start_buf;
+  std::string start_buf;
   uint64_t start_id = cursor_id;
   if (reversed && cursor_id == 0) {
     start_id = std::numeric_limits<uint64_t>::max();
   }
   PutFixed64(&start_buf, start_id);
-  InternalKey(ns_key, start_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix);
+  std::string start_key = InternalKey(ns_key, start_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string prefix = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string next_version_prefix = InternalKey(ns_key, "", metadata.version + 
1, storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -159,18 +154,18 @@ rocksdb::Status Sortedint::RangeByValue(const Slice 
&user_key, SortedintRangeSpe
   if (size) *size = 0;
   if (ids) ids->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   SortedintMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
-  std::string start_buf, start_key, prefix_key, next_version_prefix_key;
+  std::string start_buf;
   PutFixed64(&start_buf, spec.reversed ? spec.max : spec.min);
-  InternalKey(ns_key, start_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  std::string start_key = InternalKey(ns_key, start_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  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 = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -209,8 +204,7 @@ rocksdb::Status Sortedint::RangeByValue(const Slice 
&user_key, SortedintRangeSpe
 }
 
 rocksdb::Status Sortedint::MExist(const Slice &user_key, const 
std::vector<uint64_t> &ids, std::vector<int> *exists) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   SortedintMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
@@ -219,11 +213,11 @@ rocksdb::Status Sortedint::MExist(const Slice &user_key, 
const std::vector<uint6
   LatestSnapShot ss(storage_);
   rocksdb::ReadOptions read_options;
   read_options.snapshot = ss.GetSnapShot();
-  std::string sub_key, value;
+  std::string value;
   for (const auto id : ids) {
     std::string id_buf;
     PutFixed64(&id_buf, id);
-    InternalKey(ns_key, id_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+    std::string sub_key = InternalKey(ns_key, id_buf, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     s = storage_->Get(read_options, sub_key, &value);
     if (!s.ok() && !s.IsNotFound()) return s;
     if (s.IsNotFound()) {
diff --git a/src/types/redis_stream.cc b/src/types/redis_stream.cc
index fa0320eb..8b27e936 100644
--- a/src/types/redis_stream.cc
+++ b/src/types/redis_stream.cc
@@ -44,8 +44,7 @@ rocksdb::Status Stream::GetMetadata(const Slice &stream_name, 
StreamMetadata *me
 }
 
 rocksdb::Status Stream::GetLastGeneratedID(const Slice &stream_name, 
StreamEntryID *id) {
-  std::string ns_key;
-  AppendNamespacePrefix(stream_name, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(stream_name);
 
   StreamMetadata metadata;
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
@@ -77,8 +76,7 @@ std::string Stream::internalKeyFromEntryID(const std::string 
&ns_key, const Stre
   std::string sub_key;
   PutFixed64(&sub_key, id.ms);
   PutFixed64(&sub_key, id.seq);
-  std::string entry_key;
-  InternalKey(ns_key, sub_key, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&entry_key);
+  std::string entry_key = InternalKey(ns_key, sub_key, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   return entry_key;
 }
 
@@ -92,8 +90,7 @@ rocksdb::Status Stream::Add(const Slice &stream_name, const 
StreamAddOptions &op
 
   std::string entry_value = EncodeStreamEntryValue(args);
 
-  std::string ns_key;
-  AppendNamespacePrefix(stream_name, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(stream_name);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   StreamMetadata metadata;
@@ -167,8 +164,7 @@ rocksdb::Status Stream::DeleteEntries(const Slice 
&stream_name, const std::vecto
                                       uint64_t *deleted_cnt) {
   *deleted_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(stream_name, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(stream_name);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   StreamMetadata metadata(false);
@@ -181,10 +177,9 @@ rocksdb::Status Stream::DeleteEntries(const Slice 
&stream_name, const std::vecto
   WriteBatchLogData log_data(kRedisStream);
   batch->PutLogData(log_data.Encode());
 
-  std::string next_version_prefix_key;
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
-  std::string prefix_key;
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
+  std::string next_version_prefix_key =
+      InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string prefix_key = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -259,8 +254,7 @@ rocksdb::Status Stream::DeleteEntries(const Slice 
&stream_name, const std::vecto
 // The entry with the ID `StreamLenOptions::entry_id` has not taken into 
account (it serves as exclusive boundary).
 rocksdb::Status Stream::Len(const Slice &stream_name, const StreamLenOptions 
&options, uint64_t *size) {
   *size = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(stream_name, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(stream_name);
 
   StreamMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
@@ -289,10 +283,9 @@ rocksdb::Status Stream::Len(const Slice &stream_name, 
const StreamLenOptions &op
     return rocksdb::Status::OK();
   }
 
-  std::string prefix_key;
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  std::string next_version_prefix_key;
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  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 = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -353,10 +346,9 @@ rocksdb::Status Stream::range(const std::string &ns_key, 
const StreamMetadata &m
     return rocksdb::Status::OK();
   }
 
-  std::string next_version_prefix_key;
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
-  std::string prefix_key;
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
+  std::string next_version_prefix_key =
+      InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string prefix_key = InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -405,8 +397,7 @@ rocksdb::Status Stream::getEntryRawValue(const std::string 
&ns_key, const Stream
 }
 
 rocksdb::Status Stream::GetStreamInfo(const rocksdb::Slice &stream_name, bool 
full, uint64_t count, StreamInfo *info) {
-  std::string ns_key;
-  AppendNamespacePrefix(stream_name, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(stream_name);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   StreamMetadata metadata(false);
@@ -492,8 +483,7 @@ rocksdb::Status Stream::Range(const Slice &stream_name, 
const StreamRangeOptions
     return rocksdb::Status::InvalidArgument("invalid end ID for the interval");
   }
 
-  std::string ns_key;
-  AppendNamespacePrefix(stream_name, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(stream_name);
 
   StreamMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
@@ -511,8 +501,7 @@ rocksdb::Status Stream::Trim(const Slice &stream_name, 
const StreamTrimOptions &
     return rocksdb::Status::OK();
   }
 
-  std::string ns_key;
-  AppendNamespacePrefix(stream_name, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(stream_name);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
 
@@ -555,10 +544,9 @@ uint64_t Stream::trim(const std::string &ns_key, const 
StreamTrimOptions &option
 
   uint64_t ret = 0;
 
-  std::string next_version_prefix_key;
-  InternalKey(ns_key, "", metadata->version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
-  std::string prefix_key;
-  InternalKey(ns_key, "", metadata->version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
+  std::string next_version_prefix_key =
+      InternalKey(ns_key, "", metadata->version + 1, 
storage_->IsSlotIdEncoded()).Encode();
+  std::string prefix_key = InternalKey(ns_key, "", metadata->version, 
storage_->IsSlotIdEncoded()).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -618,8 +606,7 @@ rocksdb::Status Stream::SetId(const Slice &stream_name, 
const StreamEntryID &las
     return 
rocksdb::Status::InvalidArgument(errMaxDeletedIdGreaterThanLastGenerated);
   }
 
-  std::string ns_key;
-  AppendNamespacePrefix(stream_name, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(stream_name);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
 
diff --git a/src/types/redis_string.cc b/src/types/redis_string.cc
index 61ef7640..a5db05de 100644
--- a/src/types/redis_string.cc
+++ b/src/types/redis_string.cc
@@ -115,8 +115,7 @@ rocksdb::Status String::updateRawValue(const std::string 
&ns_key, const std::str
 
 rocksdb::Status String::Append(const std::string &user_key, const std::string 
&value, uint64_t *new_size) {
   *new_size = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   std::string raw_value;
@@ -135,8 +134,7 @@ std::vector<rocksdb::Status> String::MGet(const 
std::vector<Slice> &keys, std::v
   std::vector<std::string> ns_keys;
   ns_keys.reserve(keys.size());
   for (const auto &key : keys) {
-    std::string ns_key;
-    AppendNamespacePrefix(key, &ns_key);
+    std::string ns_key = AppendNamespacePrefix(key);
     ns_keys.emplace_back(ns_key);
   }
   std::vector<Slice> slice_keys;
@@ -148,8 +146,7 @@ std::vector<rocksdb::Status> String::MGet(const 
std::vector<Slice> &keys, std::v
 }
 
 rocksdb::Status String::Get(const std::string &user_key, std::string *value) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   return getValue(ns_key, value);
 }
 
@@ -159,8 +156,7 @@ rocksdb::Status String::GetEx(const std::string &user_key, 
std::string *value, u
     uint64_t now = util::GetTimeStampMS();
     expire = now + ttl;
   }
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   rocksdb::Status s = getValue(ns_key, value);
@@ -186,8 +182,7 @@ rocksdb::Status String::GetEx(const std::string &user_key, 
std::string *value, u
 }
 
 rocksdb::Status String::GetSet(const std::string &user_key, const std::string 
&new_value, std::string *old_value) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   rocksdb::Status s = getValue(ns_key, old_value);
@@ -202,8 +197,7 @@ rocksdb::Status String::GetSet(const std::string &user_key, 
const std::string &n
   return !write_status.ok() ? write_status : s;
 }
 rocksdb::Status String::GetDel(const std::string &user_key, std::string 
*value) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   rocksdb::Status s = getValue(ns_key, value);
@@ -236,8 +230,7 @@ rocksdb::Status String::SetXX(const std::string &user_key, 
const std::string &va
     expire = now + ttl;
   }
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   LockGuard guard(storage_->GetLockManager(), ns_key);
   Exists({user_key}, &exists);
   if (exists != 1) return rocksdb::Status::OK();
@@ -253,8 +246,7 @@ rocksdb::Status String::SetXX(const std::string &user_key, 
const std::string &va
 
 rocksdb::Status String::SetRange(const std::string &user_key, size_t offset, 
const std::string &value,
                                  uint64_t *new_size) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   std::string raw_value;
@@ -293,8 +285,8 @@ rocksdb::Status String::SetRange(const std::string 
&user_key, size_t offset, con
 }
 
 rocksdb::Status String::IncrBy(const std::string &user_key, int64_t increment, 
int64_t *new_value) {
-  std::string ns_key, value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   std::string raw_value;
@@ -331,8 +323,8 @@ rocksdb::Status String::IncrBy(const std::string &user_key, 
int64_t increment, i
 }
 
 rocksdb::Status String::IncrByFloat(const std::string &user_key, double 
increment, double *new_value) {
-  std::string ns_key, value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
   LockGuard guard(storage_->GetLockManager(), ns_key);
   std::string raw_value;
   rocksdb::Status s = getRawValue(ns_key, &raw_value);
@@ -373,13 +365,12 @@ rocksdb::Status String::MSet(const 
std::vector<StringPair> &pairs, uint64_t ttl,
 
   // Data race, key string maybe overwrite by other key while didn't lock the 
keys here,
   // to improve the set performance
-  std::string ns_key;
   std::optional<MultiLockGuard> guard;
   if (lock) {
     std::vector<std::string> lock_keys;
     lock_keys.reserve(pairs.size());
     for (const StringPair &pair : pairs) {
-      AppendNamespacePrefix(pair.key, &ns_key);
+      std::string ns_key = AppendNamespacePrefix(pair.key);
       lock_keys.emplace_back(ns_key);
     }
     guard.emplace(storage_->GetLockManager(), lock_keys);
@@ -394,7 +385,7 @@ rocksdb::Status String::MSet(const std::vector<StringPair> 
&pairs, uint64_t ttl,
     metadata.expire = expire;
     metadata.Encode(&bytes);
     bytes.append(pair.value.data(), pair.value.size());
-    AppendNamespacePrefix(pair.key, &ns_key);
+    std::string ns_key = AppendNamespacePrefix(pair.key);
     batch->Put(metadata_cf_handle_, ns_key, bytes);
   }
   return storage_->Write(storage_->DefaultWriteOptions(), 
batch->GetWriteBatch());
@@ -404,14 +395,13 @@ rocksdb::Status String::MSetNX(const 
std::vector<StringPair> &pairs, uint64_t tt
   *flag = false;
 
   int exists = 0;
-  std::string ns_key;
   std::vector<std::string> lock_keys;
   lock_keys.reserve(pairs.size());
   std::vector<Slice> keys;
   keys.reserve(pairs.size());
 
   for (StringPair pair : pairs) {
-    AppendNamespacePrefix(pair.key, &ns_key);
+    std::string ns_key = AppendNamespacePrefix(pair.key);
     lock_keys.emplace_back(ns_key);
     keys.emplace_back(pair.key);
   }
@@ -439,8 +429,8 @@ rocksdb::Status String::CAS(const std::string &user_key, 
const std::string &old_
                             uint64_t ttl, int *flag) {
   *flag = 0;
 
-  std::string ns_key, current_value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string current_value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   rocksdb::Status s = getValue(ns_key, &current_value);
@@ -480,8 +470,8 @@ rocksdb::Status String::CAS(const std::string &user_key, 
const std::string &old_
 rocksdb::Status String::CAD(const std::string &user_key, const std::string 
&value, int *flag) {
   *flag = 0;
 
-  std::string ns_key, current_value;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string current_value;
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   rocksdb::Status s = getValue(ns_key, &current_value);
diff --git a/src/types/redis_zset.cc b/src/types/redis_zset.cc
index 85e2d0f7..d6ffc58b 100644
--- a/src/types/redis_zset.cc
+++ b/src/types/redis_zset.cc
@@ -38,8 +38,7 @@ rocksdb::Status ZSet::GetMetadata(const Slice &ns_key, 
ZSetMetadata *metadata) {
 rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags flags, MemberScores 
*mscores, uint64_t *added_cnt) {
   *added_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ZSetMetadata metadata;
@@ -51,13 +50,12 @@ rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags 
flags, MemberScores *
   auto batch = storage_->GetWriteBatchBase();
   WriteBatchLogData log_data(kRedisZSet);
   batch->PutLogData(log_data.Encode());
-  std::string member_key;
   std::unordered_set<std::string_view> added_member_keys;
   for (auto it = mscores->rbegin(); it != mscores->rend(); it++) {
     if (!added_member_keys.insert(it->member).second) {
       continue;
     }
-    InternalKey(ns_key, it->member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&member_key);
+    std::string member_key = InternalKey(ns_key, it->member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     if (metadata.size > 0) {
       std::string old_score_bytes;
       s = storage_->Get(rocksdb::ReadOptions(), member_key, &old_score_bytes);
@@ -81,14 +79,15 @@ rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags 
flags, MemberScores *
             continue;
           }
           old_score_bytes.append(it->member);
-          std::string old_score_key;
-          InternalKey(ns_key, old_score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&old_score_key);
+          std::string old_score_key =
+              InternalKey(ns_key, old_score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
           batch->Delete(score_cf_handle_, old_score_key);
-          std::string new_score_bytes, new_score_key;
+          std::string new_score_bytes;
           PutDouble(&new_score_bytes, it->score);
           batch->Put(member_key, new_score_bytes);
           new_score_bytes.append(it->member);
-          InternalKey(ns_key, new_score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&new_score_key);
+          std::string new_score_key =
+              InternalKey(ns_key, new_score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
           batch->Put(score_cf_handle_, new_score_key, Slice());
           changed++;
         }
@@ -98,11 +97,11 @@ rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags 
flags, MemberScores *
     if (flags.HasXX()) {
       continue;
     }
-    std::string score_bytes, score_key;
+    std::string score_bytes;
     PutDouble(&score_bytes, it->score);
     batch->Put(member_key, score_bytes);
     score_bytes.append(it->member);
-    InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&score_key);
+    std::string score_key = InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     batch->Put(score_cf_handle_, score_key, Slice());
     added++;
   }
@@ -122,8 +121,7 @@ rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags 
flags, MemberScores *
 rocksdb::Status ZSet::Card(const Slice &user_key, uint64_t *size) {
   *size = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   ZSetMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
@@ -149,8 +147,7 @@ rocksdb::Status ZSet::IncrBy(const Slice &user_key, const 
Slice &member, double
 rocksdb::Status ZSet::Pop(const Slice &user_key, int count, bool min, 
MemberScores *mscores) {
   mscores->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ZSetMetadata metadata(false);
@@ -162,10 +159,10 @@ rocksdb::Status ZSet::Pop(const Slice &user_key, int 
count, bool min, MemberScor
   std::string score_bytes;
   double score = min ? kMinScore : kMaxScore;
   PutDouble(&score_bytes, score);
-  std::string start_key, prefix_key, next_version_prefix_key;
-  InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  std::string start_key = InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  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();
 
   auto batch = storage_->GetWriteBatchBase();
   WriteBatchLogData log_data(kRedisZSet);
@@ -190,8 +187,7 @@ rocksdb::Status ZSet::Pop(const Slice &user_key, int count, 
bool min, MemberScor
     Slice score_key = ikey.GetSubKey();
     GetDouble(&score_key, &score);
     mscores->emplace_back(MemberScore{score_key.ToString(), score});
-    std::string default_cf_key;
-    InternalKey(ns_key, score_key, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&default_cf_key);
+    std::string default_cf_key = InternalKey(ns_key, score_key, 
metadata.version, storage_->IsSlotIdEncoded()).Encode();
     batch->Delete(default_cf_key);
     batch->Delete(score_cf_handle_, iter->key());
     if (mscores->size() >= static_cast<unsigned>(count)) break;
@@ -214,8 +210,7 @@ rocksdb::Status ZSet::RangeByRank(const Slice &user_key, 
const RangeRankSpec &sp
   if (!removed_cnt) removed_cnt = &cnt;
   *removed_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   std::optional<LockGuard> lock_guard;
   if (spec.with_deletion) lock_guard.emplace(storage_->GetLockManager(), 
ns_key);
@@ -236,10 +231,10 @@ rocksdb::Status ZSet::RangeByRank(const Slice &user_key, 
const RangeRankSpec &sp
   std::string score_bytes;
   double score = !(spec.reversed) ? kMinScore : kMaxScore;
   PutDouble(&score_bytes, score);
-  std::string start_key, prefix_key, next_version_prefix_key;
-  InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  std::string start_key = InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  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();
 
   int removed_subkey = 0;
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
@@ -265,8 +260,7 @@ rocksdb::Status ZSet::RangeByRank(const Slice &user_key, 
const RangeRankSpec &sp
     GetDouble(&score_key, &score);
     if (count >= start) {
       if (spec.with_deletion) {
-        std::string sub_key;
-        InternalKey(ns_key, score_key, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+        std::string sub_key = InternalKey(ns_key, score_key, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
         batch->Delete(sub_key);
         batch->Delete(score_cf_handle_, iter->key());
         removed_subkey++;
@@ -296,8 +290,7 @@ rocksdb::Status ZSet::RangeByScore(const Slice &user_key, 
const RangeScoreSpec &
   if (!removed_cnt) removed_cnt = &cnt;
   *removed_cnt = 0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   std::optional<LockGuard> lock_guard;
   if (spec.with_deletion) lock_guard.emplace(storage_->GetLockManager(), 
ns_key);
@@ -344,10 +337,11 @@ rocksdb::Status ZSet::RangeByScore(const Slice &user_key, 
const RangeScoreSpec &
 
   std::string start_score_bytes;
   PutDouble(&start_score_bytes, spec.reversed ? (spec.maxex ? spec.max : 
max_next_score) : spec.min);
-  std::string start_key, prefix_key, next_version_prefix_key;
-  InternalKey(ns_key, start_score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  std::string start_key =
+      InternalKey(ns_key, start_score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  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 = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -385,8 +379,7 @@ rocksdb::Status ZSet::RangeByScore(const Slice &user_key, 
const RangeScoreSpec &
     }
     if (spec.offset >= 0 && pos++ < spec.offset) continue;
     if (spec.with_deletion) {
-      std::string sub_key;
-      InternalKey(ns_key, score_key, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&sub_key);
+      std::string sub_key = InternalKey(ns_key, score_key, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
       batch->Delete(sub_key);
       batch->Delete(score_cf_handle_, iter->key());
     } else {
@@ -418,8 +411,7 @@ rocksdb::Status ZSet::RangeByLex(const Slice &user_key, 
const RangeLexSpec &spec
     return rocksdb::Status::OK();
   }
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   std::optional<LockGuard> lock_guard;
   if (spec.with_deletion) {
@@ -430,10 +422,10 @@ rocksdb::Status ZSet::RangeByLex(const Slice &user_key, 
const RangeLexSpec &spec
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
   std::string start_member = spec.reversed ? spec.max : spec.min;
-  std::string start_key, prefix_key, next_version_prefix_key;
-  InternalKey(ns_key, start_member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  std::string start_key = InternalKey(ns_key, start_member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  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 = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
@@ -477,8 +469,7 @@ rocksdb::Status ZSet::RangeByLex(const Slice &user_key, 
const RangeLexSpec &spec
     if (spec.with_deletion) {
       std::string score_bytes = iter->value().ToString();
       score_bytes.append(member.data(), member.size());
-      std::string score_key;
-      InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&score_key);
+      std::string score_key = InternalKey(ns_key, score_bytes, 
metadata.version, storage_->IsSlotIdEncoded()).Encode();
       batch->Delete(score_cf_handle_, score_key);
       batch->Delete(iter->key());
     } else {
@@ -499,8 +490,7 @@ rocksdb::Status ZSet::RangeByLex(const Slice &user_key, 
const RangeLexSpec &spec
 }
 
 rocksdb::Status ZSet::Score(const Slice &user_key, const Slice &member, double 
*score) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   ZSetMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s;
@@ -509,8 +499,8 @@ rocksdb::Status ZSet::Score(const Slice &user_key, const 
Slice &member, double *
   LatestSnapShot ss(storage_);
   read_options.snapshot = ss.GetSnapShot();
 
-  std::string member_key, score_bytes;
-  InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&member_key);
+  std::string score_bytes;
+  std::string member_key = InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   s = storage_->Get(read_options, member_key, &score_bytes);
   if (!s.ok()) return s;
   *score = DecodeDouble(score_bytes.data());
@@ -519,8 +509,7 @@ rocksdb::Status ZSet::Score(const Slice &user_key, const 
Slice &member, double *
 
 rocksdb::Status ZSet::Remove(const Slice &user_key, const std::vector<Slice> 
&members, uint64_t *removed_cnt) {
   *removed_cnt = 0;
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ZSetMetadata metadata(false);
@@ -531,18 +520,17 @@ rocksdb::Status ZSet::Remove(const Slice &user_key, const 
std::vector<Slice> &me
   WriteBatchLogData log_data(kRedisZSet);
   batch->PutLogData(log_data.Encode());
   int removed = 0;
-  std::string member_key, score_key;
   std::unordered_set<std::string_view> mset;
   for (const auto &member : members) {
     if (!mset.insert(member.ToStringView()).second) {
       continue;
     }
-    InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&member_key);
+    std::string member_key = InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     std::string score_bytes;
     s = storage_->Get(rocksdb::ReadOptions(), member_key, &score_bytes);
     if (s.ok()) {
       score_bytes.append(member.data(), member.size());
-      InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&score_key);
+      std::string score_key = InternalKey(ns_key, score_bytes, 
metadata.version, storage_->IsSlotIdEncoded()).Encode();
       batch->Delete(member_key);
       batch->Delete(score_cf_handle_, score_key);
       removed++;
@@ -563,8 +551,7 @@ rocksdb::Status ZSet::Rank(const Slice &user_key, const 
Slice &member, bool reve
   *member_rank = -1;
   *member_score = 0.0;
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   ZSetMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
@@ -572,18 +559,20 @@ rocksdb::Status ZSet::Rank(const Slice &user_key, const 
Slice &member, bool reve
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   LatestSnapShot ss(storage_);
   read_options.snapshot = ss.GetSnapShot();
-  std::string score_bytes, member_key;
-  InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&member_key);
+  std::string score_bytes;
+  std::string member_key = InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
   s = storage_->Get(read_options, member_key, &score_bytes);
   if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s;
 
   double target_score = DecodeDouble(score_bytes.data());
-  std::string start_score_bytes, start_key, prefix_key, 
next_version_prefix_key;
+  std::string start_score_bytes;
   double start_score = !reversed ? kMinScore : kMaxScore;
   PutDouble(&start_score_bytes, start_score);
-  InternalKey(ns_key, start_score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&start_key);
-  InternalKey(ns_key, "", metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&prefix_key);
-  InternalKey(ns_key, "", metadata.version + 1, 
storage_->IsSlotIdEncoded()).Encode(&next_version_prefix_key);
+  std::string start_key =
+      InternalKey(ns_key, start_score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  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();
 
   int rank = 0;
   rocksdb::Slice upper_bound(next_version_prefix_key);
@@ -612,8 +601,7 @@ rocksdb::Status ZSet::Rank(const Slice &user_key, const 
Slice &member, bool reve
 }
 
 rocksdb::Status ZSet::Overwrite(const Slice &user_key, const MemberScores 
&mscores) {
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
 
   LockGuard guard(storage_->GetLockManager(), ns_key);
   ZSetMetadata metadata;
@@ -621,12 +609,12 @@ rocksdb::Status ZSet::Overwrite(const Slice &user_key, 
const MemberScores &mscor
   WriteBatchLogData log_data(kRedisZSet);
   batch->PutLogData(log_data.Encode());
   for (const auto &ms : mscores) {
-    std::string member_key, score_bytes, score_key;
-    InternalKey(ns_key, ms.member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&member_key);
+    std::string score_bytes;
+    std::string member_key = InternalKey(ns_key, ms.member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     PutDouble(&score_bytes, ms.score);
     batch->Put(member_key, score_bytes);
     score_bytes.append(ms.member);
-    InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&score_key);
+    std::string score_key = InternalKey(ns_key, score_bytes, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     batch->Put(score_cf_handle_, score_key, Slice());
   }
   metadata.size = static_cast<uint32_t>(mscores.size());
@@ -775,8 +763,7 @@ rocksdb::Status ZSet::MGet(const Slice &user_key, const 
std::vector<Slice> &memb
                            std::map<std::string, double> *mscores) {
   mscores->clear();
 
-  std::string ns_key;
-  AppendNamespacePrefix(user_key, &ns_key);
+  std::string ns_key = AppendNamespacePrefix(user_key);
   ZSetMetadata metadata(false);
   rocksdb::Status s = GetMetadata(ns_key, &metadata);
   if (!s.ok()) return s;
@@ -784,9 +771,9 @@ rocksdb::Status ZSet::MGet(const Slice &user_key, const 
std::vector<Slice> &memb
   rocksdb::ReadOptions read_options;
   LatestSnapShot ss(storage_);
   read_options.snapshot = ss.GetSnapShot();
-  std::string score_bytes, member_key;
+  std::string score_bytes;
   for (const auto &member : members) {
-    InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode(&member_key);
+    std::string member_key = InternalKey(ns_key, member, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
     score_bytes.clear();
     s = storage_->Get(read_options, member_key, &score_bytes);
     if (!s.ok() && !s.IsNotFound()) return s;
diff --git a/tests/cppunit/compact_test.cc b/tests/cppunit/compact_test.cc
index 004dd69d..b8499720 100644
--- a/tests/cppunit/compact_test.cc
+++ b/tests/cppunit/compact_test.cc
@@ -61,9 +61,8 @@ TEST(Compact, Filter) {
 
   auto iter = new_iterator("metadata");
   for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
-    std::string user_key, user_ns;
-    ExtractNamespaceKey(iter->key(), &user_ns, &user_key, 
storage->IsSlotIdEncoded());
-    EXPECT_EQ(user_key, live_hash_key);
+    auto [user_ns, user_key] = ExtractNamespaceKey(iter->key(), 
storage->IsSlotIdEncoded());
+    EXPECT_EQ(user_key.ToString(), live_hash_key);
   }
 
   iter = new_iterator("subkey");
diff --git a/tests/cppunit/metadata_test.cc b/tests/cppunit/metadata_test.cc
index a463bc20..e5b2963e 100644
--- a/tests/cppunit/metadata_test.cc
+++ b/tests/cppunit/metadata_test.cc
@@ -32,15 +32,12 @@ TEST(InternalKey, EncodeAndDecode) {
   Slice sub_key = "test-metadata-sub-key";
   Slice ns = "namespace";
   uint64_t version = 12;
-  std::string ns_key;
-
-  ComposeNamespaceKey(ns, key, &ns_key, false);
+  std::string ns_key = ComposeNamespaceKey(ns, key, false);
   InternalKey ikey(ns_key, sub_key, version, false);
   ASSERT_EQ(ikey.GetKey(), key);
   ASSERT_EQ(ikey.GetSubKey(), sub_key);
   ASSERT_EQ(ikey.GetVersion(), version);
-  std::string bytes;
-  ikey.Encode(&bytes);
+  std::string bytes = ikey.Encode();
   InternalKey ikey1(bytes, false);
   EXPECT_EQ(ikey, ikey1);
 }
@@ -92,8 +89,7 @@ TEST_F(RedisTypeTest, GetMetadata) {
   rocksdb::Status s = hash_->MSet(key_, fvs, false, &ret);
   EXPECT_TRUE(s.ok() && fvs.size() == ret);
   HashMetadata metadata;
-  std::string ns_key;
-  redis_->AppendNamespacePrefix(key_, &ns_key);
+  std::string ns_key = redis_->AppendNamespacePrefix(key_);
   redis_->GetMetadata(kRedisHash, ns_key, &metadata);
   EXPECT_EQ(fvs.size(), metadata.size);
   s = redis_->Del(key_);
diff --git a/utils/kvrocks2redis/parser.cc b/utils/kvrocks2redis/parser.cc
index f477c819..a06acf8a 100644
--- a/utils/kvrocks2redis/parser.cc
+++ b/utils/kvrocks2redis/parser.cc
@@ -61,8 +61,7 @@ Status Parser::ParseFullDB() {
 }
 
 Status Parser::parseSimpleKV(const Slice &ns_key, const Slice &value, uint64_t 
expire) {
-  std::string ns, user_key;
-  ExtractNamespaceKey(ns_key, &ns, &user_key, slot_id_encoded_);
+  auto [ns, user_key] = ExtractNamespaceKey<std::string>(ns_key, 
slot_id_encoded_);
 
   auto command =
       redis::Command2RESP({"SET", user_key, 
value.ToString().substr(Metadata::GetOffsetAfterExpire(value[0]))});
@@ -83,12 +82,9 @@ Status Parser::parseComplexKV(const Slice &ns_key, const 
Metadata &metadata) {
     return {Status::NotOK, "unknown metadata type: " + std::to_string(type)};
   }
 
-  std::string ns, user_key;
-  ExtractNamespaceKey(ns_key, &ns, &user_key, slot_id_encoded_);
-  std::string prefix_key;
-  InternalKey(ns_key, "", metadata.version, 
slot_id_encoded_).Encode(&prefix_key);
-  std::string next_version_prefix_key;
-  InternalKey(ns_key, "", metadata.version + 1, 
slot_id_encoded_).Encode(&next_version_prefix_key);
+  auto [ns, user_key] = ExtractNamespaceKey<std::string>(ns_key, 
slot_id_encoded_);
+  std::string prefix_key = InternalKey(ns_key, "", metadata.version, 
slot_id_encoded_).Encode();
+  std::string next_version_prefix_key = InternalKey(ns_key, "", 
metadata.version + 1, slot_id_encoded_).Encode();
 
   rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
   read_options.snapshot = latest_snapshot_->GetSnapShot();

Reply via email to