write_batch_test.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 "gtest/gtest.h"
  5. #include "db/memtable.h"
  6. #include "db/write_batch_internal.h"
  7. #include "leveldb/db.h"
  8. #include "leveldb/env.h"
  9. #include "util/logging.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. EXPECT_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. TEST(WriteBatchTest, Empty) {
  51. WriteBatch batch;
  52. ASSERT_EQ("", PrintContents(&batch));
  53. ASSERT_EQ(0, WriteBatchInternal::Count(&batch));
  54. }
  55. TEST(WriteBatchTest, Multiple) {
  56. WriteBatch batch;
  57. batch.Put(Slice("foo"), Slice("bar"));
  58. batch.Delete(Slice("box"));
  59. batch.Put(Slice("baz"), Slice("boo"));
  60. WriteBatchInternal::SetSequence(&batch, 100);
  61. ASSERT_EQ(100, WriteBatchInternal::Sequence(&batch));
  62. ASSERT_EQ(3, WriteBatchInternal::Count(&batch));
  63. ASSERT_EQ(
  64. "Put(baz, boo)@102"
  65. "Delete(box)@101"
  66. "Put(foo, bar)@100",
  67. PrintContents(&batch));
  68. }
  69. TEST(WriteBatchTest, Corruption) {
  70. WriteBatch batch;
  71. batch.Put(Slice("foo"), Slice("bar"));
  72. batch.Delete(Slice("box"));
  73. WriteBatchInternal::SetSequence(&batch, 200);
  74. Slice contents = WriteBatchInternal::Contents(&batch);
  75. WriteBatchInternal::SetContents(&batch,
  76. Slice(contents.data(), contents.size() - 1));
  77. ASSERT_EQ(
  78. "Put(foo, bar)@200"
  79. "ParseError()",
  80. PrintContents(&batch));
  81. }
  82. TEST(WriteBatchTest, Append) {
  83. WriteBatch b1, b2;
  84. WriteBatchInternal::SetSequence(&b1, 200);
  85. WriteBatchInternal::SetSequence(&b2, 300);
  86. b1.Append(b2);
  87. ASSERT_EQ("", PrintContents(&b1));
  88. b2.Put("a", "va");
  89. b1.Append(b2);
  90. ASSERT_EQ("Put(a, va)@200", PrintContents(&b1));
  91. b2.Clear();
  92. b2.Put("b", "vb");
  93. b1.Append(b2);
  94. ASSERT_EQ(
  95. "Put(a, va)@200"
  96. "Put(b, vb)@201",
  97. PrintContents(&b1));
  98. b2.Delete("foo");
  99. b1.Append(b2);
  100. ASSERT_EQ(
  101. "Put(a, va)@200"
  102. "Put(b, vb)@202"
  103. "Put(b, vb)@201"
  104. "Delete(foo)@203",
  105. PrintContents(&b1));
  106. }
  107. TEST(WriteBatchTest, ApproximateSize) {
  108. WriteBatch batch;
  109. size_t empty_size = batch.ApproximateSize();
  110. batch.Put(Slice("foo"), Slice("bar"));
  111. size_t one_key_size = batch.ApproximateSize();
  112. ASSERT_LT(empty_size, one_key_size);
  113. batch.Put(Slice("baz"), Slice("boo"));
  114. size_t two_keys_size = batch.ApproximateSize();
  115. ASSERT_LT(one_key_size, two_keys_size);
  116. batch.Delete(Slice("box"));
  117. size_t post_delete_size = batch.ApproximateSize();
  118. ASSERT_LT(two_keys_size, post_delete_size);
  119. }
  120. } // namespace leveldb