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.

137 lines
3.7 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 "leveldb/db.h"
  5. #include "db/memtable.h"
  6. #include "db/write_batch_internal.h"
  7. #include "leveldb/env.h"
  8. #include "util/logging.h"
  9. #include "util/testharness.h"
  10. namespace leveldb {
  11. static std::string PrintContents(WriteBatch* b) {
  12. InternalKeyComparator cmp(BytewiseComparator());
  13. MemTable* mem = new MemTable(cmp);
  14. mem->Ref();
  15. std::string state;
  16. Status s = WriteBatchInternal::InsertInto(b, mem);
  17. int count = 0;
  18. Iterator* iter = mem->NewIterator();
  19. for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
  20. ParsedInternalKey ikey;
  21. ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey));
  22. switch (ikey.type) {
  23. case kTypeValue:
  24. state.append("Put(");
  25. state.append(ikey.user_key.ToString());
  26. state.append(", ");
  27. state.append(iter->value().ToString());
  28. state.append(")");
  29. count++;
  30. break;
  31. case kTypeDeletion:
  32. state.append("Delete(");
  33. state.append(ikey.user_key.ToString());
  34. state.append(")");
  35. count++;
  36. break;
  37. }
  38. state.append("@");
  39. state.append(NumberToString(ikey.sequence));
  40. }
  41. delete iter;
  42. if (!s.ok()) {
  43. state.append("ParseError()");
  44. } else if (count != WriteBatchInternal::Count(b)) {
  45. state.append("CountMismatch()");
  46. }
  47. mem->Unref();
  48. return state;
  49. }
  50. class WriteBatchTest {};
  51. TEST(WriteBatchTest, Empty) {
  52. WriteBatch batch;
  53. ASSERT_EQ("", PrintContents(&batch));
  54. ASSERT_EQ(0, WriteBatchInternal::Count(&batch));
  55. }
  56. TEST(WriteBatchTest, Multiple) {
  57. WriteBatch batch;
  58. batch.Put(Slice("foo"), Slice("bar"));
  59. batch.Delete(Slice("box"));
  60. batch.Put(Slice("baz"), Slice("boo"));
  61. WriteBatchInternal::SetSequence(&batch, 100);
  62. ASSERT_EQ(100, WriteBatchInternal::Sequence(&batch));
  63. ASSERT_EQ(3, WriteBatchInternal::Count(&batch));
  64. ASSERT_EQ(
  65. "Put(baz, boo)@102"
  66. "Delete(box)@101"
  67. "Put(foo, bar)@100",
  68. PrintContents(&batch));
  69. }
  70. TEST(WriteBatchTest, Corruption) {
  71. WriteBatch batch;
  72. batch.Put(Slice("foo"), Slice("bar"));
  73. batch.Delete(Slice("box"));
  74. WriteBatchInternal::SetSequence(&batch, 200);
  75. Slice contents = WriteBatchInternal::Contents(&batch);
  76. WriteBatchInternal::SetContents(&batch,
  77. Slice(contents.data(), contents.size() - 1));
  78. ASSERT_EQ(
  79. "Put(foo, bar)@200"
  80. "ParseError()",
  81. PrintContents(&batch));
  82. }
  83. TEST(WriteBatchTest, Append) {
  84. WriteBatch b1, b2;
  85. WriteBatchInternal::SetSequence(&b1, 200);
  86. WriteBatchInternal::SetSequence(&b2, 300);
  87. b1.Append(b2);
  88. ASSERT_EQ("", PrintContents(&b1));
  89. b2.Put("a", "va");
  90. b1.Append(b2);
  91. ASSERT_EQ("Put(a, va)@200", PrintContents(&b1));
  92. b2.Clear();
  93. b2.Put("b", "vb");
  94. b1.Append(b2);
  95. ASSERT_EQ(
  96. "Put(a, va)@200"
  97. "Put(b, vb)@201",
  98. PrintContents(&b1));
  99. b2.Delete("foo");
  100. b1.Append(b2);
  101. ASSERT_EQ(
  102. "Put(a, va)@200"
  103. "Put(b, vb)@202"
  104. "Put(b, vb)@201"
  105. "Delete(foo)@203",
  106. PrintContents(&b1));
  107. }
  108. TEST(WriteBatchTest, ApproximateSize) {
  109. WriteBatch batch;
  110. size_t empty_size = batch.ApproximateSize();
  111. batch.Put(Slice("foo"), Slice("bar"));
  112. size_t one_key_size = batch.ApproximateSize();
  113. ASSERT_LT(empty_size, one_key_size);
  114. batch.Put(Slice("baz"), Slice("boo"));
  115. size_t two_keys_size = batch.ApproximateSize();
  116. ASSERT_LT(one_key_size, two_keys_size);
  117. batch.Delete(Slice("box"));
  118. size_t post_delete_size = batch.ApproximateSize();
  119. ASSERT_LT(two_keys_size, post_delete_size);
  120. }
  121. } // namespace leveldb
  122. int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }