小组成员:谢瑞阳、徐翔宇
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
4.3 KiB

  1. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. #include "db/dbformat.h"
  5. #include "gtest/gtest.h"
  6. #include "util/logging.h"
  7. namespace leveldb {
  8. static std::string IKey(const std::string& user_key, uint64_t seq,
  9. ValueType vt) {
  10. std::string encoded;
  11. AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt));
  12. return encoded;
  13. }
  14. static std::string Shorten(const std::string& s, const std::string& l) {
  15. std::string result = s;
  16. InternalKeyComparator(BytewiseComparator()).FindShortestSeparator(&result, l);
  17. return result;
  18. }
  19. static std::string ShortSuccessor(const std::string& s) {
  20. std::string result = s;
  21. InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result);
  22. return result;
  23. }
  24. static void TestKey(const std::string& key, uint64_t seq, ValueType vt) {
  25. std::string encoded = IKey(key, seq, vt);
  26. Slice in(encoded);
  27. ParsedInternalKey decoded("", 0, kTypeValue);
  28. ASSERT_TRUE(ParseInternalKey(in, &decoded));
  29. ASSERT_EQ(key, decoded.user_key.ToString());
  30. ASSERT_EQ(seq, decoded.sequence);
  31. ASSERT_EQ(vt, decoded.type);
  32. ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded));
  33. }
  34. TEST(FormatTest, InternalKey_EncodeDecode) {
  35. const char* keys[] = {"", "k", "hello", "longggggggggggggggggggggg"};
  36. const uint64_t seq[] = {1,
  37. 2,
  38. 3,
  39. (1ull << 8) - 1,
  40. 1ull << 8,
  41. (1ull << 8) + 1,
  42. (1ull << 16) - 1,
  43. 1ull << 16,
  44. (1ull << 16) + 1,
  45. (1ull << 32) - 1,
  46. 1ull << 32,
  47. (1ull << 32) + 1};
  48. for (int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) {
  49. for (int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) {
  50. TestKey(keys[k], seq[s], kTypeValue);
  51. TestKey("hello", 1, kTypeDeletion);
  52. }
  53. }
  54. }
  55. TEST(FormatTest, InternalKey_DecodeFromEmpty) {
  56. InternalKey internal_key;
  57. ASSERT_TRUE(!internal_key.DecodeFrom(""));
  58. }
  59. TEST(FormatTest, InternalKeyShortSeparator) {
  60. // When user keys are same
  61. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  62. Shorten(IKey("foo", 100, kTypeValue), IKey("foo", 99, kTypeValue)));
  63. ASSERT_EQ(
  64. IKey("foo", 100, kTypeValue),
  65. Shorten(IKey("foo", 100, kTypeValue), IKey("foo", 101, kTypeValue)));
  66. ASSERT_EQ(
  67. IKey("foo", 100, kTypeValue),
  68. Shorten(IKey("foo", 100, kTypeValue), IKey("foo", 100, kTypeValue)));
  69. ASSERT_EQ(
  70. IKey("foo", 100, kTypeValue),
  71. Shorten(IKey("foo", 100, kTypeValue), IKey("foo", 100, kTypeDeletion)));
  72. // When user keys are misordered
  73. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  74. Shorten(IKey("foo", 100, kTypeValue), IKey("bar", 99, kTypeValue)));
  75. // When user keys are different, but correctly ordered
  76. ASSERT_EQ(
  77. IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
  78. Shorten(IKey("foo", 100, kTypeValue), IKey("hello", 200, kTypeValue)));
  79. // When start user key is prefix of limit user key
  80. ASSERT_EQ(
  81. IKey("foo", 100, kTypeValue),
  82. Shorten(IKey("foo", 100, kTypeValue), IKey("foobar", 200, kTypeValue)));
  83. // When limit user key is prefix of start user key
  84. ASSERT_EQ(
  85. IKey("foobar", 100, kTypeValue),
  86. Shorten(IKey("foobar", 100, kTypeValue), IKey("foo", 200, kTypeValue)));
  87. }
  88. TEST(FormatTest, InternalKeyShortestSuccessor) {
  89. ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
  90. ShortSuccessor(IKey("foo", 100, kTypeValue)));
  91. ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue),
  92. ShortSuccessor(IKey("\xff\xff", 100, kTypeValue)));
  93. }
  94. TEST(FormatTest, ParsedInternalKeyDebugString) {
  95. ParsedInternalKey key("The \"key\" in 'single quotes'", 42, kTypeValue);
  96. ASSERT_EQ("'The \"key\" in 'single quotes'' @ 42 : 1", key.DebugString());
  97. }
  98. TEST(FormatTest, InternalKeyDebugString) {
  99. InternalKey key("The \"key\" in 'single quotes'", 42, kTypeValue);
  100. ASSERT_EQ("'The \"key\" in 'single quotes'' @ 42 : 1", key.DebugString());
  101. InternalKey invalid_key;
  102. ASSERT_EQ("(bad)", invalid_key.DebugString());
  103. }
  104. } // namespace leveldb
  105. int main(int argc, char** argv) {
  106. testing::InitGoogleTest(&argc, argv);
  107. return RUN_ALL_TESTS();
  108. }