// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
-// This source code is licensed under the BSD-style license found in the
-// LICENSE file in the root directory of this source tree. An additional grant
-// of patent rights can be found in the PATENTS file in the same directory.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
#ifndef ROCKSDB_LITE
class OptimisticTransactionTest : public testing::Test {
public:
OptimisticTransactionDB* txn_db;
- DB* db;
string dbname;
Options options;
OptimisticTransactionTest() {
options.create_if_missing = true;
options.max_write_buffer_number = 2;
- dbname = test::TmpDir() + "/optimistic_transaction_testdb";
+ dbname = test::PerThreadDBPath("optimistic_transaction_testdb");
DestroyDB(dbname, options);
Open();
}
- ~OptimisticTransactionTest() {
+ ~OptimisticTransactionTest() override {
delete txn_db;
DestroyDB(dbname, options);
}
void Reopen() {
delete txn_db;
+ txn_db = nullptr;
Open();
}
void Open() {
Status s = OptimisticTransactionDB::Open(options, dbname, &txn_db);
assert(s.ok());
- db = txn_db->GetBaseDB();
+ assert(txn_db != nullptr);
}
};
string value;
Status s;
- db->Put(write_options, Slice("foo"), Slice("bar"));
- db->Put(write_options, Slice("foo2"), Slice("bar"));
+ txn_db->Put(write_options, Slice("foo"), Slice("bar"));
+ txn_db->Put(write_options, Slice("foo2"), Slice("bar"));
Transaction* txn = txn_db->BeginTransaction(write_options);
ASSERT_TRUE(txn);
s = txn->Commit();
ASSERT_OK(s);
- db->Get(read_options, "foo", &value);
+ txn_db->Get(read_options, "foo", &value);
ASSERT_EQ(value, "bar2");
delete txn;
string value;
Status s;
- db->Put(write_options, "foo", "bar");
- db->Put(write_options, "foo2", "bar");
+ txn_db->Put(write_options, "foo", "bar");
+ txn_db->Put(write_options, "foo2", "bar");
Transaction* txn = txn_db->BeginTransaction(write_options);
ASSERT_TRUE(txn);
txn->Put("foo", "bar2");
// This Put outside of a transaction will conflict with the previous write
- s = db->Put(write_options, "foo", "barz");
+ s = txn_db->Put(write_options, "foo", "barz");
ASSERT_OK(s);
- s = db->Get(read_options, "foo", &value);
+ s = txn_db->Get(read_options, "foo", &value);
ASSERT_EQ(value, "barz");
ASSERT_EQ(1, txn->GetNumKeys());
ASSERT_TRUE(s.IsBusy()); // Txn should not commit
// Verify that transaction did not write anything
- db->Get(read_options, "foo", &value);
+ txn_db->Get(read_options, "foo", &value);
ASSERT_EQ(value, "barz");
- db->Get(read_options, "foo2", &value);
+ txn_db->Get(read_options, "foo2", &value);
ASSERT_EQ(value, "bar");
delete txn;
string value;
Status s;
- db->Put(write_options, "foo", "bar");
- db->Put(write_options, "foo2", "bar");
+ txn_db->Put(write_options, "foo", "bar");
+ txn_db->Put(write_options, "foo2", "bar");
txn_options.set_snapshot = true;
Transaction* txn = txn_db->BeginTransaction(write_options, txn_options);
ASSERT_TRUE(txn);
// This Put outside of a transaction will conflict with a later write
- s = db->Put(write_options, "foo", "barz");
+ s = txn_db->Put(write_options, "foo", "barz");
ASSERT_OK(s);
txn->Put("foo", "bar2"); // Conflicts with write done after snapshot taken
- s = db->Get(read_options, "foo", &value);
+ s = txn_db->Get(read_options, "foo", &value);
ASSERT_EQ(value, "barz");
s = txn->Commit();
ASSERT_TRUE(s.IsBusy()); // Txn should not commit
// Verify that transaction did not write anything
- db->Get(read_options, "foo", &value);
+ txn_db->Get(read_options, "foo", &value);
ASSERT_EQ(value, "barz");
- db->Get(read_options, "foo2", &value);
+ txn_db->Get(read_options, "foo2", &value);
ASSERT_EQ(value, "bar");
delete txn;
string value;
Status s;
- db->Put(write_options, "foo", "bar");
- db->Put(write_options, "foo2", "bar");
+ txn_db->Put(write_options, "foo", "bar");
+ txn_db->Put(write_options, "foo2", "bar");
txn_options.set_snapshot = true;
Transaction* txn = txn_db->BeginTransaction(write_options, txn_options);
ASSERT_EQ(value, "bar");
// This Put outside of a transaction will conflict with the previous read
- s = db->Put(write_options, "foo", "barz");
+ s = txn_db->Put(write_options, "foo", "barz");
ASSERT_OK(s);
- s = db->Get(read_options, "foo", &value);
+ s = txn_db->Get(read_options, "foo", &value);
ASSERT_EQ(value, "barz");
s = txn->Commit();
string value;
Status s;
- db->Put(write_options, Slice("foo"), Slice("bar"));
- db->Put(write_options, Slice("foo2"), Slice("bar"));
+ txn_db->Put(write_options, Slice("foo"), Slice("bar"));
+ txn_db->Put(write_options, Slice("foo2"), Slice("bar"));
Transaction* txn = txn_db->BeginTransaction(write_options);
ASSERT_TRUE(txn);
ASSERT_EQ(value, "bar2");
// Put a random key so we have a memtable to flush
- s = db->Put(write_options, "dummy", "dummy");
+ s = txn_db->Put(write_options, "dummy", "dummy");
ASSERT_OK(s);
// force a memtable flush
FlushOptions flush_ops;
- db->Flush(flush_ops);
+ txn_db->Flush(flush_ops);
s = txn->Commit();
// txn should commit since the flushed table is still in MemtableList History
ASSERT_OK(s);
- db->Get(read_options, "foo", &value);
+ txn_db->Get(read_options, "foo", &value);
ASSERT_EQ(value, "bar2");
delete txn;
string value;
Status s;
- db->Put(write_options, Slice("foo"), Slice("bar"));
- db->Put(write_options, Slice("foo2"), Slice("bar"));
+ txn_db->Put(write_options, Slice("foo"), Slice("bar"));
+ txn_db->Put(write_options, Slice("foo2"), Slice("bar"));
Transaction* txn = txn_db->BeginTransaction(write_options);
ASSERT_TRUE(txn);
ASSERT_EQ(value, "bar2");
// Put a random key so we have a MemTable to flush
- s = db->Put(write_options, "dummy", "dummy");
+ s = txn_db->Put(write_options, "dummy", "dummy");
ASSERT_OK(s);
// force a memtable flush
FlushOptions flush_ops;
- db->Flush(flush_ops);
+ txn_db->Flush(flush_ops);
// Put a random key so we have a MemTable to flush
- s = db->Put(write_options, "dummy", "dummy2");
+ s = txn_db->Put(write_options, "dummy", "dummy2");
ASSERT_OK(s);
// force a memtable flush
- db->Flush(flush_ops);
+ txn_db->Flush(flush_ops);
- s = db->Put(write_options, "dummy", "dummy3");
+ s = txn_db->Put(write_options, "dummy", "dummy3");
ASSERT_OK(s);
// force a memtable flush
// Since our test db has max_write_buffer_number=2, this flush will cause
// the first memtable to get purged from the MemtableList history.
- db->Flush(flush_ops);
+ txn_db->Flush(flush_ops);
s = txn->Commit();
// txn should not commit since MemTableList History is not large enough
ASSERT_TRUE(s.IsTryAgain());
- db->Get(read_options, "foo", &value);
+ txn_db->Get(read_options, "foo", &value);
ASSERT_EQ(value, "bar");
delete txn;
string value;
Status s;
- db->Put(write_options, "AAA", "bar");
+ txn_db->Put(write_options, "AAA", "bar");
Transaction* txn = txn_db->BeginTransaction(write_options);
ASSERT_TRUE(txn);
// Modify key after transaction start
- db->Put(write_options, "AAA", "bar1");
+ txn_db->Put(write_options, "AAA", "bar1");
// Read and write without a snapshot
txn->GetForUpdate(read_options, "AAA", &value);
string value;
Status s;
- db->Put(write_options, "AAA", "bar");
- db->Put(write_options, "BBB", "bar");
- db->Put(write_options, "CCC", "bar");
+ txn_db->Put(write_options, "AAA", "bar");
+ txn_db->Put(write_options, "BBB", "bar");
+ txn_db->Put(write_options, "CCC", "bar");
Transaction* txn = txn_db->BeginTransaction(write_options);
ASSERT_TRUE(txn);
- db->Put(write_options, "AAA", "bar1");
+ txn_db->Put(write_options, "AAA", "bar1");
// Read and write without a snapshot
txn->GetForUpdate(read_options, "AAA", &value);
txn->Put("AAA", "bar2");
// Modify BBB before snapshot is taken
- db->Put(write_options, "BBB", "bar1");
+ txn_db->Put(write_options, "BBB", "bar1");
txn->SetSnapshot();
snapshot_read_options.snapshot = txn->GetSnapshot();
ASSERT_EQ(value, "bar1");
txn->Put("BBB", "bar2");
- db->Put(write_options, "CCC", "bar1");
+ txn_db->Put(write_options, "CCC", "bar1");
// Set a new snapshot
txn->SetSnapshot();
ASSERT_OK(s);
ASSERT_EQ(value, "bar2");
- s = db->Get(read_options, "AAA", &value);
+ s = txn_db->Get(read_options, "AAA", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "bar1");
- s = db->Get(read_options, "BBB", &value);
+ s = txn_db->Get(read_options, "BBB", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "bar1");
- s = db->Get(read_options, "CCC", &value);
+ s = txn_db->Get(read_options, "CCC", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "bar1");
s = txn->Commit();
ASSERT_OK(s);
- s = db->Get(read_options, "AAA", &value);
+ s = txn_db->Get(read_options, "AAA", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "bar2");
- s = db->Get(read_options, "BBB", &value);
+ s = txn_db->Get(read_options, "BBB", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "bar2");
- s = db->Get(read_options, "CCC", &value);
+ s = txn_db->Get(read_options, "CCC", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "bar2");
txn = txn_db->BeginTransaction(write_options);
// Potentially conflicting writes
- db->Put(write_options, "ZZZ", "zzz");
- db->Put(write_options, "XXX", "xxx");
+ txn_db->Put(write_options, "ZZZ", "zzz");
+ txn_db->Put(write_options, "XXX", "xxx");
txn->SetSnapshot();
ColumnFamilyOptions cf_options;
// Create 2 new column families
- s = db->CreateColumnFamily(cf_options, "CFA", &cfa);
+ s = txn_db->CreateColumnFamily(cf_options, "CFA", &cfa);
ASSERT_OK(s);
- s = db->CreateColumnFamily(cf_options, "CFB", &cfb);
+ s = txn_db->CreateColumnFamily(cf_options, "CFB", &cfb);
ASSERT_OK(s);
delete cfa;
delete cfb;
delete txn_db;
+ txn_db = nullptr;
// open DB with three column families
std::vector<ColumnFamilyDescriptor> column_families;
s = OptimisticTransactionDB::Open(options, dbname, column_families, &handles,
&txn_db);
ASSERT_OK(s);
- db = txn_db->GetBaseDB();
+ assert(txn_db != nullptr);
Transaction* txn = txn_db->BeginTransaction(write_options);
ASSERT_TRUE(txn);
batch.Put("foo", "foo");
batch.Put(handles[1], "AAA", "bar");
batch.Put(handles[1], "AAAZZZ", "bar");
- s = db->Write(write_options, &batch);
+ s = txn_db->Write(write_options, &batch);
ASSERT_OK(s);
- db->Delete(write_options, handles[1], "AAAZZZ");
+ txn_db->Delete(write_options, handles[1], "AAAZZZ");
// These keys do no conflict with existing writes since they're in
// different column families
// Txn should commit
s = txn->Commit();
ASSERT_OK(s);
- s = db->Get(read_options, "AAA", &value);
+ s = txn_db->Get(read_options, "AAA", &value);
ASSERT_TRUE(s.IsNotFound());
- s = db->Get(read_options, handles[2], "AAAZZZ", &value);
+ s = txn_db->Get(read_options, handles[2], "AAAZZZ", &value);
ASSERT_EQ(value, "barbar");
Slice key_slices[3] = {Slice("AAA"), Slice("ZZ"), Slice("Z")};
// Verify txn did not commit
s = txn2->Commit();
ASSERT_TRUE(s.IsBusy());
- s = db->Get(read_options, handles[1], "AAAZZZ", &value);
+ s = txn_db->Get(read_options, handles[1], "AAAZZZ", &value);
ASSERT_EQ(value, "barbar");
delete txn;
// Txn should commit
s = txn->Commit();
ASSERT_OK(s);
- s = db->Get(read_options, handles[2], "ZZZ", &value);
+ s = txn_db->Get(read_options, handles[2], "ZZZ", &value);
ASSERT_TRUE(s.IsNotFound());
// Put a key which will conflict with the next txn using the previous snapshot
- db->Put(write_options, handles[2], "foo", "000");
+ txn_db->Put(write_options, handles[2], "foo", "000");
results = txn2->MultiGetForUpdate(snapshot_read_options, multiget_cfh,
multiget_keys, &values);
s = txn2->Commit();
ASSERT_TRUE(s.IsBusy());
- s = db->DropColumnFamily(handles[1]);
+ s = txn_db->DropColumnFamily(handles[1]);
ASSERT_OK(s);
- s = db->DropColumnFamily(handles[2]);
+ s = txn_db->DropColumnFamily(handles[2]);
ASSERT_OK(s);
delete txn;
string value;
Status s;
- s = db->Put(write_options, "aaa", "aaa");
+ s = txn_db->Put(write_options, "aaa", "aaa");
ASSERT_OK(s);
Transaction* txn = txn_db->BeginTransaction(write_options);
s = txn->GetForUpdate(read_options, "aaa", &value);
ASSERT_EQ(value, "aaa");
- s = db->Put(write_options, "aaa", "xxx");
+ s = txn_db->Put(write_options, "aaa", "xxx");
s = txn->Commit();
ASSERT_TRUE(s.IsBusy());
delete txn;
delete txn1;
delete txn2;
- s = db->Get(read_options, "1", &value);
+ s = txn_db->Get(read_options, "1", &value);
ASSERT_OK(s);
ASSERT_EQ(value, "8");
}
Transaction* txn = txn_db->BeginTransaction(write_options);
txn->PutUntracked("untracked", "0");
txn->Rollback();
- s = db->Get(read_options, "untracked", &value);
+ s = txn_db->Get(read_options, "untracked", &value);
ASSERT_TRUE(s.IsNotFound());
delete txn;
// Write to the untracked key outside of the transaction and verify
// it doesn't prevent the transaction from committing.
- s = db->Put(write_options, "untracked", "x");
+ s = txn_db->Put(write_options, "untracked", "x");
ASSERT_OK(s);
s = txn->Commit();
ASSERT_OK(s);
- s = db->Get(read_options, "untracked", &value);
+ s = txn_db->Get(read_options, "untracked", &value);
ASSERT_TRUE(s.IsNotFound());
delete txn;
// Write to tracked key outside of the transaction and verify that the
// untracked keys are not written when the commit fails.
- s = db->Delete(write_options, "tracked");
+ s = txn_db->Delete(write_options, "tracked");
s = txn->Commit();
ASSERT_TRUE(s.IsBusy());
- s = db->Get(read_options, "untracked", &value);
+ s = txn_db->Get(read_options, "untracked", &value);
ASSERT_TRUE(s.IsNotFound());
delete txn;
Status s;
// Write some keys to the db
- s = db->Put(write_options, "A", "a");
+ s = txn_db->Put(write_options, "A", "a");
ASSERT_OK(s);
- s = db->Put(write_options, "G", "g");
+ s = txn_db->Put(write_options, "G", "g");
ASSERT_OK(s);
- s = db->Put(write_options, "F", "f");
+ s = txn_db->Put(write_options, "F", "f");
ASSERT_OK(s);
- s = db->Put(write_options, "C", "c");
+ s = txn_db->Put(write_options, "C", "c");
ASSERT_OK(s);
- s = db->Put(write_options, "D", "d");
+ s = txn_db->Put(write_options, "D", "d");
ASSERT_OK(s);
Transaction* txn = txn_db->BeginTransaction(write_options);
const Snapshot* snapshot = txn->GetSnapshot();
// Write some keys to the db after the snapshot
- s = db->Put(write_options, "BB", "xx");
+ s = txn_db->Put(write_options, "BB", "xx");
ASSERT_OK(s);
- s = db->Put(write_options, "C", "xx");
+ s = txn_db->Put(write_options, "C", "xx");
ASSERT_OK(s);
read_options.snapshot = snapshot;
s = txn->Commit();
ASSERT_OK(s);
- s = db->Get(read_options, "B", &value);
+ s = txn_db->Get(read_options, "B", &value);
ASSERT_OK(s);
ASSERT_EQ("b", value);
s = txn->Commit();
ASSERT_OK(s);
- s = db->Get(read_options, "F", &value);
+ s = txn_db->Get(read_options, "F", &value);
ASSERT_OK(s);
ASSERT_EQ("f", value);
- s = db->Get(read_options, "G", &value);
+ s = txn_db->Get(read_options, "G", &value);
ASSERT_TRUE(s.IsNotFound());
- s = db->Get(read_options, "A", &value);
+ s = txn_db->Get(read_options, "A", &value);
ASSERT_OK(s);
ASSERT_EQ("aa", value);
- s = db->Get(read_options, "B", &value);
+ s = txn_db->Get(read_options, "B", &value);
ASSERT_OK(s);
ASSERT_EQ("b", value);
- s = db->Get(read_options, "C", &value);
+ s = txn_db->Get(read_options, "C", &value);
ASSERT_TRUE(s.IsNotFound());
- s = db->Get(read_options, "D", &value);
+ s = txn_db->Get(read_options, "D", &value);
ASSERT_TRUE(s.IsNotFound());
- s = db->Get(read_options, "E", &value);
+ s = txn_db->Get(read_options, "E", &value);
ASSERT_TRUE(s.IsNotFound());
delete txn;
string value;
Status s;
- db->Put(write_options, "A", "");
+ txn_db->Put(write_options, "A", "");
Transaction* txn1 = txn_db->BeginTransaction(write_options);
ASSERT_TRUE(txn1);
}
// Verify that data is consistent
- Status s = RandomTransactionInserter::Verify(db, num_sets);
+ Status s = RandomTransactionInserter::Verify(txn_db, num_sets);
ASSERT_OK(s);
}
#else
#include <stdio.h>
-int main(int argc, char** argv) {
+int main(int /*argc*/, char** /*argv*/) {
fprintf(
stderr,
"SKIPPED as optimistic_transaction is not supported in ROCKSDB_LITE\n");