Add further tests to ASSERT_STATUS_CHECKED (1) (#7679)

Summary:
First batch of adding more tests to ASSERT_STATUS_CHECKED.

* db_iterator_test
* db_memtable_test
* db_merge_operator_test
* db_merge_operand_test
* write_batch_test
* write_batch_with_index_test

Pull Request resolved: https://github.com/facebook/rocksdb/pull/7679

Reviewed By: ajkr

Differential Revision: D25399270

Pulled By: pdillinger

fbshipit-source-id: 3017d0a686aec5cd2d743fc2acbbf75df239f3ba
main
Adam Retter 4 years ago committed by Facebook GitHub Bot
parent 66e54c5984
commit 7b2216c906
  1. 6
      Makefile
  2. 106
      db/db_iterator_test.cc
  3. 5
      db/db_memtable_test.cc
  4. 94
      db/db_merge_operand_test.cc
  5. 29
      db/db_merge_operator_test.cc
  6. 10
      db/db_test_util.cc
  7. 8
      db/forward_iterator.cc
  8. 2
      db/write_batch_test.cc
  9. 403
      utilities/write_batch_with_index/write_batch_with_index_test.cc

@ -595,6 +595,10 @@ ifdef ASSERT_STATUS_CHECKED
db_basic_test \ db_basic_test \
db_blob_basic_test \ db_blob_basic_test \
db_flush_test \ db_flush_test \
db_iterator_test \
db_memtable_test \
db_merge_operand_test \
db_merge_operator_test \
db_with_timestamp_basic_test \ db_with_timestamp_basic_test \
db_with_timestamp_compaction_test \ db_with_timestamp_compaction_test \
db_options_test \ db_options_test \
@ -677,6 +681,8 @@ ifdef ASSERT_STATUS_CHECKED
import_column_family_test \ import_column_family_test \
memory_test \ memory_test \
table_test \ table_test \
write_batch_test \
write_batch_with_index_test \
ifeq ($(USE_FOLLY_DISTRIBUTED_MUTEX),1) ifeq ($(USE_FOLLY_DISTRIBUTED_MUTEX),1)
TESTS_PASSING_ASC += folly_synchronization_distributed_mutex_test TESTS_PASSING_ASC += folly_synchronization_distributed_mutex_test

@ -67,8 +67,8 @@ TEST_P(DBIteratorTest, IteratorProperty) {
// The test needs to be changed if kPersistedTier is supported in iterator. // The test needs to be changed if kPersistedTier is supported in iterator.
Options options = CurrentOptions(); Options options = CurrentOptions();
CreateAndReopenWithCF({"pikachu"}, options); CreateAndReopenWithCF({"pikachu"}, options);
Put(1, "1", "2"); ASSERT_OK(Put(1, "1", "2"));
Delete(1, "2"); ASSERT_OK(Delete(1, "2"));
ReadOptions ropt; ReadOptions ropt;
ropt.pin_data = false; ropt.pin_data = false;
{ {
@ -172,10 +172,10 @@ TEST_P(DBIteratorTest, NonBlockingIteration) {
TEST_P(DBIteratorTest, IterSeekBeforePrev) { TEST_P(DBIteratorTest, IterSeekBeforePrev) {
ASSERT_OK(Put("a", "b")); ASSERT_OK(Put("a", "b"));
ASSERT_OK(Put("c", "d")); ASSERT_OK(Put("c", "d"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("0", "f")); ASSERT_OK(Put("0", "f"));
ASSERT_OK(Put("1", "h")); ASSERT_OK(Put("1", "h"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("2", "j")); ASSERT_OK(Put("2", "j"));
auto iter = NewIterator(ReadOptions()); auto iter = NewIterator(ReadOptions());
iter->Seek(Slice("c")); iter->Seek(Slice("c"));
@ -199,7 +199,7 @@ TEST_P(DBIteratorTest, IterReseekNewUpperBound) {
ASSERT_OK(Put("aabb", rnd.RandomString(400))); ASSERT_OK(Put("aabb", rnd.RandomString(400)));
ASSERT_OK(Put("aaef", rnd.RandomString(400))); ASSERT_OK(Put("aaef", rnd.RandomString(400)));
ASSERT_OK(Put("b", rnd.RandomString(400))); ASSERT_OK(Put("b", rnd.RandomString(400)));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ReadOptions opts; ReadOptions opts;
Slice ub = Slice("aa"); Slice ub = Slice("aa");
opts.iterate_upper_bound = &ub; opts.iterate_upper_bound = &ub;
@ -215,10 +215,10 @@ TEST_P(DBIteratorTest, IterReseekNewUpperBound) {
TEST_P(DBIteratorTest, IterSeekForPrevBeforeNext) { TEST_P(DBIteratorTest, IterSeekForPrevBeforeNext) {
ASSERT_OK(Put("a", "b")); ASSERT_OK(Put("a", "b"));
ASSERT_OK(Put("c", "d")); ASSERT_OK(Put("c", "d"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("0", "f")); ASSERT_OK(Put("0", "f"));
ASSERT_OK(Put("1", "h")); ASSERT_OK(Put("1", "h"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("2", "j")); ASSERT_OK(Put("2", "j"));
auto iter = NewIterator(ReadOptions()); auto iter = NewIterator(ReadOptions());
iter->SeekForPrev(Slice("0")); iter->SeekForPrev(Slice("0"));
@ -238,7 +238,7 @@ TEST_P(DBIteratorTest, IterLongKeys) {
ASSERT_OK(Put(MakeLongKey(20, 0), "0")); ASSERT_OK(Put(MakeLongKey(20, 0), "0"));
ASSERT_OK(Put(MakeLongKey(32, 2), "2")); ASSERT_OK(Put(MakeLongKey(32, 2), "2"));
ASSERT_OK(Put("a", "b")); ASSERT_OK(Put("a", "b"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put(MakeLongKey(50, 1), "1")); ASSERT_OK(Put(MakeLongKey(50, 1), "1"));
ASSERT_OK(Put(MakeLongKey(127, 3), "3")); ASSERT_OK(Put(MakeLongKey(127, 3), "3"));
ASSERT_OK(Put(MakeLongKey(64, 4), "4")); ASSERT_OK(Put(MakeLongKey(64, 4), "4"));
@ -276,7 +276,7 @@ TEST_P(DBIteratorTest, IterLongKeys) {
TEST_P(DBIteratorTest, IterNextWithNewerSeq) { TEST_P(DBIteratorTest, IterNextWithNewerSeq) {
ASSERT_OK(Put("0", "0")); ASSERT_OK(Put("0", "0"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("a", "b")); ASSERT_OK(Put("a", "b"));
ASSERT_OK(Put("c", "d")); ASSERT_OK(Put("c", "d"));
ASSERT_OK(Put("d", "e")); ASSERT_OK(Put("d", "e"));
@ -302,7 +302,7 @@ TEST_P(DBIteratorTest, IterNextWithNewerSeq) {
TEST_P(DBIteratorTest, IterPrevWithNewerSeq) { TEST_P(DBIteratorTest, IterPrevWithNewerSeq) {
ASSERT_OK(Put("0", "0")); ASSERT_OK(Put("0", "0"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("a", "b")); ASSERT_OK(Put("a", "b"));
ASSERT_OK(Put("c", "d")); ASSERT_OK(Put("c", "d"));
ASSERT_OK(Put("d", "e")); ASSERT_OK(Put("d", "e"));
@ -333,7 +333,7 @@ TEST_P(DBIteratorTest, IterPrevWithNewerSeq) {
TEST_P(DBIteratorTest, IterPrevWithNewerSeq2) { TEST_P(DBIteratorTest, IterPrevWithNewerSeq2) {
ASSERT_OK(Put("0", "0")); ASSERT_OK(Put("0", "0"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("a", "b")); ASSERT_OK(Put("a", "b"));
ASSERT_OK(Put("c", "d")); ASSERT_OK(Put("c", "d"));
ASSERT_OK(Put("e", "f")); ASSERT_OK(Put("e", "f"));
@ -377,6 +377,8 @@ TEST_P(DBIteratorTest, IterEmpty) {
iter->SeekForPrev("foo"); iter->SeekForPrev("foo");
ASSERT_EQ(IterStatus(iter), "(invalid)"); ASSERT_EQ(IterStatus(iter), "(invalid)");
ASSERT_OK(iter->status());
delete iter; delete iter;
} while (ChangeCompactOptions()); } while (ChangeCompactOptions());
} }
@ -783,18 +785,18 @@ TEST_P(DBIteratorTest, IterWithSnapshot) {
TEST_P(DBIteratorTest, IteratorPinsRef) { TEST_P(DBIteratorTest, IteratorPinsRef) {
do { do {
CreateAndReopenWithCF({"pikachu"}, CurrentOptions()); CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
Put(1, "foo", "hello"); ASSERT_OK(Put(1, "foo", "hello"));
// Get iterator that will yield the current contents of the DB. // Get iterator that will yield the current contents of the DB.
Iterator* iter = NewIterator(ReadOptions(), handles_[1]); Iterator* iter = NewIterator(ReadOptions(), handles_[1]);
// Write to force compactions // Write to force compactions
Put(1, "foo", "newvalue1"); ASSERT_OK(Put(1, "foo", "newvalue1"));
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
// 100K values // 100K values
ASSERT_OK(Put(1, Key(i), Key(i) + std::string(100000, 'v'))); ASSERT_OK(Put(1, Key(i), Key(i) + std::string(100000, 'v')));
} }
Put(1, "foo", "newvalue2"); ASSERT_OK(Put(1, "foo", "newvalue2"));
iter->SeekToFirst(); iter->SeekToFirst();
ASSERT_TRUE(iter->Valid()); ASSERT_TRUE(iter->Valid());
@ -809,8 +811,8 @@ TEST_P(DBIteratorTest, IteratorPinsRef) {
TEST_P(DBIteratorTest, IteratorDeleteAfterCfDelete) { TEST_P(DBIteratorTest, IteratorDeleteAfterCfDelete) {
CreateAndReopenWithCF({"pikachu"}, CurrentOptions()); CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
Put(1, "foo", "delete-cf-then-delete-iter"); ASSERT_OK(Put(1, "foo", "delete-cf-then-delete-iter"));
Put(1, "hello", "value2"); ASSERT_OK(Put(1, "hello", "value2"));
ColumnFamilyHandle* cf = handles_[1]; ColumnFamilyHandle* cf = handles_[1];
ReadOptions ro; ReadOptions ro;
@ -820,7 +822,7 @@ TEST_P(DBIteratorTest, IteratorDeleteAfterCfDelete) {
ASSERT_EQ(IterStatus(iter), "foo->delete-cf-then-delete-iter"); ASSERT_EQ(IterStatus(iter), "foo->delete-cf-then-delete-iter");
// delete CF handle // delete CF handle
db_->DestroyColumnFamilyHandle(cf); EXPECT_OK(db_->DestroyColumnFamilyHandle(cf));
handles_.erase(std::begin(handles_) + 1); handles_.erase(std::begin(handles_) + 1);
// delete Iterator after CF handle is deleted // delete Iterator after CF handle is deleted
@ -832,7 +834,7 @@ TEST_P(DBIteratorTest, IteratorDeleteAfterCfDelete) {
TEST_P(DBIteratorTest, IteratorDeleteAfterCfDrop) { TEST_P(DBIteratorTest, IteratorDeleteAfterCfDrop) {
CreateAndReopenWithCF({"pikachu"}, CurrentOptions()); CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
Put(1, "foo", "drop-cf-then-delete-iter"); ASSERT_OK(Put(1, "foo", "drop-cf-then-delete-iter"));
ReadOptions ro; ReadOptions ro;
ColumnFamilyHandle* cf = handles_[1]; ColumnFamilyHandle* cf = handles_[1];
@ -842,8 +844,8 @@ TEST_P(DBIteratorTest, IteratorDeleteAfterCfDrop) {
ASSERT_EQ(IterStatus(iter), "foo->drop-cf-then-delete-iter"); ASSERT_EQ(IterStatus(iter), "foo->drop-cf-then-delete-iter");
// drop and delete CF // drop and delete CF
db_->DropColumnFamily(cf); EXPECT_OK(db_->DropColumnFamily(cf));
db_->DestroyColumnFamilyHandle(cf); EXPECT_OK(db_->DestroyColumnFamilyHandle(cf));
handles_.erase(std::begin(handles_) + 1); handles_.erase(std::begin(handles_) + 1);
// delete Iterator after CF handle is dropped // delete Iterator after CF handle is dropped
@ -1307,9 +1309,9 @@ TEST_P(DBIteratorTest, PrevAfterAndNextAfterMerge) {
// write three entries with different keys using Merge() // write three entries with different keys using Merge()
WriteOptions wopts; WriteOptions wopts;
db_->Merge(wopts, "1", "data1"); ASSERT_OK(db_->Merge(wopts, "1", "data1"));
db_->Merge(wopts, "2", "data2"); ASSERT_OK(db_->Merge(wopts, "2", "data2"));
db_->Merge(wopts, "3", "data3"); ASSERT_OK(db_->Merge(wopts, "3", "data3"));
std::unique_ptr<Iterator> it(NewIterator(ReadOptions())); std::unique_ptr<Iterator> it(NewIterator(ReadOptions()));
@ -1393,7 +1395,7 @@ class DBIteratorTestForPinnedData : public DBIteratorTest {
if (run_config == TestConfig::FLUSH_EVERY_1000) { if (run_config == TestConfig::FLUSH_EVERY_1000) {
if (i && i % 1000 == 0) { if (i && i % 1000 == 0) {
Flush(); ASSERT_OK(Flush());
} }
} }
} }
@ -1402,7 +1404,7 @@ class DBIteratorTestForPinnedData : public DBIteratorTest {
Close(); Close();
Reopen(options); Reopen(options);
} else if (run_config == TestConfig::COMPACT_BEFORE_READ) { } else if (run_config == TestConfig::COMPACT_BEFORE_READ) {
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
} }
ReadOptions ro; ReadOptions ro;
@ -1768,6 +1770,7 @@ TEST_P(DBIteratorTest, IterSeekForPrevCrossingFiles) {
Iterator* iter = NewIterator(ro); Iterator* iter = NewIterator(ro);
iter->SeekForPrev("c2"); iter->SeekForPrev("c2");
ASSERT_TRUE(!iter->Valid()); ASSERT_TRUE(!iter->Valid());
ASSERT_OK(iter->status());
delete iter; delete iter;
} }
} }
@ -1823,6 +1826,7 @@ TEST_P(DBIteratorTest, IterSeekForPrevCrossingFilesCustomPrefixExtractor) {
Iterator* iter = NewIterator(ro); Iterator* iter = NewIterator(ro);
iter->SeekForPrev("c2"); iter->SeekForPrev("c2");
ASSERT_TRUE(!iter->Valid()); ASSERT_TRUE(!iter->Valid());
ASSERT_OK(iter->status());
delete iter; delete iter;
} }
} }
@ -2151,19 +2155,19 @@ TEST_P(DBIteratorTest, ReadAhead) {
std::string value(1024, 'a'); std::string value(1024, 'a');
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
Put(Key(i), value); ASSERT_OK(Put(Key(i), value));
} }
ASSERT_OK(Flush()); ASSERT_OK(Flush());
MoveFilesToLevel(2); MoveFilesToLevel(2);
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
Put(Key(i), value); ASSERT_OK(Put(Key(i), value));
} }
ASSERT_OK(Flush()); ASSERT_OK(Flush());
MoveFilesToLevel(1); MoveFilesToLevel(1);
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
Put(Key(i), value); ASSERT_OK(Put(Key(i), value));
} }
ASSERT_OK(Flush()); ASSERT_OK(Flush());
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
@ -2270,6 +2274,7 @@ TEST_P(DBIteratorTest, Refresh) {
ASSERT_OK(Put("x", "y")); ASSERT_OK(Put("x", "y"));
std::unique_ptr<Iterator> iter(NewIterator(ReadOptions())); std::unique_ptr<Iterator> iter(NewIterator(ReadOptions()));
ASSERT_OK(iter->status());
iter->Seek(Slice("a")); iter->Seek(Slice("a"));
ASSERT_TRUE(iter->Valid()); ASSERT_TRUE(iter->Valid());
ASSERT_EQ(iter->key().compare(Slice("x")), 0); ASSERT_EQ(iter->key().compare(Slice("x")), 0);
@ -2284,7 +2289,8 @@ TEST_P(DBIteratorTest, Refresh) {
iter->Next(); iter->Next();
ASSERT_FALSE(iter->Valid()); ASSERT_FALSE(iter->Valid());
iter->Refresh(); ASSERT_OK(iter->status());
ASSERT_OK(iter->Refresh());
iter->Seek(Slice("a")); iter->Seek(Slice("a"));
ASSERT_TRUE(iter->Valid()); ASSERT_TRUE(iter->Valid());
@ -2295,7 +2301,7 @@ TEST_P(DBIteratorTest, Refresh) {
iter->Next(); iter->Next();
ASSERT_FALSE(iter->Valid()); ASSERT_FALSE(iter->Valid());
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("m", "n")); ASSERT_OK(Put("m", "n"));
@ -2308,7 +2314,8 @@ TEST_P(DBIteratorTest, Refresh) {
iter->Next(); iter->Next();
ASSERT_FALSE(iter->Valid()); ASSERT_FALSE(iter->Valid());
iter->Refresh(); ASSERT_OK(iter->status());
ASSERT_OK(iter->Refresh());
iter->Seek(Slice("a")); iter->Seek(Slice("a"));
ASSERT_TRUE(iter->Valid()); ASSERT_TRUE(iter->Valid());
@ -2331,6 +2338,7 @@ TEST_P(DBIteratorTest, RefreshWithSnapshot) {
ReadOptions options; ReadOptions options;
options.snapshot = snapshot; options.snapshot = snapshot;
Iterator* iter = NewIterator(options); Iterator* iter = NewIterator(options);
ASSERT_OK(iter->status());
iter->Seek(Slice("a")); iter->Seek(Slice("a"));
ASSERT_TRUE(iter->Valid()); ASSERT_TRUE(iter->Valid());
@ -2346,8 +2354,8 @@ TEST_P(DBIteratorTest, RefreshWithSnapshot) {
iter->Next(); iter->Next();
ASSERT_FALSE(iter->Valid()); ASSERT_FALSE(iter->Valid());
Status s; ASSERT_OK(iter->status());
s = iter->Refresh(); Status s = iter->Refresh();
ASSERT_TRUE(s.IsNotSupported()); ASSERT_TRUE(s.IsNotSupported());
db_->ReleaseSnapshot(snapshot); db_->ReleaseSnapshot(snapshot);
delete iter; delete iter;
@ -2405,14 +2413,14 @@ TEST_P(DBIteratorTest, UpperBoundWithChangeDirection) {
TEST_P(DBIteratorTest, TableFilter) { TEST_P(DBIteratorTest, TableFilter) {
ASSERT_OK(Put("a", "1")); ASSERT_OK(Put("a", "1"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("b", "2")); ASSERT_OK(Put("b", "2"));
ASSERT_OK(Put("c", "3")); ASSERT_OK(Put("c", "3"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
ASSERT_OK(Put("d", "4")); ASSERT_OK(Put("d", "4"));
ASSERT_OK(Put("e", "5")); ASSERT_OK(Put("e", "5"));
ASSERT_OK(Put("f", "6")); ASSERT_OK(Put("f", "6"));
dbfull()->Flush(FlushOptions()); EXPECT_OK(dbfull()->Flush(FlushOptions()));
// Ensure the table_filter callback is called once for each table. // Ensure the table_filter callback is called once for each table.
{ {
@ -2597,13 +2605,13 @@ TEST_P(DBIteratorTest, SeekAfterHittingManyInternalKeys) {
ReadOptions ropts; ReadOptions ropts;
ropts.max_skippable_internal_keys = 2; ropts.max_skippable_internal_keys = 2;
Put("1", "val_1"); ASSERT_OK(Put("1", "val_1"));
// Add more tombstones than max_skippable_internal_keys so that Next() fails. // Add more tombstones than max_skippable_internal_keys so that Next() fails.
Delete("2"); ASSERT_OK(Delete("2"));
Delete("3"); ASSERT_OK(Delete("3"));
Delete("4"); ASSERT_OK(Delete("4"));
Delete("5"); ASSERT_OK(Delete("5"));
Put("6", "val_6"); ASSERT_OK(Put("6", "val_6"));
std::unique_ptr<Iterator> iter(NewIterator(ropts)); std::unique_ptr<Iterator> iter(NewIterator(ropts));
iter->SeekToFirst(); iter->SeekToFirst();
@ -2645,9 +2653,9 @@ TEST_P(DBIteratorTest, NonBlockingIterationBugRepro) {
DestroyAndReopen(options); DestroyAndReopen(options);
// Two records in sst file, each in its own block. // Two records in sst file, each in its own block.
Put("b", ""); ASSERT_OK(Put("b", ""));
Put("d", ""); ASSERT_OK(Put("d", ""));
Flush(); ASSERT_OK(Flush());
// Create a nonblocking iterator before writing to memtable. // Create a nonblocking iterator before writing to memtable.
ReadOptions ropt; ReadOptions ropt;
@ -2657,7 +2665,7 @@ TEST_P(DBIteratorTest, NonBlockingIterationBugRepro) {
// Overwrite a key in memtable many times to hit // Overwrite a key in memtable many times to hit
// max_sequential_skip_in_iterations (which is 8 by default). // max_sequential_skip_in_iterations (which is 8 by default).
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
Put("c", ""); ASSERT_OK(Put("c", ""));
} }
// Load the second block in sst file into the block cache. // Load the second block in sst file into the block cache.
@ -2674,9 +2682,9 @@ TEST_P(DBIteratorTest, NonBlockingIterationBugRepro) {
} }
TEST_P(DBIteratorTest, SeekBackwardAfterOutOfUpperBound) { TEST_P(DBIteratorTest, SeekBackwardAfterOutOfUpperBound) {
Put("a", ""); ASSERT_OK(Put("a", ""));
Put("b", ""); ASSERT_OK(Put("b", ""));
Flush(); ASSERT_OK(Flush());
ReadOptions ropt; ReadOptions ropt;
Slice ub = "b"; Slice ub = "b";

@ -129,7 +129,6 @@ class TestPrefixExtractor : public SliceTransform {
TEST_F(DBMemTableTest, DuplicateSeq) { TEST_F(DBMemTableTest, DuplicateSeq) {
SequenceNumber seq = 123; SequenceNumber seq = 123;
std::string value; std::string value;
Status s;
MergeContext merge_context; MergeContext merge_context;
Options options; Options options;
InternalKeyComparator ikey_cmp(options.comparator); InternalKeyComparator ikey_cmp(options.comparator);
@ -162,7 +161,7 @@ TEST_F(DBMemTableTest, DuplicateSeq) {
if (!insert_dup) { if (!insert_dup) {
seq++; seq++;
} }
s = mem->Add(seq, kTypeValue, "foo", "value" + ToString(seq)); Status s = mem->Add(seq, kTypeValue, "foo", "value" + ToString(seq));
if (insert_dup) { if (insert_dup) {
ASSERT_TRUE(s.IsTryAgain()); ASSERT_TRUE(s.IsTryAgain());
} else { } else {
@ -200,7 +199,6 @@ TEST_F(DBMemTableTest, DuplicateSeq) {
TEST_F(DBMemTableTest, ConcurrentMergeWrite) { TEST_F(DBMemTableTest, ConcurrentMergeWrite) {
int num_ops = 1000; int num_ops = 1000;
std::string value; std::string value;
Status s;
MergeContext merge_context; MergeContext merge_context;
Options options; Options options;
// A merge operator that is not sensitive to concurrent writes since in this // A merge operator that is not sensitive to concurrent writes since in this
@ -252,6 +250,7 @@ TEST_F(DBMemTableTest, ConcurrentMergeWrite) {
LookupKey lkey("key", kMaxSequenceNumber); LookupKey lkey("key", kMaxSequenceNumber);
bool res = mem->Get(lkey, &value, /*timestamp=*/nullptr, &status, bool res = mem->Get(lkey, &value, /*timestamp=*/nullptr, &status,
&merge_context, &max_covering_tombstone_seq, roptions); &merge_context, &max_covering_tombstone_seq, roptions);
ASSERT_OK(status);
ASSERT_TRUE(res); ASSERT_TRUE(res);
uint64_t ivalue = DecodeFixed64(Slice(value).data()); uint64_t ivalue = DecodeFixed64(Slice(value).data());
uint64_t sum = 0; uint64_t sum = 0;

@ -59,29 +59,29 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
merge_operands_info.expected_max_number_of_operands = num_records; merge_operands_info.expected_max_number_of_operands = num_records;
// k0 value in memtable // k0 value in memtable
Put("k0", "PutARock"); ASSERT_OK(Put("k0", "PutARock"));
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k0", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k0", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "PutARock"); ASSERT_EQ(values[0], "PutARock");
// k0.1 value in SST // k0.1 value in SST
Put("k0.1", "RockInSST"); ASSERT_OK(Put("k0.1", "RockInSST"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k0.1", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k0.1", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "RockInSST"); ASSERT_EQ(values[0], "RockInSST");
// All k1 values are in memtable. // All k1 values are in memtable.
ASSERT_OK(Merge("k1", "a")); ASSERT_OK(Merge("k1", "a"));
Put("k1", "x"); ASSERT_OK(Put("k1", "x"));
ASSERT_OK(Merge("k1", "b")); ASSERT_OK(Merge("k1", "b"));
ASSERT_OK(Merge("k1", "c")); ASSERT_OK(Merge("k1", "c"));
ASSERT_OK(Merge("k1", "d")); ASSERT_OK(Merge("k1", "d"));
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k1", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k1", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "x"); ASSERT_EQ(values[0], "x");
ASSERT_EQ(values[1], "b"); ASSERT_EQ(values[1], "b");
ASSERT_EQ(values[2], "c"); ASSERT_EQ(values[2], "c");
@ -98,13 +98,13 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
// All k1.1 values are in memtable. // All k1.1 values are in memtable.
ASSERT_OK(Merge("k1.1", "r")); ASSERT_OK(Merge("k1.1", "r"));
Delete("k1.1"); ASSERT_OK(Delete("k1.1"));
ASSERT_OK(Merge("k1.1", "c")); ASSERT_OK(Merge("k1.1", "c"));
ASSERT_OK(Merge("k1.1", "k")); ASSERT_OK(Merge("k1.1", "k"));
ASSERT_OK(Merge("k1.1", "s")); ASSERT_OK(Merge("k1.1", "s"));
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k1.1", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k1.1", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "c"); ASSERT_EQ(values[0], "c");
ASSERT_EQ(values[1], "k"); ASSERT_EQ(values[1], "k");
ASSERT_EQ(values[2], "s"); ASSERT_EQ(values[2], "s");
@ -115,9 +115,9 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
ASSERT_OK(Merge("k2", "e")); ASSERT_OK(Merge("k2", "e"));
ASSERT_OK(Merge("k2", "r")); ASSERT_OK(Merge("k2", "r"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k2", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k2", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "q"); ASSERT_EQ(values[0], "q");
ASSERT_EQ(values[1], "w"); ASSERT_EQ(values[1], "w");
ASSERT_EQ(values[2], "e"); ASSERT_EQ(values[2], "e");
@ -125,30 +125,30 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
// All k2.1 values are flushed to L0 into a single file. // All k2.1 values are flushed to L0 into a single file.
ASSERT_OK(Merge("k2.1", "m")); ASSERT_OK(Merge("k2.1", "m"));
Put("k2.1", "l"); ASSERT_OK(Put("k2.1", "l"));
ASSERT_OK(Merge("k2.1", "n")); ASSERT_OK(Merge("k2.1", "n"));
ASSERT_OK(Merge("k2.1", "o")); ASSERT_OK(Merge("k2.1", "o"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k2.1", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k2.1", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "l,n,o"); ASSERT_EQ(values[0], "l,n,o");
// All k2.2 values are flushed to L0 into a single file. // All k2.2 values are flushed to L0 into a single file.
ASSERT_OK(Merge("k2.2", "g")); ASSERT_OK(Merge("k2.2", "g"));
Delete("k2.2"); ASSERT_OK(Delete("k2.2"));
ASSERT_OK(Merge("k2.2", "o")); ASSERT_OK(Merge("k2.2", "o"));
ASSERT_OK(Merge("k2.2", "t")); ASSERT_OK(Merge("k2.2", "t"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k2.2", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k2.2", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "o,t"); ASSERT_EQ(values[0], "o,t");
// Do some compaction that will make the following tests more predictable // Do some compaction that will make the following tests more predictable
// Slice start("PutARock"); // Slice start("PutARock");
// Slice end("t"); // Slice end("t");
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
// All k3 values are flushed and are in different files. // All k3 values are flushed and are in different files.
ASSERT_OK(Merge("k3", "ab")); ASSERT_OK(Merge("k3", "ab"));
@ -158,9 +158,9 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
ASSERT_OK(Merge("k3", "cd")); ASSERT_OK(Merge("k3", "cd"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
ASSERT_OK(Merge("k3", "de")); ASSERT_OK(Merge("k3", "de"));
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k3", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k3", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "ab"); ASSERT_EQ(values[0], "ab");
ASSERT_EQ(values[1], "bc"); ASSERT_EQ(values[1], "bc");
ASSERT_EQ(values[2], "cd"); ASSERT_EQ(values[2], "cd");
@ -169,14 +169,14 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
// All k3.1 values are flushed and are in different files. // All k3.1 values are flushed and are in different files.
ASSERT_OK(Merge("k3.1", "ab")); ASSERT_OK(Merge("k3.1", "ab"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
Put("k3.1", "bc"); ASSERT_OK(Put("k3.1", "bc"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
ASSERT_OK(Merge("k3.1", "cd")); ASSERT_OK(Merge("k3.1", "cd"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
ASSERT_OK(Merge("k3.1", "de")); ASSERT_OK(Merge("k3.1", "de"));
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k3.1", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k3.1", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "bc"); ASSERT_EQ(values[0], "bc");
ASSERT_EQ(values[1], "cd"); ASSERT_EQ(values[1], "cd");
ASSERT_EQ(values[2], "de"); ASSERT_EQ(values[2], "de");
@ -184,14 +184,14 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
// All k3.2 values are flushed and are in different files. // All k3.2 values are flushed and are in different files.
ASSERT_OK(Merge("k3.2", "ab")); ASSERT_OK(Merge("k3.2", "ab"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
Delete("k3.2"); ASSERT_OK(Delete("k3.2"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
ASSERT_OK(Merge("k3.2", "cd")); ASSERT_OK(Merge("k3.2", "cd"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
ASSERT_OK(Merge("k3.2", "de")); ASSERT_OK(Merge("k3.2", "de"));
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k3.2", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k3.2", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "cd"); ASSERT_EQ(values[0], "cd");
ASSERT_EQ(values[1], "de"); ASSERT_EQ(values[1], "de");
@ -206,9 +206,9 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
ASSERT_OK(Flush()); ASSERT_OK(Flush());
MoveFilesToLevel(1); MoveFilesToLevel(1);
ASSERT_OK(Merge("k4", "ed")); ASSERT_OK(Merge("k4", "ed"));
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k4", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k4", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "ba"); ASSERT_EQ(values[0], "ba");
ASSERT_EQ(values[1], "cb"); ASSERT_EQ(values[1], "cb");
ASSERT_EQ(values[2], "dc"); ASSERT_EQ(values[2], "dc");
@ -219,14 +219,14 @@ TEST_F(DBMergeOperandTest, GetMergeOperandsBasic) {
ASSERT_OK(Merge("k5", "am")); ASSERT_OK(Merge("k5", "am"));
ASSERT_OK(Merge("k5", "i")); ASSERT_OK(Merge("k5", "i"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
Put("k5", "remember"); ASSERT_OK(Put("k5", "remember"));
ASSERT_OK(Merge("k5", "i")); ASSERT_OK(Merge("k5", "i"));
ASSERT_OK(Merge("k5", "am")); ASSERT_OK(Merge("k5", "am"));
ASSERT_OK(Merge("k5", "rocks")); ASSERT_OK(Merge("k5", "rocks"));
dbfull()->TEST_SwitchMemtable(); ASSERT_OK(dbfull()->TEST_SwitchMemtable());
db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(), "k5", ASSERT_OK(db_->GetMergeOperands(ReadOptions(), db_->DefaultColumnFamily(),
values.data(), &merge_operands_info, "k5", values.data(), &merge_operands_info,
&number_of_operands); &number_of_operands));
ASSERT_EQ(values[0], "remember"); ASSERT_EQ(values[0], "remember");
ASSERT_EQ(values[1], "i"); ASSERT_EQ(values[1], "i");
ASSERT_EQ(values[2], "am"); ASSERT_EQ(values[2], "am");

@ -94,7 +94,7 @@ TEST_F(DBMergeOperatorTest, LimitMergeOperands) {
ASSERT_OK(Merge("k1", "c")); ASSERT_OK(Merge("k1", "c"));
ASSERT_OK(Merge("k1", "d")); ASSERT_OK(Merge("k1", "d"));
std::string value; std::string value;
ASSERT_TRUE(db_->Get(ReadOptions(), "k1", &value).ok()); ASSERT_OK(db_->Get(ReadOptions(), "k1", &value));
// Make sure that only the latest two merge operands are used. If this was // Make sure that only the latest two merge operands are used. If this was
// not the case the value would be "a,b,c,d". // not the case the value would be "a,b,c,d".
ASSERT_EQ(value, "c,d"); ASSERT_EQ(value, "c,d");
@ -105,7 +105,7 @@ TEST_F(DBMergeOperatorTest, LimitMergeOperands) {
ASSERT_OK(Merge("k2", "c")); ASSERT_OK(Merge("k2", "c"));
ASSERT_OK(Merge("k2", "d")); ASSERT_OK(Merge("k2", "d"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
ASSERT_TRUE(db_->Get(ReadOptions(), "k2", &value).ok()); ASSERT_OK(db_->Get(ReadOptions(), "k2", &value));
ASSERT_EQ(value, "c,d"); ASSERT_EQ(value, "c,d");
// All K3 values are flushed and are in different files. // All K3 values are flushed and are in different files.
@ -116,7 +116,7 @@ TEST_F(DBMergeOperatorTest, LimitMergeOperands) {
ASSERT_OK(Merge("k3", "cd")); ASSERT_OK(Merge("k3", "cd"));
ASSERT_OK(Flush()); ASSERT_OK(Flush());
ASSERT_OK(Merge("k3", "de")); ASSERT_OK(Merge("k3", "de"));
ASSERT_TRUE(db_->Get(ReadOptions(), "k3", &value).ok()); ASSERT_OK(db_->Get(ReadOptions(), "k3", &value));
ASSERT_EQ(value, "cd,de"); ASSERT_EQ(value, "cd,de");
// All K4 values are in different levels // All K4 values are in different levels
@ -130,7 +130,7 @@ TEST_F(DBMergeOperatorTest, LimitMergeOperands) {
ASSERT_OK(Flush()); ASSERT_OK(Flush());
MoveFilesToLevel(1); MoveFilesToLevel(1);
ASSERT_OK(Merge("k4", "de")); ASSERT_OK(Merge("k4", "de"));
ASSERT_TRUE(db_->Get(ReadOptions(), "k4", &value).ok()); ASSERT_OK(db_->Get(ReadOptions(), "k4", &value));
ASSERT_EQ(value, "cd,de"); ASSERT_EQ(value, "cd,de");
} }
@ -344,8 +344,9 @@ TEST_P(MergeOperatorPinningTest, EvictCacheBeforeMerge) {
// Code executed before merge operation // Code executed before merge operation
merge_hook->before_merge_ = [&]() { merge_hook->before_merge_ = [&]() {
// Evict all tables from cache before every merge operation // Evict all tables from cache before every merge operation
auto* table_cache = dbfull()->TEST_table_cache();
for (uint64_t num : file_numbers) { for (uint64_t num : file_numbers) {
TableCache::Evict(dbfull()->TEST_table_cache(), num); TableCache::Evict(table_cache, num);
} }
// Decrease cache capacity to force all unrefed blocks to be evicted // Decrease cache capacity to force all unrefed blocks to be evicted
if (bbto.block_cache) { if (bbto.block_cache) {
@ -366,7 +367,7 @@ TEST_P(MergeOperatorPinningTest, EvictCacheBeforeMerge) {
VerifyDBFromMap(true_data, &total_reads); VerifyDBFromMap(true_data, &total_reads);
ASSERT_EQ(merge_cnt, total_reads); ASSERT_EQ(merge_cnt, total_reads);
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
VerifyDBFromMap(true_data, &total_reads); VerifyDBFromMap(true_data, &total_reads);
} }
@ -385,7 +386,7 @@ TEST_P(MergeOperatorPinningTest, TailingIterator) {
std::function<void()> writer_func = [&]() { std::function<void()> writer_func = [&]() {
int k = 0; int k = 0;
for (int i = 0; i < kNumWrites; i++) { for (int i = 0; i < kNumWrites; i++) {
db_->Merge(WriteOptions(), Key(k), Key(k)); ASSERT_OK(db_->Merge(WriteOptions(), Key(k), Key(k)));
if (i && i % kNumOperands == 0) { if (i && i % kNumOperands == 0) {
k++; k++;
@ -403,7 +404,7 @@ TEST_P(MergeOperatorPinningTest, TailingIterator) {
ReadOptions ro; ReadOptions ro;
ro.tailing = true; ro.tailing = true;
Iterator* iter = db_->NewIterator(ro); Iterator* iter = db_->NewIterator(ro);
ASSERT_OK(iter->status());
iter->SeekToFirst(); iter->SeekToFirst();
for (int i = 0; i < (kNumWrites / kNumOperands); i++) { for (int i = 0; i < (kNumWrites / kNumOperands); i++) {
while (!iter->Valid()) { while (!iter->Valid()) {
@ -416,6 +417,7 @@ TEST_P(MergeOperatorPinningTest, TailingIterator) {
iter->Next(); iter->Next();
} }
ASSERT_OK(iter->status());
delete iter; delete iter;
}; };
@ -449,12 +451,13 @@ TEST_F(DBMergeOperatorTest, TailingIteratorMemtableUnrefedBySomeoneElse) {
// ForwardIterator to not pin it in some circumstances. This test // ForwardIterator to not pin it in some circumstances. This test
// reproduces it. // reproduces it.
db_->Merge(WriteOptions(), "key", "sst"); ASSERT_OK(db_->Merge(WriteOptions(), "key", "sst"));
db_->Flush(FlushOptions()); // Switch to SuperVersion A ASSERT_OK(db_->Flush(FlushOptions())); // Switch to SuperVersion A
db_->Merge(WriteOptions(), "key", "memtable"); ASSERT_OK(db_->Merge(WriteOptions(), "key", "memtable"));
// Pin SuperVersion A // Pin SuperVersion A
std::unique_ptr<Iterator> someone_else(db_->NewIterator(ReadOptions())); std::unique_ptr<Iterator> someone_else(db_->NewIterator(ReadOptions()));
ASSERT_OK(someone_else->status());
bool pushed_first_operand = false; bool pushed_first_operand = false;
bool stepped_to_next_operand = false; bool stepped_to_next_operand = false;
@ -462,7 +465,7 @@ TEST_F(DBMergeOperatorTest, TailingIteratorMemtableUnrefedBySomeoneElse) {
"DBIter::MergeValuesNewToOld:PushedFirstOperand", [&](void*) { "DBIter::MergeValuesNewToOld:PushedFirstOperand", [&](void*) {
EXPECT_FALSE(pushed_first_operand); EXPECT_FALSE(pushed_first_operand);
pushed_first_operand = true; pushed_first_operand = true;
db_->Flush(FlushOptions()); // Switch to SuperVersion B EXPECT_OK(db_->Flush(FlushOptions())); // Switch to SuperVersion B
}); });
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack( ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"DBIter::MergeValuesNewToOld:SteppedToNextOperand", [&](void*) { "DBIter::MergeValuesNewToOld:SteppedToNextOperand", [&](void*) {
@ -477,7 +480,7 @@ TEST_F(DBMergeOperatorTest, TailingIteratorMemtableUnrefedBySomeoneElse) {
std::unique_ptr<Iterator> iter(db_->NewIterator(ro)); std::unique_ptr<Iterator> iter(db_->NewIterator(ro));
iter->Seek("key"); iter->Seek("key");
ASSERT_TRUE(iter->status().ok()); ASSERT_OK(iter->status());
ASSERT_TRUE(iter->Valid()); ASSERT_TRUE(iter->Valid());
EXPECT_EQ(std::string("sst,memtable"), iter->value().ToString()); EXPECT_EQ(std::string("sst,memtable"), iter->value().ToString());
EXPECT_TRUE(pushed_first_operand); EXPECT_TRUE(pushed_first_operand);

@ -200,28 +200,28 @@ bool DBTestBase::ChangeCompactOptions() {
Destroy(last_options_); Destroy(last_options_);
auto options = CurrentOptions(); auto options = CurrentOptions();
options.create_if_missing = true; options.create_if_missing = true;
TryReopen(options); Reopen(options);
return true; return true;
} else if (option_config_ == kUniversalCompaction) { } else if (option_config_ == kUniversalCompaction) {
option_config_ = kUniversalCompactionMultiLevel; option_config_ = kUniversalCompactionMultiLevel;
Destroy(last_options_); Destroy(last_options_);
auto options = CurrentOptions(); auto options = CurrentOptions();
options.create_if_missing = true; options.create_if_missing = true;
TryReopen(options); Reopen(options);
return true; return true;
} else if (option_config_ == kUniversalCompactionMultiLevel) { } else if (option_config_ == kUniversalCompactionMultiLevel) {
option_config_ = kLevelSubcompactions; option_config_ = kLevelSubcompactions;
Destroy(last_options_); Destroy(last_options_);
auto options = CurrentOptions(); auto options = CurrentOptions();
assert(options.max_subcompactions > 1); assert(options.max_subcompactions > 1);
TryReopen(options); Reopen(options);
return true; return true;
} else if (option_config_ == kLevelSubcompactions) { } else if (option_config_ == kLevelSubcompactions) {
option_config_ = kUniversalSubcompactions; option_config_ = kUniversalSubcompactions;
Destroy(last_options_); Destroy(last_options_);
auto options = CurrentOptions(); auto options = CurrentOptions();
assert(options.max_subcompactions > 1); assert(options.max_subcompactions > 1);
TryReopen(options); Reopen(options);
return true; return true;
} else { } else {
return false; return false;
@ -680,7 +680,7 @@ void DBTestBase::Close() {
void DBTestBase::DestroyAndReopen(const Options& options) { void DBTestBase::DestroyAndReopen(const Options& options) {
// Destroy using last options // Destroy using last options
Destroy(last_options_); Destroy(last_options_);
ASSERT_OK(TryReopen(options)); Reopen(options);
} }
void DBTestBase::Destroy(const Options& options, bool delete_cf_paths) { void DBTestBase::Destroy(const Options& options, bool delete_cf_paths) {

@ -46,7 +46,13 @@ class ForwardLevelIterator : public InternalIterator {
file_iter_(nullptr), file_iter_(nullptr),
pinned_iters_mgr_(nullptr), pinned_iters_mgr_(nullptr),
prefix_extractor_(prefix_extractor), prefix_extractor_(prefix_extractor),
allow_unprepared_value_(allow_unprepared_value) {} allow_unprepared_value_(allow_unprepared_value) {
/*
NOTE needed for ASSERT_STATUS_CHECKED
in MergeOperatorPinningTest/MergeOperatorPinningTest.TailingIterator
*/
status_.PermitUncheckedError();
}
~ForwardLevelIterator() override { ~ForwardLevelIterator() override {
// Reset current pointer // Reset current pointer

@ -64,6 +64,7 @@ static std::string PrintContents(WriteBatch* b,
if (iter == nullptr) { if (iter == nullptr) {
continue; continue;
} }
EXPECT_OK(iter->status());
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
ParsedInternalKey ikey; ParsedInternalKey ikey;
ikey.clear(); ikey.clear();
@ -117,6 +118,7 @@ static std::string PrintContents(WriteBatch* b,
state.append("@"); state.append("@");
state.append(NumberToString(ikey.sequence)); state.append(NumberToString(ikey.sequence));
} }
EXPECT_OK(iter->status());
} }
if (s.ok()) { if (s.ok()) {
EXPECT_EQ(b->HasPut(), put_count > 0); EXPECT_EQ(b->HasPut(), put_count > 0);

@ -96,11 +96,11 @@ void TestValueAsSecondaryIndexHelper(std::vector<Entry> entries,
ColumnFamilyHandleImplDummy index(8, BytewiseComparator()); ColumnFamilyHandleImplDummy index(8, BytewiseComparator());
for (auto& e : entries) { for (auto& e : entries) {
if (e.type == kPutRecord) { if (e.type == kPutRecord) {
batch->Put(&data, e.key, e.value); ASSERT_OK(batch->Put(&data, e.key, e.value));
batch->Put(&index, e.value, e.key); ASSERT_OK(batch->Put(&index, e.value, e.key));
} else if (e.type == kMergeRecord) { } else if (e.type == kMergeRecord) {
batch->Merge(&data, e.key, e.value); ASSERT_OK(batch->Merge(&data, e.key, e.value));
batch->Put(&index, e.value, e.key); ASSERT_OK(batch->Put(&index, e.value, e.key));
} else { } else {
assert(e.type == kDeleteRecord); assert(e.type == kDeleteRecord);
std::unique_ptr<WBWIIterator> iter(batch->NewIterator(&data)); std::unique_ptr<WBWIIterator> iter(batch->NewIterator(&data));
@ -109,8 +109,8 @@ void TestValueAsSecondaryIndexHelper(std::vector<Entry> entries,
auto write_entry = iter->Entry(); auto write_entry = iter->Entry();
ASSERT_EQ(e.key, write_entry.key.ToString()); ASSERT_EQ(e.key, write_entry.key.ToString());
ASSERT_EQ(e.value, write_entry.value.ToString()); ASSERT_EQ(e.value, write_entry.value.ToString());
batch->Delete(&data, e.key); ASSERT_OK(batch->Delete(&data, e.key));
batch->Put(&index, e.value, ""); ASSERT_OK(batch->Put(&index, e.value, ""));
} }
} }
@ -243,7 +243,7 @@ void TestValueAsSecondaryIndexHelper(std::vector<Entry> entries,
// Verify WriteBatch can be iterated // Verify WriteBatch can be iterated
TestHandler handler; TestHandler handler;
batch->GetWriteBatch()->Iterate(&handler); ASSERT_OK(batch->GetWriteBatch()->Iterate(&handler));
// Verify data column family // Verify data column family
{ {
@ -315,18 +315,18 @@ TEST_F(WriteBatchWithIndexTest, TestComparatorForCF) {
ColumnFamilyHandleImplDummy cf2(88, BytewiseComparator()); ColumnFamilyHandleImplDummy cf2(88, BytewiseComparator());
WriteBatchWithIndex batch(BytewiseComparator(), 20); WriteBatchWithIndex batch(BytewiseComparator(), 20);
batch.Put(&cf1, "ddd", ""); ASSERT_OK(batch.Put(&cf1, "ddd", ""));
batch.Put(&cf2, "aaa", ""); ASSERT_OK(batch.Put(&cf2, "aaa", ""));
batch.Put(&cf2, "eee", ""); ASSERT_OK(batch.Put(&cf2, "eee", ""));
batch.Put(&cf1, "ccc", ""); ASSERT_OK(batch.Put(&cf1, "ccc", ""));
batch.Put(&reverse_cf, "a11", ""); ASSERT_OK(batch.Put(&reverse_cf, "a11", ""));
batch.Put(&cf1, "bbb", ""); ASSERT_OK(batch.Put(&cf1, "bbb", ""));
Slice key_slices[] = {"a", "3", "3"}; Slice key_slices[] = {"a", "3", "3"};
Slice value_slice = ""; Slice value_slice = "";
batch.Put(&reverse_cf, SliceParts(key_slices, 3), ASSERT_OK(batch.Put(&reverse_cf, SliceParts(key_slices, 3),
SliceParts(&value_slice, 1)); SliceParts(&value_slice, 1)));
batch.Put(&reverse_cf, "a22", ""); ASSERT_OK(batch.Put(&reverse_cf, "a22", ""));
{ {
std::unique_ptr<WBWIIterator> iter(batch.NewIterator(&cf1)); std::unique_ptr<WBWIIterator> iter(batch.NewIterator(&cf1));
@ -402,20 +402,20 @@ TEST_F(WriteBatchWithIndexTest, TestOverwriteKey) {
ColumnFamilyHandleImplDummy cf2(88, BytewiseComparator()); ColumnFamilyHandleImplDummy cf2(88, BytewiseComparator());
WriteBatchWithIndex batch(BytewiseComparator(), 20, true); WriteBatchWithIndex batch(BytewiseComparator(), 20, true);
batch.Put(&cf1, "ddd", ""); ASSERT_OK(batch.Put(&cf1, "ddd", ""));
batch.Merge(&cf1, "ddd", ""); ASSERT_OK(batch.Merge(&cf1, "ddd", ""));
batch.Delete(&cf1, "ddd"); ASSERT_OK(batch.Delete(&cf1, "ddd"));
batch.Put(&cf2, "aaa", ""); ASSERT_OK(batch.Put(&cf2, "aaa", ""));
batch.Delete(&cf2, "aaa"); ASSERT_OK(batch.Delete(&cf2, "aaa"));
batch.Put(&cf2, "aaa", "aaa"); ASSERT_OK(batch.Put(&cf2, "aaa", "aaa"));
batch.Put(&cf2, "eee", "eee"); ASSERT_OK(batch.Put(&cf2, "eee", "eee"));
batch.Put(&cf1, "ccc", ""); ASSERT_OK(batch.Put(&cf1, "ccc", ""));
batch.Put(&reverse_cf, "a11", ""); ASSERT_OK(batch.Put(&reverse_cf, "a11", ""));
batch.Delete(&cf1, "ccc"); ASSERT_OK(batch.Delete(&cf1, "ccc"));
batch.Put(&reverse_cf, "a33", "a33"); ASSERT_OK(batch.Put(&reverse_cf, "a33", "a33"));
batch.Put(&reverse_cf, "a11", "a11"); ASSERT_OK(batch.Put(&reverse_cf, "a11", "a11"));
Slice slices[] = {"a", "3", "3"}; Slice slices[] = {"a", "3", "3"};
batch.Delete(&reverse_cf, SliceParts(slices, 3)); ASSERT_OK(batch.Delete(&reverse_cf, SliceParts(slices, 3)));
{ {
std::unique_ptr<WBWIIterator> iter(batch.NewIterator(&cf1)); std::unique_ptr<WBWIIterator> iter(batch.NewIterator(&cf1));
@ -570,10 +570,10 @@ TEST_F(WriteBatchWithIndexTest, TestRandomIteraratorWithBase) {
WriteBatchWithIndex batch(BytewiseComparator(), 20, true); WriteBatchWithIndex batch(BytewiseComparator(), 20, true);
if (rand_seed % 2 == 0) { if (rand_seed % 2 == 0) {
batch.Put(&cf2, "zoo", "bar"); ASSERT_OK(batch.Put(&cf2, "zoo", "bar"));
} }
if (rand_seed % 4 == 1) { if (rand_seed % 4 == 1) {
batch.Put(&cf3, "zoo", "bar"); ASSERT_OK(batch.Put(&cf3, "zoo", "bar"));
} }
KVMap map; KVMap map;
@ -589,24 +589,24 @@ TEST_F(WriteBatchWithIndexTest, TestRandomIteraratorWithBase) {
break; break;
case 1: case 1:
// only delta has it // only delta has it
batch.Put(&cf1, key, value); ASSERT_OK(batch.Put(&cf1, key, value));
map[key] = value; map[key] = value;
merged_map[key] = value; merged_map[key] = value;
break; break;
case 2: case 2:
// both has it. Delta should win // both has it. Delta should win
batch.Put(&cf1, key, value); ASSERT_OK(batch.Put(&cf1, key, value));
map[key] = "wrong_value"; map[key] = "wrong_value";
merged_map[key] = value; merged_map[key] = value;
break; break;
case 3: case 3:
// both has it. Delta is delete // both has it. Delta is delete
batch.Delete(&cf1, key); ASSERT_OK(batch.Delete(&cf1, key));
map[key] = "wrong_value"; map[key] = "wrong_value";
break; break;
case 4: case 4:
// only delta has it. Delta is delete // only delta has it. Delta is delete
batch.Delete(&cf1, key); ASSERT_OK(batch.Delete(&cf1, key));
map[key] = "wrong_value"; map[key] = "wrong_value";
break; break;
default: default:
@ -675,6 +675,8 @@ TEST_F(WriteBatchWithIndexTest, TestRandomIteraratorWithBase) {
AssertItersEqual(iter.get(), result_iter.get()); AssertItersEqual(iter.get(), result_iter.get());
is_valid = iter->Valid(); is_valid = iter->Valid();
} }
ASSERT_OK(iter->status());
} }
} }
@ -722,8 +724,8 @@ TEST_F(WriteBatchWithIndexTest, TestIteraratorWithBase) {
} }
// Test the case that there is one element in the write batch // Test the case that there is one element in the write batch
batch.Put(&cf2, "zoo", "bar"); ASSERT_OK(batch.Put(&cf2, "zoo", "bar"));
batch.Put(&cf1, "a", "aa"); ASSERT_OK(batch.Put(&cf1, "a", "aa"));
{ {
KVMap empty_map; KVMap empty_map;
std::unique_ptr<Iterator> iter( std::unique_ptr<Iterator> iter(
@ -736,10 +738,10 @@ TEST_F(WriteBatchWithIndexTest, TestIteraratorWithBase) {
ASSERT_TRUE(!iter->Valid()); ASSERT_TRUE(!iter->Valid());
} }
batch.Delete(&cf1, "b"); ASSERT_OK(batch.Delete(&cf1, "b"));
batch.Put(&cf1, "c", "cc"); ASSERT_OK(batch.Put(&cf1, "c", "cc"));
batch.Put(&cf1, "d", "dd"); ASSERT_OK(batch.Put(&cf1, "d", "dd"));
batch.Delete(&cf1, "e"); ASSERT_OK(batch.Delete(&cf1, "e"));
{ {
KVMap map; KVMap map;
@ -847,8 +849,8 @@ TEST_F(WriteBatchWithIndexTest, TestIteraratorWithBaseReverseCmp) {
WriteBatchWithIndex batch(BytewiseComparator(), 20, true); WriteBatchWithIndex batch(BytewiseComparator(), 20, true);
// Test the case that there is one element in the write batch // Test the case that there is one element in the write batch
batch.Put(&cf2, "zoo", "bar"); ASSERT_OK(batch.Put(&cf2, "zoo", "bar"));
batch.Put(&cf1, "a", "aa"); ASSERT_OK(batch.Put(&cf1, "a", "aa"));
{ {
KVMap empty_map; KVMap empty_map;
std::unique_ptr<Iterator> iter( std::unique_ptr<Iterator> iter(
@ -861,7 +863,7 @@ TEST_F(WriteBatchWithIndexTest, TestIteraratorWithBaseReverseCmp) {
ASSERT_TRUE(!iter->Valid()); ASSERT_TRUE(!iter->Valid());
} }
batch.Put(&cf1, "c", "cc"); ASSERT_OK(batch.Put(&cf1, "c", "cc"));
{ {
KVMap map; KVMap map;
std::unique_ptr<Iterator> iter( std::unique_ptr<Iterator> iter(
@ -894,7 +896,7 @@ TEST_F(WriteBatchWithIndexTest, TestIteraratorWithBaseReverseCmp) {
} }
// default column family // default column family
batch.Put("a", "b"); ASSERT_OK(batch.Put("a", "b"));
{ {
KVMap map; KVMap map;
map["b"] = ""; map["b"] = "";
@ -936,14 +938,14 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatch) {
s = batch.GetFromBatch(options, "b", &value); s = batch.GetFromBatch(options, "b", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
batch.Put("a", "a"); ASSERT_OK(batch.Put("a", "a"));
batch.Put("b", "b"); ASSERT_OK(batch.Put("b", "b"));
batch.Put("c", "c"); ASSERT_OK(batch.Put("c", "c"));
batch.Put("a", "z"); ASSERT_OK(batch.Put("a", "z"));
batch.Delete("c"); ASSERT_OK(batch.Delete("c"));
batch.Delete("d"); ASSERT_OK(batch.Delete("d"));
batch.Delete("e"); ASSERT_OK(batch.Delete("e"));
batch.Put("e", "e"); ASSERT_OK(batch.Put("e", "e"));
s = batch.GetFromBatch(options, "b", &value); s = batch.GetFromBatch(options, "b", &value);
ASSERT_OK(s); ASSERT_OK(s);
@ -966,7 +968,7 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatch) {
ASSERT_OK(s); ASSERT_OK(s);
ASSERT_EQ("e", value); ASSERT_EQ("e", value);
batch.Merge("z", "z"); ASSERT_OK(batch.Merge("z", "z"));
s = batch.GetFromBatch(options, "z", &value); s = batch.GetFromBatch(options, "z", &value);
ASSERT_NOK(s); // No merge operator specified. ASSERT_NOK(s); // No merge operator specified.
@ -984,7 +986,7 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchMerge) {
std::string dbname = test::PerThreadDBPath("write_batch_with_index_test"); std::string dbname = test::PerThreadDBPath("write_batch_with_index_test");
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
Status s = DB::Open(options, dbname, &db); Status s = DB::Open(options, dbname, &db);
ASSERT_OK(s); ASSERT_OK(s);
@ -995,18 +997,18 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchMerge) {
s = batch.GetFromBatch(options, "x", &value); s = batch.GetFromBatch(options, "x", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
batch.Put("x", "X"); ASSERT_OK(batch.Put("x", "X"));
std::string expected = "X"; std::string expected = "X";
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
batch.Merge("x", ToString(i)); ASSERT_OK(batch.Merge("x", ToString(i)));
expected = expected + "," + ToString(i); expected = expected + "," + ToString(i);
if (i % 2 == 0) { if (i % 2 == 0) {
batch.Put("y", ToString(i / 2)); ASSERT_OK(batch.Put("y", ToString(i / 2)));
} }
batch.Merge("z", "z"); ASSERT_OK(batch.Merge("z", "z"));
s = batch.GetFromBatch(column_family, options, "x", &value); s = batch.GetFromBatch(column_family, options, "x", &value);
ASSERT_OK(s); ASSERT_OK(s);
@ -1021,7 +1023,7 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchMerge) {
} }
delete db; delete db;
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
} }
TEST_F(WriteBatchWithIndexTest, TestGetFromBatchMerge2) { TEST_F(WriteBatchWithIndexTest, TestGetFromBatchMerge2) {
@ -1032,7 +1034,7 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchMerge2) {
std::string dbname = test::PerThreadDBPath("write_batch_with_index_test"); std::string dbname = test::PerThreadDBPath("write_batch_with_index_test");
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
Status s = DB::Open(options, dbname, &db); Status s = DB::Open(options, dbname, &db);
ASSERT_OK(s); ASSERT_OK(s);
@ -1045,43 +1047,43 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchMerge2) {
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
batch.Put(column_family, "X", "x"); ASSERT_OK(batch.Put(column_family, "X", "x"));
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_OK(s); ASSERT_OK(s);
ASSERT_EQ("x", value); ASSERT_EQ("x", value);
batch.Put(column_family, "X", "x2"); ASSERT_OK(batch.Put(column_family, "X", "x2"));
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_OK(s); ASSERT_OK(s);
ASSERT_EQ("x2", value); ASSERT_EQ("x2", value);
batch.Merge(column_family, "X", "aaa"); ASSERT_OK(batch.Merge(column_family, "X", "aaa"));
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_TRUE(s.IsMergeInProgress()); ASSERT_TRUE(s.IsMergeInProgress());
batch.Merge(column_family, "X", "bbb"); ASSERT_OK(batch.Merge(column_family, "X", "bbb"));
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_TRUE(s.IsMergeInProgress()); ASSERT_TRUE(s.IsMergeInProgress());
batch.Put(column_family, "X", "x3"); ASSERT_OK(batch.Put(column_family, "X", "x3"));
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_OK(s); ASSERT_OK(s);
ASSERT_EQ("x3", value); ASSERT_EQ("x3", value);
batch.Merge(column_family, "X", "ccc"); ASSERT_OK(batch.Merge(column_family, "X", "ccc"));
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_TRUE(s.IsMergeInProgress()); ASSERT_TRUE(s.IsMergeInProgress());
batch.Delete(column_family, "X"); ASSERT_OK(batch.Delete(column_family, "X"));
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
batch.Merge(column_family, "X", "ddd"); ASSERT_OK(batch.Merge(column_family, "X", "ddd"));
s = batch.GetFromBatch(column_family, options, "X", &value); s = batch.GetFromBatch(column_family, options, "X", &value);
ASSERT_TRUE(s.IsMergeInProgress()); ASSERT_TRUE(s.IsMergeInProgress());
delete db; delete db;
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
} }
TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDB) { TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDB) {
@ -1090,7 +1092,7 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDB) {
options.create_if_missing = true; options.create_if_missing = true;
std::string dbname = test::PerThreadDBPath("write_batch_with_index_test"); std::string dbname = test::PerThreadDBPath("write_batch_with_index_test");
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
Status s = DB::Open(options, dbname, &db); Status s = DB::Open(options, dbname, &db);
ASSERT_OK(s); ASSERT_OK(s);
@ -1108,8 +1110,8 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDB) {
s = db->Put(write_options, "c", "c"); s = db->Put(write_options, "c", "c");
ASSERT_OK(s); ASSERT_OK(s);
batch.Put("a", "batch.a"); ASSERT_OK(batch.Put("a", "batch.a"));
batch.Delete("b"); ASSERT_OK(batch.Delete("b"));
s = batch.GetFromBatchAndDB(db, read_options, "a", &value); s = batch.GetFromBatchAndDB(db, read_options, "a", &value);
ASSERT_OK(s); ASSERT_OK(s);
@ -1125,13 +1127,13 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDB) {
s = batch.GetFromBatchAndDB(db, read_options, "x", &value); s = batch.GetFromBatchAndDB(db, read_options, "x", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
db->Delete(write_options, "x"); ASSERT_OK(db->Delete(write_options, "x"));
s = batch.GetFromBatchAndDB(db, read_options, "x", &value); s = batch.GetFromBatchAndDB(db, read_options, "x", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
delete db; delete db;
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
} }
TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge) { TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge) {
@ -1143,9 +1145,9 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge) {
options.merge_operator = MergeOperators::CreateFromStringId("stringappend"); options.merge_operator = MergeOperators::CreateFromStringId("stringappend");
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
Status s = DB::Open(options, dbname, &db); Status s = DB::Open(options, dbname, &db);
assert(s.ok()); ASSERT_OK(s);
WriteBatchWithIndex batch; WriteBatchWithIndex batch;
ReadOptions read_options; ReadOptions read_options;
@ -1167,11 +1169,11 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge) {
s = db->Merge(write_options, "d", "d0"); s = db->Merge(write_options, "d", "d0");
ASSERT_OK(s); ASSERT_OK(s);
batch.Merge("a", "a1"); ASSERT_OK(batch.Merge("a", "a1"));
batch.Merge("a", "a2"); ASSERT_OK(batch.Merge("a", "a2"));
batch.Merge("b", "b2"); ASSERT_OK(batch.Merge("b", "b2"));
batch.Merge("d", "d1"); ASSERT_OK(batch.Merge("d", "d1"));
batch.Merge("e", "e0"); ASSERT_OK(batch.Merge("e", "e0"));
s = batch.GetFromBatchAndDB(db, read_options, "a", &value); s = batch.GetFromBatchAndDB(db, read_options, "a", &value);
ASSERT_OK(s); ASSERT_OK(s);
@ -1214,7 +1216,7 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge) {
ASSERT_OK(s); ASSERT_OK(s);
ASSERT_EQ("a0,a1,a2", value); ASSERT_EQ("a0,a1,a2", value);
batch.Delete("a"); ASSERT_OK(batch.Delete("a"));
s = batch.GetFromBatchAndDB(db, read_options, "a", &value); s = batch.GetFromBatchAndDB(db, read_options, "a", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
@ -1257,7 +1259,7 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge) {
db->ReleaseSnapshot(snapshot); db->ReleaseSnapshot(snapshot);
delete db; delete db;
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
} }
TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge2) { TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge2) {
@ -1269,9 +1271,9 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge2) {
options.merge_operator = MergeOperators::CreateFromStringId("stringappend"); options.merge_operator = MergeOperators::CreateFromStringId("stringappend");
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
Status s = DB::Open(options, dbname, &db); Status s = DB::Open(options, dbname, &db);
assert(s.ok()); ASSERT_OK(s);
// Test batch with overwrite_key=true // Test batch with overwrite_key=true
WriteBatchWithIndex batch(BytewiseComparator(), 0, true); WriteBatchWithIndex batch(BytewiseComparator(), 0, true);
@ -1283,12 +1285,12 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge2) {
s = batch.GetFromBatchAndDB(db, read_options, "A", &value); s = batch.GetFromBatchAndDB(db, read_options, "A", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
batch.Merge("A", "xxx"); ASSERT_OK(batch.Merge("A", "xxx"));
s = batch.GetFromBatchAndDB(db, read_options, "A", &value); s = batch.GetFromBatchAndDB(db, read_options, "A", &value);
ASSERT_TRUE(s.IsMergeInProgress()); ASSERT_TRUE(s.IsMergeInProgress());
batch.Merge("A", "yyy"); ASSERT_OK(batch.Merge("A", "yyy"));
s = batch.GetFromBatchAndDB(db, read_options, "A", &value); s = batch.GetFromBatchAndDB(db, read_options, "A", &value);
ASSERT_TRUE(s.IsMergeInProgress()); ASSERT_TRUE(s.IsMergeInProgress());
@ -1299,13 +1301,13 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge2) {
s = batch.GetFromBatchAndDB(db, read_options, "A", &value); s = batch.GetFromBatchAndDB(db, read_options, "A", &value);
ASSERT_TRUE(s.IsMergeInProgress()); ASSERT_TRUE(s.IsMergeInProgress());
batch.Delete("A"); ASSERT_OK(batch.Delete("A"));
s = batch.GetFromBatchAndDB(db, read_options, "A", &value); s = batch.GetFromBatchAndDB(db, read_options, "A", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
delete db; delete db;
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
} }
TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge3) { TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge3) {
@ -1317,9 +1319,9 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge3) {
options.merge_operator = MergeOperators::CreateFromStringId("stringappend"); options.merge_operator = MergeOperators::CreateFromStringId("stringappend");
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
Status s = DB::Open(options, dbname, &db); Status s = DB::Open(options, dbname, &db);
assert(s.ok()); ASSERT_OK(s);
ReadOptions read_options; ReadOptions read_options;
WriteOptions write_options; WriteOptions write_options;
@ -1336,7 +1338,7 @@ TEST_F(WriteBatchWithIndexTest, TestGetFromBatchAndDBMerge3) {
ASSERT_EQ(value, "1,2"); ASSERT_EQ(value, "1,2");
delete db; delete db;
DestroyDB(dbname, options); EXPECT_OK(DestroyDB(dbname, options));
} }
void AssertKey(std::string key, WBWIIterator* iter) { void AssertKey(std::string key, WBWIIterator* iter) {
@ -1354,7 +1356,7 @@ void AssertValue(std::string value, WBWIIterator* iter) {
TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingCorrectnessTest) { TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingCorrectnessTest) {
WriteBatchWithIndex batch(BytewiseComparator(), 0, true); WriteBatchWithIndex batch(BytewiseComparator(), 0, true);
for (char c = 'a'; c <= 'z'; ++c) { for (char c = 'a'; c <= 'z'; ++c) {
batch.Put(std::string(1, c), std::string(1, c)); ASSERT_OK(batch.Put(std::string(1, c), std::string(1, c)));
} }
std::unique_ptr<WBWIIterator> iter(batch.NewIterator()); std::unique_ptr<WBWIIterator> iter(batch.NewIterator());
@ -1362,14 +1364,14 @@ TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingCorrectnessTest) {
AssertKey("k", iter.get()); AssertKey("k", iter.get());
iter->Next(); iter->Next();
AssertKey("l", iter.get()); AssertKey("l", iter.get());
batch.Put("ab", "cc"); ASSERT_OK(batch.Put("ab", "cc"));
iter->Next(); iter->Next();
AssertKey("m", iter.get()); AssertKey("m", iter.get());
batch.Put("mm", "kk"); ASSERT_OK(batch.Put("mm", "kk"));
iter->Next(); iter->Next();
AssertKey("mm", iter.get()); AssertKey("mm", iter.get());
AssertValue("kk", iter.get()); AssertValue("kk", iter.get());
batch.Delete("mm"); ASSERT_OK(batch.Delete("mm"));
iter->Next(); iter->Next();
AssertKey("n", iter.get()); AssertKey("n", iter.get());
@ -1379,7 +1381,7 @@ TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingCorrectnessTest) {
iter->Seek("ab"); iter->Seek("ab");
AssertKey("ab", iter.get()); AssertKey("ab", iter.get());
batch.Delete("x"); ASSERT_OK(batch.Delete("x"));
iter->Seek("x"); iter->Seek("x");
AssertKey("x", iter.get()); AssertKey("x", iter.get());
ASSERT_EQ(kDeleteRecord, iter->Entry().type); ASSERT_EQ(kDeleteRecord, iter->Entry().type);
@ -1401,7 +1403,7 @@ void AssertIterValue(std::string value, Iterator* iter) {
TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseCorrectnessTest) { TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseCorrectnessTest) {
WriteBatchWithIndex batch(BytewiseComparator(), 0, true); WriteBatchWithIndex batch(BytewiseComparator(), 0, true);
for (char c = 'a'; c <= 'z'; ++c) { for (char c = 'a'; c <= 'z'; ++c) {
batch.Put(std::string(1, c), std::string(1, c)); ASSERT_OK(batch.Put(std::string(1, c), std::string(1, c)));
} }
KVMap map; KVMap map;
@ -1416,14 +1418,14 @@ TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseCorrectnessTest) {
AssertIterKey("k", iter.get()); AssertIterKey("k", iter.get());
iter->Next(); iter->Next();
AssertIterKey("l", iter.get()); AssertIterKey("l", iter.get());
batch.Put("ab", "cc"); ASSERT_OK(batch.Put("ab", "cc"));
iter->Next(); iter->Next();
AssertIterKey("m", iter.get()); AssertIterKey("m", iter.get());
batch.Put("mm", "kk"); ASSERT_OK(batch.Put("mm", "kk"));
iter->Next(); iter->Next();
AssertIterKey("mm", iter.get()); AssertIterKey("mm", iter.get());
AssertIterValue("kk", iter.get()); AssertIterValue("kk", iter.get());
batch.Delete("mm"); ASSERT_OK(batch.Delete("mm"));
iter->Next(); iter->Next();
AssertIterKey("n", iter.get()); AssertIterKey("n", iter.get());
iter->Prev(); iter->Prev();
@ -1436,13 +1438,13 @@ TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseCorrectnessTest) {
AssertIterKey("aa", iter.get()); AssertIterKey("aa", iter.get());
iter->Prev(); iter->Prev();
AssertIterKey("a", iter.get()); AssertIterKey("a", iter.get());
batch.Delete("aa"); ASSERT_OK(batch.Delete("aa"));
iter->Next(); iter->Next();
AssertIterKey("ab", iter.get()); AssertIterKey("ab", iter.get());
iter->Prev(); iter->Prev();
AssertIterKey("a", iter.get()); AssertIterKey("a", iter.get());
batch.Delete("x"); ASSERT_OK(batch.Delete("x"));
iter->Seek("x"); iter->Seek("x");
AssertIterKey("y", iter.get()); AssertIterKey("y", iter.get());
iter->Next(); iter->Next();
@ -1451,11 +1453,11 @@ TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseCorrectnessTest) {
iter->Prev(); iter->Prev();
AssertIterKey("w", iter.get()); AssertIterKey("w", iter.get());
batch.Delete("e"); ASSERT_OK(batch.Delete("e"));
iter->Seek("e"); iter->Seek("e");
AssertIterKey("ee", iter.get()); AssertIterKey("ee", iter.get());
AssertIterValue("ee", iter.get()); AssertIterValue("ee", iter.get());
batch.Put("ee", "xx"); ASSERT_OK(batch.Put("ee", "xx"));
// still the same value // still the same value
AssertIterValue("ee", iter.get()); AssertIterValue("ee", iter.get());
iter->Next(); iter->Next();
@ -1463,13 +1465,15 @@ TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseCorrectnessTest) {
iter->Prev(); iter->Prev();
// new value // new value
AssertIterValue("xx", iter.get()); AssertIterValue("xx", iter.get());
ASSERT_OK(iter->status());
} }
// stress testing mutations with IteratorWithBase // stress testing mutations with IteratorWithBase
TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseStressTest) { TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseStressTest) {
WriteBatchWithIndex batch(BytewiseComparator(), 0, true); WriteBatchWithIndex batch(BytewiseComparator(), 0, true);
for (char c = 'a'; c <= 'z'; ++c) { for (char c = 'a'; c <= 'z'; ++c) {
batch.Put(std::string(1, c), std::string(1, c)); ASSERT_OK(batch.Put(std::string(1, c), std::string(1, c)));
} }
KVMap map; KVMap map;
@ -1486,16 +1490,16 @@ TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseStressTest) {
char c = static_cast<char>(rnd.Uniform(26) + 'a'); char c = static_cast<char>(rnd.Uniform(26) + 'a');
switch (random) { switch (random) {
case 0: case 0:
batch.Put(std::string(1, c), "xxx"); ASSERT_OK(batch.Put(std::string(1, c), "xxx"));
break; break;
case 1: case 1:
batch.Put(std::string(2, c), "xxx"); ASSERT_OK(batch.Put(std::string(2, c), "xxx"));
break; break;
case 2: case 2:
batch.Delete(std::string(1, c)); ASSERT_OK(batch.Delete(std::string(1, c)));
break; break;
case 3: case 3:
batch.Delete(std::string(2, c)); ASSERT_OK(batch.Delete(std::string(2, c)));
break; break;
case 4: case 4:
iter->Seek(std::string(1, c)); iter->Seek(std::string(1, c));
@ -1517,12 +1521,12 @@ TEST_F(WriteBatchWithIndexTest, MutateWhileIteratingBaseStressTest) {
assert(false); assert(false);
} }
} }
ASSERT_OK(iter->status());
} }
static std::string PrintContents(WriteBatchWithIndex* batch, static void PrintContents(WriteBatchWithIndex* batch,
ColumnFamilyHandle* column_family) { ColumnFamilyHandle* column_family,
std::string result; std::string* result) {
WBWIIterator* iter; WBWIIterator* iter;
if (column_family == nullptr) { if (column_family == nullptr) {
iter = batch->NewIterator(); iter = batch->NewIterator();
@ -1532,41 +1536,50 @@ static std::string PrintContents(WriteBatchWithIndex* batch,
iter->SeekToFirst(); iter->SeekToFirst();
while (iter->Valid()) { while (iter->Valid()) {
ASSERT_OK(iter->status());
WriteEntry e = iter->Entry(); WriteEntry e = iter->Entry();
if (e.type == kPutRecord) { if (e.type == kPutRecord) {
result.append("PUT("); result->append("PUT(");
result.append(e.key.ToString()); result->append(e.key.ToString());
result.append("):"); result->append("):");
result.append(e.value.ToString()); result->append(e.value.ToString());
} else if (e.type == kMergeRecord) { } else if (e.type == kMergeRecord) {
result.append("MERGE("); result->append("MERGE(");
result.append(e.key.ToString()); result->append(e.key.ToString());
result.append("):"); result->append("):");
result.append(e.value.ToString()); result->append(e.value.ToString());
} else if (e.type == kSingleDeleteRecord) { } else if (e.type == kSingleDeleteRecord) {
result.append("SINGLE-DEL("); result->append("SINGLE-DEL(");
result.append(e.key.ToString()); result->append(e.key.ToString());
result.append(")"); result->append(")");
} else { } else {
assert(e.type == kDeleteRecord); assert(e.type == kDeleteRecord);
result.append("DEL("); result->append("DEL(");
result.append(e.key.ToString()); result->append(e.key.ToString());
result.append(")"); result->append(")");
} }
result.append(","); result->append(",");
iter->Next(); iter->Next();
} }
ASSERT_OK(iter->status());
delete iter; delete iter;
return result;
} }
static std::string PrintContents(WriteBatchWithIndex* batch, KVMap* base_map, static std::string PrintContents(WriteBatchWithIndex* batch,
ColumnFamilyHandle* column_family) { ColumnFamilyHandle* column_family) {
std::string result; std::string result;
PrintContents(batch, column_family, &result);
return result;
}
static void PrintContents(WriteBatchWithIndex* batch, KVMap* base_map,
ColumnFamilyHandle* column_family,
std::string* result) {
Iterator* iter; Iterator* iter;
if (column_family == nullptr) { if (column_family == nullptr) {
iter = batch->NewIteratorWithBase(new KVIter(base_map)); iter = batch->NewIteratorWithBase(new KVIter(base_map));
@ -1576,20 +1589,28 @@ static std::string PrintContents(WriteBatchWithIndex* batch, KVMap* base_map,
iter->SeekToFirst(); iter->SeekToFirst();
while (iter->Valid()) { while (iter->Valid()) {
assert(iter->status().ok()); ASSERT_OK(iter->status());
Slice key = iter->key(); Slice key = iter->key();
Slice value = iter->value(); Slice value = iter->value();
result.append(key.ToString()); result->append(key.ToString());
result.append(":"); result->append(":");
result.append(value.ToString()); result->append(value.ToString());
result.append(","); result->append(",");
iter->Next(); iter->Next();
} }
ASSERT_OK(iter->status());
delete iter; delete iter;
}
static std::string PrintContents(WriteBatchWithIndex* batch, KVMap* base_map,
ColumnFamilyHandle* column_family) {
std::string result;
PrintContents(batch, base_map, column_family, &result);
return result; return result;
} }
@ -1598,34 +1619,34 @@ TEST_F(WriteBatchWithIndexTest, SavePointTest) {
ColumnFamilyHandleImplDummy cf1(1, BytewiseComparator()); ColumnFamilyHandleImplDummy cf1(1, BytewiseComparator());
Status s; Status s;
batch.Put("A", "a"); ASSERT_OK(batch.Put("A", "a"));
batch.Put("B", "b"); ASSERT_OK(batch.Put("B", "b"));
batch.Put("A", "aa"); ASSERT_OK(batch.Put("A", "aa"));
batch.Put(&cf1, "A", "a1"); ASSERT_OK(batch.Put(&cf1, "A", "a1"));
batch.Delete(&cf1, "B"); ASSERT_OK(batch.Delete(&cf1, "B"));
batch.Put(&cf1, "C", "c1"); ASSERT_OK(batch.Put(&cf1, "C", "c1"));
batch.Put(&cf1, "E", "e1"); ASSERT_OK(batch.Put(&cf1, "E", "e1"));
batch.SetSavePoint(); // 1 batch.SetSavePoint(); // 1
batch.Put("C", "cc"); ASSERT_OK(batch.Put("C", "cc"));
batch.Put("B", "bb"); ASSERT_OK(batch.Put("B", "bb"));
batch.Delete("A"); ASSERT_OK(batch.Delete("A"));
batch.Put(&cf1, "B", "b1"); ASSERT_OK(batch.Put(&cf1, "B", "b1"));
batch.Delete(&cf1, "A"); ASSERT_OK(batch.Delete(&cf1, "A"));
batch.SingleDelete(&cf1, "E"); ASSERT_OK(batch.SingleDelete(&cf1, "E"));
batch.SetSavePoint(); // 2 batch.SetSavePoint(); // 2
batch.Put("A", "aaa"); ASSERT_OK(batch.Put("A", "aaa"));
batch.Put("A", "xxx"); ASSERT_OK(batch.Put("A", "xxx"));
batch.Delete("B"); ASSERT_OK(batch.Delete("B"));
batch.Put(&cf1, "B", "b2"); ASSERT_OK(batch.Put(&cf1, "B", "b2"));
batch.Delete(&cf1, "C"); ASSERT_OK(batch.Delete(&cf1, "C"));
batch.SetSavePoint(); // 3 batch.SetSavePoint(); // 3
batch.SetSavePoint(); // 4 batch.SetSavePoint(); // 4
batch.SingleDelete("D"); ASSERT_OK(batch.SingleDelete("D"));
batch.Delete(&cf1, "D"); ASSERT_OK(batch.Delete(&cf1, "D"));
batch.Delete(&cf1, "E"); ASSERT_OK(batch.Delete(&cf1, "E"));
ASSERT_EQ( ASSERT_EQ(
"PUT(A):a,PUT(A):aa,DEL(A),PUT(A):aaa,PUT(A):xxx,PUT(B):b,PUT(B):bb,DEL(" "PUT(A):a,PUT(A):aa,DEL(A),PUT(A):aaa,PUT(A):xxx,PUT(B):b,PUT(B):bb,DEL("
@ -1672,7 +1693,7 @@ TEST_F(WriteBatchWithIndexTest, SavePointTest) {
PrintContents(&batch, &cf1)); PrintContents(&batch, &cf1));
batch.SetSavePoint(); // 5 batch.SetSavePoint(); // 5
batch.Put("X", "x"); ASSERT_OK(batch.Put("X", "x"));
ASSERT_EQ("PUT(A):a,PUT(A):aa,DEL(A),PUT(B):b,PUT(B):bb,PUT(C):cc,PUT(X):x,", ASSERT_EQ("PUT(A):a,PUT(A):aa,DEL(A),PUT(B):b,PUT(B):bb,PUT(C):cc,PUT(X):x,",
PrintContents(&batch, nullptr)); PrintContents(&batch, nullptr));
@ -1715,7 +1736,7 @@ TEST_F(WriteBatchWithIndexTest, SingleDeleteTest) {
std::string value; std::string value;
DBOptions db_options; DBOptions db_options;
batch.SingleDelete("A"); ASSERT_OK(batch.SingleDelete("A"));
s = batch.GetFromBatch(db_options, "A", &value); s = batch.GetFromBatch(db_options, "A", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
@ -1725,10 +1746,10 @@ TEST_F(WriteBatchWithIndexTest, SingleDeleteTest) {
ASSERT_EQ("SINGLE-DEL(A),", value); ASSERT_EQ("SINGLE-DEL(A),", value);
batch.Clear(); batch.Clear();
batch.Put("A", "a"); ASSERT_OK(batch.Put("A", "a"));
batch.Put("A", "a2"); ASSERT_OK(batch.Put("A", "a2"));
batch.Put("B", "b"); ASSERT_OK(batch.Put("B", "b"));
batch.SingleDelete("A"); ASSERT_OK(batch.SingleDelete("A"));
s = batch.GetFromBatch(db_options, "A", &value); s = batch.GetFromBatch(db_options, "A", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
@ -1739,11 +1760,11 @@ TEST_F(WriteBatchWithIndexTest, SingleDeleteTest) {
value = PrintContents(&batch, nullptr); value = PrintContents(&batch, nullptr);
ASSERT_EQ("PUT(A):a,PUT(A):a2,SINGLE-DEL(A),PUT(B):b,", value); ASSERT_EQ("PUT(A):a,PUT(A):a2,SINGLE-DEL(A),PUT(B):b,", value);
batch.Put("C", "c"); ASSERT_OK(batch.Put("C", "c"));
batch.Put("A", "a3"); ASSERT_OK(batch.Put("A", "a3"));
batch.Delete("B"); ASSERT_OK(batch.Delete("B"));
batch.SingleDelete("B"); ASSERT_OK(batch.SingleDelete("B"));
batch.SingleDelete("C"); ASSERT_OK(batch.SingleDelete("C"));
s = batch.GetFromBatch(db_options, "A", &value); s = batch.GetFromBatch(db_options, "A", &value);
ASSERT_OK(s); ASSERT_OK(s);
@ -1761,12 +1782,12 @@ TEST_F(WriteBatchWithIndexTest, SingleDeleteTest) {
",PUT(C):c,SINGLE-DEL(C),", ",PUT(C):c,SINGLE-DEL(C),",
value); value);
batch.Put("B", "b4"); ASSERT_OK(batch.Put("B", "b4"));
batch.Put("C", "c4"); ASSERT_OK(batch.Put("C", "c4"));
batch.Put("D", "d4"); ASSERT_OK(batch.Put("D", "d4"));
batch.SingleDelete("D"); ASSERT_OK(batch.SingleDelete("D"));
batch.SingleDelete("D"); ASSERT_OK(batch.SingleDelete("D"));
batch.Delete("A"); ASSERT_OK(batch.Delete("A"));
s = batch.GetFromBatch(db_options, "A", &value); s = batch.GetFromBatch(db_options, "A", &value);
ASSERT_TRUE(s.IsNotFound()); ASSERT_TRUE(s.IsNotFound());
@ -1788,15 +1809,15 @@ TEST_F(WriteBatchWithIndexTest, SingleDeleteTest) {
} }
TEST_F(WriteBatchWithIndexTest, SingleDeleteDeltaIterTest) { TEST_F(WriteBatchWithIndexTest, SingleDeleteDeltaIterTest) {
Status s;
std::string value; std::string value;
DBOptions db_options; DBOptions db_options;
WriteBatchWithIndex batch(BytewiseComparator(), 20, true /* overwrite_key */); WriteBatchWithIndex batch(BytewiseComparator(), 20, true /* overwrite_key */);
batch.Put("A", "a");
batch.Put("A", "a2"); ASSERT_OK(batch.Put("A", "a"));
batch.Put("B", "b"); ASSERT_OK(batch.Put("A", "a2"));
batch.SingleDelete("A"); ASSERT_OK(batch.Put("B", "b"));
batch.Delete("B"); ASSERT_OK(batch.SingleDelete("A"));
ASSERT_OK(batch.Delete("B"));
KVMap map; KVMap map;
value = PrintContents(&batch, &map, nullptr); value = PrintContents(&batch, &map, nullptr);
@ -1806,20 +1827,20 @@ TEST_F(WriteBatchWithIndexTest, SingleDeleteDeltaIterTest) {
map["C"] = "cc"; map["C"] = "cc";
map["D"] = "dd"; map["D"] = "dd";
batch.SingleDelete("B"); ASSERT_OK(batch.SingleDelete("B"));
batch.SingleDelete("C"); ASSERT_OK(batch.SingleDelete("C"));
batch.SingleDelete("Z"); ASSERT_OK(batch.SingleDelete("Z"));
value = PrintContents(&batch, &map, nullptr); value = PrintContents(&batch, &map, nullptr);
ASSERT_EQ("D:dd,", value); ASSERT_EQ("D:dd,", value);
batch.Put("A", "a3"); ASSERT_OK(batch.Put("A", "a3"));
batch.Put("B", "b3"); ASSERT_OK(batch.Put("B", "b3"));
batch.SingleDelete("A"); ASSERT_OK(batch.SingleDelete("A"));
batch.SingleDelete("A"); ASSERT_OK(batch.SingleDelete("A"));
batch.SingleDelete("D"); ASSERT_OK(batch.SingleDelete("D"));
batch.SingleDelete("D"); ASSERT_OK(batch.SingleDelete("D"));
batch.Delete("D"); ASSERT_OK(batch.Delete("D"));
map["E"] = "ee"; map["E"] = "ee";

Loading…
Cancel
Save