1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 #pragma once
7 #ifndef ROCKSDB_LITE
8 
9 #include <string>
10 #include <vector>
11 
12 #include "rocksdb/comparator.h"
13 #include "rocksdb/db.h"
14 #include "rocksdb/utilities/stackable_db.h"
15 
16 namespace ROCKSDB_NAMESPACE {
17 
18 class Transaction;
19 
20 // Database with Transaction support.
21 //
22 // See optimistic_transaction.h and examples/transaction_example.cc
23 
24 // Options to use when starting an Optimistic Transaction
25 struct OptimisticTransactionOptions {
26   // Setting set_snapshot=true is the same as calling SetSnapshot().
27   bool set_snapshot = false;
28 
29   // Should be set if the DB has a non-default comparator.
30   // See comment in WriteBatchWithIndex constructor.
31   const Comparator* cmp = BytewiseComparator();
32 };
33 
34 enum class OccValidationPolicy {
35   // Validate serially at commit stage, AFTER entering the write-group.
36   // Isolation validation is processed single-threaded(since in the
37   // write-group).
38   // May suffer from high mutex contention, as per this link:
39   // https://github.com/facebook/rocksdb/issues/4402
40   kValidateSerial = 0,
41   // Validate parallelly before commit stage, BEFORE entering the write-group to
42   // reduce mutex contention. Each txn acquires locks for its write-set
43   // records in some well-defined order.
44   kValidateParallel = 1
45 };
46 
47 struct OptimisticTransactionDBOptions {
48   OccValidationPolicy validate_policy = OccValidationPolicy::kValidateParallel;
49 
50   // works only if validate_policy == OccValidationPolicy::kValidateParallel
51   uint32_t occ_lock_buckets = (1 << 20);
52 };
53 
54 class OptimisticTransactionDB : public StackableDB {
55  public:
56   // Open an OptimisticTransactionDB similar to DB::Open().
57   static Status Open(const Options& options, const std::string& dbname,
58                      OptimisticTransactionDB** dbptr);
59 
60   static Status Open(const DBOptions& db_options, const std::string& dbname,
61                      const std::vector<ColumnFamilyDescriptor>& column_families,
62                      std::vector<ColumnFamilyHandle*>* handles,
63                      OptimisticTransactionDB** dbptr);
64 
65   static Status Open(const DBOptions& db_options,
66                      const OptimisticTransactionDBOptions& occ_options,
67                      const std::string& dbname,
68                      const std::vector<ColumnFamilyDescriptor>& column_families,
69                      std::vector<ColumnFamilyHandle*>* handles,
70                      OptimisticTransactionDB** dbptr);
71 
~OptimisticTransactionDB()72   virtual ~OptimisticTransactionDB() {}
73 
74   // Starts a new Transaction.
75   //
76   // Caller is responsible for deleting the returned transaction when no
77   // longer needed.
78   //
79   // If old_txn is not null, BeginTransaction will reuse this Transaction
80   // handle instead of allocating a new one.  This is an optimization to avoid
81   // extra allocations when repeatedly creating transactions.
82   virtual Transaction* BeginTransaction(
83       const WriteOptions& write_options,
84       const OptimisticTransactionOptions& txn_options =
85           OptimisticTransactionOptions(),
86       Transaction* old_txn = nullptr) = 0;
87 
88   OptimisticTransactionDB(const OptimisticTransactionDB&) = delete;
89   void operator=(const OptimisticTransactionDB&) = delete;
90 
91  protected:
92   // To Create an OptimisticTransactionDB, call Open()
OptimisticTransactionDB(DB * db)93   explicit OptimisticTransactionDB(DB* db) : StackableDB(db) {}
94 };
95 
96 }  // namespace ROCKSDB_NAMESPACE
97 
98 #endif  // ROCKSDB_LITE
99