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