git / moonbite-core / src/leveldb/db/write_batch_test.cc · raw

// Copyright (c) 2011 The LevelDB Authors. All rights reserved.// Use of this source code is governed by a BSD-style license that can be// found in the LICENSE file. See the AUTHORS file for names of contributors.#include "leveldb/db.h"#include "db/memtable.h"#include "db/write_batch_internal.h"#include "leveldb/env.h"#include "util/logging.h"#include "util/testharness.h"namespace leveldb {static std::string PrintContents(WriteBatch* b) {  InternalKeyComparator cmp(BytewiseComparator());  MemTable* mem = new MemTable(cmp);  mem->Ref();  std::string state;  Status s = WriteBatchInternal::InsertInto(b, mem);  int count = 0;  Iterator* iter = mem->NewIterator();  for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {    ParsedInternalKey ikey;    ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey));    switch (ikey.type) {      case kTypeValue:        state.append("Put(");        state.append(ikey.user_key.ToString());        state.append(", ");        state.append(iter->value().ToString());        state.append(")");        count++;        break;      case kTypeDeletion:        state.append("Delete(");        state.append(ikey.user_key.ToString());        state.append(")");        count++;        break;    }    state.append("@");    state.append(NumberToString(ikey.sequence));  }  delete iter;  if (!s.ok()) {    state.append("ParseError()");  } else if (count != WriteBatchInternal::Count(b)) {    state.append("CountMismatch()");  }  mem->Unref();  return state;}class WriteBatchTest {};TEST(WriteBatchTest, Empty) {  WriteBatch batch;  ASSERT_EQ("", PrintContents(&batch));  ASSERT_EQ(0, WriteBatchInternal::Count(&batch));}TEST(WriteBatchTest, Multiple) {  WriteBatch batch;  batch.Put(Slice("foo"), Slice("bar"));  batch.Delete(Slice("box"));  batch.Put(Slice("baz"), Slice("boo"));  WriteBatchInternal::SetSequence(&batch, 100);  ASSERT_EQ(100, WriteBatchInternal::Sequence(&batch));  ASSERT_EQ(3, WriteBatchInternal::Count(&batch));  ASSERT_EQ(      "Put(baz, boo)@102"      "Delete(box)@101"      "Put(foo, bar)@100",      PrintContents(&batch));}TEST(WriteBatchTest, Corruption) {  WriteBatch batch;  batch.Put(Slice("foo"), Slice("bar"));  batch.Delete(Slice("box"));  WriteBatchInternal::SetSequence(&batch, 200);  Slice contents = WriteBatchInternal::Contents(&batch);  WriteBatchInternal::SetContents(&batch,                                  Slice(contents.data(), contents.size() - 1));  ASSERT_EQ(      "Put(foo, bar)@200"      "ParseError()",      PrintContents(&batch));}TEST(WriteBatchTest, Append) {  WriteBatch b1, b2;  WriteBatchInternal::SetSequence(&b1, 200);  WriteBatchInternal::SetSequence(&b2, 300);  b1.Append(b2);  ASSERT_EQ("", PrintContents(&b1));  b2.Put("a", "va");  b1.Append(b2);  ASSERT_EQ("Put(a, va)@200", PrintContents(&b1));  b2.Clear();  b2.Put("b", "vb");  b1.Append(b2);  ASSERT_EQ(      "Put(a, va)@200"      "Put(b, vb)@201",      PrintContents(&b1));  b2.Delete("foo");  b1.Append(b2);  ASSERT_EQ(      "Put(a, va)@200"      "Put(b, vb)@202"      "Put(b, vb)@201"      "Delete(foo)@203",      PrintContents(&b1));}TEST(WriteBatchTest, ApproximateSize) {  WriteBatch batch;  size_t empty_size = batch.ApproximateSize();  batch.Put(Slice("foo"), Slice("bar"));  size_t one_key_size = batch.ApproximateSize();  ASSERT_LT(empty_size, one_key_size);  batch.Put(Slice("baz"), Slice("boo"));  size_t two_keys_size = batch.ApproximateSize();  ASSERT_LT(one_key_size, two_keys_size);  batch.Delete(Slice("box"));  size_t post_delete_size = batch.ApproximateSize();  ASSERT_LT(two_keys_size, post_delete_size);}}  // namespace leveldbint main(int argc, char** argv) { return leveldb::test::RunAllTests(); }