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