diff --git a/db/db_basic_test.cc b/db/db_basic_test.cc index 2fda22cc3b40acec605dbbfd88eb505f565b6af2..6b5f61c96b8a8b0cafbacf19179e0aa6ecba72a6 100644 --- a/db/db_basic_test.cc +++ b/db/db_basic_test.cc @@ -2618,13 +2618,20 @@ TEST_F(DBBasicTest, GetAllKeyVersions) { ASSERT_OK(Delete(std::to_string(i))); } std::vector key_versions; - ASSERT_OK(ROCKSDB_NAMESPACE::GetAllKeyVersions( - db_, Slice(), Slice(), std::numeric_limits::max(), - &key_versions)); + ASSERT_OK(GetAllKeyVersions(db_, Slice(), Slice(), + std::numeric_limits::max(), + &key_versions)); ASSERT_EQ(kNumInserts + kNumDeletes + kNumUpdates, key_versions.size()); - ASSERT_OK(ROCKSDB_NAMESPACE::GetAllKeyVersions( - db_, handles_[0], Slice(), Slice(), std::numeric_limits::max(), - &key_versions)); + for (size_t i = 0; i < kNumInserts + kNumDeletes + kNumUpdates; i++) { + if (i % 3 == 0) { + ASSERT_EQ(key_versions[i].GetTypeName(), "TypeDeletion"); + } else { + ASSERT_EQ(key_versions[i].GetTypeName(), "TypeValue"); + } + } + ASSERT_OK(GetAllKeyVersions(db_, handles_[0], Slice(), Slice(), + std::numeric_limits::max(), + &key_versions)); ASSERT_EQ(kNumInserts + kNumDeletes + kNumUpdates, key_versions.size()); // Check non-default column family @@ -2637,11 +2644,21 @@ TEST_F(DBBasicTest, GetAllKeyVersions) { for (size_t i = 0; i + 1 != kNumDeletes; ++i) { ASSERT_OK(Delete(1, std::to_string(i))); } - ASSERT_OK(ROCKSDB_NAMESPACE::GetAllKeyVersions( - db_, handles_[1], Slice(), Slice(), std::numeric_limits::max(), - &key_versions)); + ASSERT_OK(GetAllKeyVersions(db_, handles_[1], Slice(), Slice(), + std::numeric_limits::max(), + &key_versions)); ASSERT_EQ(kNumInserts + kNumDeletes + kNumUpdates - 3, key_versions.size()); } + +TEST_F(DBBasicTest, ValueTypeString) { + KeyVersion key_version; + // when adding new type, please also update `value_type_string_map` + for (unsigned char i = ValueType::kTypeDeletion; i < ValueType::kTypeMaxValid; + i++) { + key_version.type = i; + ASSERT_TRUE(key_version.GetTypeName() != "Invalid"); + } +} #endif // !ROCKSDB_LITE TEST_F(DBBasicTest, MultiGetIOBufferOverrun) { diff --git a/db/dbformat.h b/db/dbformat.h index 83bc37d785740141f9cf2dd752e3603d966f70fe..51986d6af92c975cb68e176a132a3e19f2ded203 100644 --- a/db/dbformat.h +++ b/db/dbformat.h @@ -68,7 +68,9 @@ enum ValueType : unsigned char { kTypeCommitXIDAndTimestamp = 0x15, // WAL only kTypeWideColumnEntity = 0x16, kTypeColumnFamilyWideColumnEntity = 0x17, // WAL only - kMaxValue = 0x7F // Not used for storing records. + kTypeMaxValid, // Should be after the last valid type, only used for + // validation + kMaxValue = 0x7F // Not used for storing records. }; // Defined in dbformat.cc diff --git a/include/rocksdb/utilities/debug.h b/include/rocksdb/utilities/debug.h index a2b6adcb0474b6ef8e00530a21903ab34cc12eb9..0e05265573c57d8b4b8c2f5f02ea78ca219557bd 100644 --- a/include/rocksdb/utilities/debug.h +++ b/include/rocksdb/utilities/debug.h @@ -25,9 +25,8 @@ struct KeyVersion { std::string user_key; std::string value; SequenceNumber sequence; - // TODO(ajkr): we should provide a helper function that converts the int to a - // string describing the type for easier debugging. int type; + std::string GetTypeName() const; }; // Returns listing of all versions of keys in the provided user key range. diff --git a/utilities/debug.cc b/utilities/debug.cc index 247d717bae3176dcbd4094eecdb3ae4ac4586166..a33c95a6c34a8625e3b91d66989f6d9490e41d7c 100644 --- a/utilities/debug.cc +++ b/utilities/debug.cc @@ -8,9 +8,49 @@ #include "rocksdb/utilities/debug.h" #include "db/db_impl/db_impl.h" +#include "rocksdb/utilities/options_type.h" namespace ROCKSDB_NAMESPACE { +static std::unordered_map value_type_string_map = { + {"TypeDeletion", ValueType::kTypeDeletion}, + {"TypeValue", ValueType::kTypeValue}, + {"TypeMerge", ValueType::kTypeMerge}, + {"TypeLogData", ValueType::kTypeLogData}, + {"TypeColumnFamilyDeletion", ValueType::kTypeColumnFamilyDeletion}, + {"TypeColumnFamilyValue", ValueType::kTypeColumnFamilyValue}, + {"TypeColumnFamilyMerge", ValueType::kTypeColumnFamilyMerge}, + {"TypeSingleDeletion", ValueType::kTypeSingleDeletion}, + {"TypeColumnFamilySingleDeletion", + ValueType::kTypeColumnFamilySingleDeletion}, + {"TypeBeginPrepareXID", ValueType::kTypeBeginPrepareXID}, + {"TypeEndPrepareXID", ValueType::kTypeEndPrepareXID}, + {"TypeCommitXID", ValueType::kTypeCommitXID}, + {"TypeRollbackXID", ValueType::kTypeRollbackXID}, + {"TypeNoop", ValueType::kTypeNoop}, + {"TypeColumnFamilyRangeDeletion", + ValueType::kTypeColumnFamilyRangeDeletion}, + {"TypeRangeDeletion", ValueType::kTypeRangeDeletion}, + {"TypeColumnFamilyBlobIndex", ValueType::kTypeColumnFamilyBlobIndex}, + {"TypeBlobIndex", ValueType::kTypeBlobIndex}, + {"TypeBeginPersistedPrepareXID", ValueType::kTypeBeginPersistedPrepareXID}, + {"TypeBeginUnprepareXID", ValueType::kTypeBeginUnprepareXID}, + {"TypeDeletionWithTimestamp", ValueType::kTypeDeletionWithTimestamp}, + {"TypeCommitXIDAndTimestamp", ValueType::kTypeCommitXIDAndTimestamp}, + {"TypeWideColumnEntity", ValueType::kTypeWideColumnEntity}, + {"TypeColumnFamilyWideColumnEntity", + ValueType::kTypeColumnFamilyWideColumnEntity}}; + +std::string KeyVersion::GetTypeName() const { + std::string type_name; + if (SerializeEnum(value_type_string_map, + static_cast(type), &type_name)) { + return type_name; + } else { + return "Invalid"; + } +} + Status GetAllKeyVersions(DB* db, Slice begin_key, Slice end_key, size_t max_num_ikeys, std::vector* key_versions) {