小组成员:谢瑞阳、徐翔宇
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.

127 lines
4.4 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 "util/logging.h"
  6. #include "util/testharness.h"
  7. namespace leveldb {
  8. static std::string IKey(const std::string& user_key,
  9. uint64_t seq,
  10. ValueType vt) {
  11. std::string encoded;
  12. AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt));
  13. return encoded;
  14. }
  15. static std::string Shorten(const std::string& s, const std::string& l) {
  16. std::string result = s;
  17. InternalKeyComparator(BytewiseComparator()).FindShortestSeparator(&result, l);
  18. return result;
  19. }
  20. static std::string ShortSuccessor(const std::string& s) {
  21. std::string result = s;
  22. InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result);
  23. return result;
  24. }
  25. static void TestKey(const std::string& key,
  26. uint64_t seq,
  27. ValueType vt) {
  28. std::string encoded = IKey(key, seq, vt);
  29. Slice in(encoded);
  30. ParsedInternalKey decoded("", 0, kTypeValue);
  31. ASSERT_TRUE(ParseInternalKey(in, &decoded));
  32. ASSERT_EQ(key, decoded.user_key.ToString());
  33. ASSERT_EQ(seq, decoded.sequence);
  34. ASSERT_EQ(vt, decoded.type);
  35. ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded));
  36. }
  37. class FormatTest { };
  38. TEST(FormatTest, InternalKey_EncodeDecode) {
  39. const char* keys[] = { "", "k", "hello", "longggggggggggggggggggggg" };
  40. const uint64_t seq[] = {
  41. 1, 2, 3,
  42. (1ull << 8) - 1, 1ull << 8, (1ull << 8) + 1,
  43. (1ull << 16) - 1, 1ull << 16, (1ull << 16) + 1,
  44. (1ull << 32) - 1, 1ull << 32, (1ull << 32) + 1
  45. };
  46. for (int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) {
  47. for (int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) {
  48. TestKey(keys[k], seq[s], kTypeValue);
  49. TestKey("hello", 1, kTypeDeletion);
  50. }
  51. }
  52. }
  53. TEST(FormatTest, InternalKeyShortSeparator) {
  54. // When user keys are same
  55. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  56. Shorten(IKey("foo", 100, kTypeValue),
  57. IKey("foo", 99, kTypeValue)));
  58. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  59. Shorten(IKey("foo", 100, kTypeValue),
  60. IKey("foo", 101, kTypeValue)));
  61. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  62. Shorten(IKey("foo", 100, kTypeValue),
  63. IKey("foo", 100, kTypeValue)));
  64. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  65. Shorten(IKey("foo", 100, kTypeValue),
  66. IKey("foo", 100, kTypeDeletion)));
  67. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  68. Shorten(IKey("foo", 100, kTypeValue),
  69. IKey("foo", 100, kTypeLargeValueRef)));
  70. // When user keys are misordered
  71. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  72. Shorten(IKey("foo", 100, kTypeValue),
  73. IKey("bar", 99, kTypeValue)));
  74. // When user keys are different, but correctly ordered
  75. ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
  76. Shorten(IKey("foo", 100, kTypeValue),
  77. IKey("hello", 200, kTypeValue)));
  78. // When start user key is prefix of limit user key
  79. ASSERT_EQ(IKey("foo", 100, kTypeValue),
  80. Shorten(IKey("foo", 100, kTypeValue),
  81. IKey("foobar", 200, kTypeValue)));
  82. // When limit user key is prefix of start user key
  83. ASSERT_EQ(IKey("foobar", 100, kTypeValue),
  84. Shorten(IKey("foobar", 100, kTypeValue),
  85. IKey("foo", 200, kTypeValue)));
  86. }
  87. TEST(FormatTest, InternalKeyShortestSuccessor) {
  88. ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
  89. ShortSuccessor(IKey("foo", 100, kTypeValue)));
  90. ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue),
  91. ShortSuccessor(IKey("\xff\xff", 100, kTypeValue)));
  92. }
  93. TEST(FormatTest, SHA1) {
  94. // Check that we are computing the same value as sha1.
  95. // Note that the last two numbers are the length of the input and the
  96. // compression type.
  97. ASSERT_EQ("aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d-5-0", // SHA1, uncompr
  98. LargeValueRefToFilenameString(
  99. LargeValueRef::Make("hello", kNoCompression)));
  100. ASSERT_EQ("aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d-5-1", // SHA1, lwcompr
  101. LargeValueRefToFilenameString(
  102. LargeValueRef::Make("hello", kLightweightCompression)));
  103. }
  104. }
  105. int main(int argc, char** argv) {
  106. return leveldb::test::RunAllTests();
  107. }