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 #ifndef ROCKSDB_LITE
7 
8 #include "utilities/transactions/optimistic_transaction_db_impl.h"
9 
10 #include <string>
11 #include <vector>
12 
13 #include "db/db_impl/db_impl.h"
14 #include "rocksdb/db.h"
15 #include "rocksdb/options.h"
16 #include "rocksdb/utilities/optimistic_transaction_db.h"
17 #include "utilities/transactions/optimistic_transaction.h"
18 
19 namespace rocksdb {
20 
BeginTransaction(const WriteOptions & write_options,const OptimisticTransactionOptions & txn_options,Transaction * old_txn)21 Transaction* OptimisticTransactionDBImpl::BeginTransaction(
22     const WriteOptions& write_options,
23     const OptimisticTransactionOptions& txn_options, Transaction* old_txn) {
24   if (old_txn != nullptr) {
25     ReinitializeTransaction(old_txn, write_options, txn_options);
26     return old_txn;
27   } else {
28     return new OptimisticTransaction(this, write_options, txn_options);
29   }
30 }
31 
LockBucket(size_t idx)32 std::unique_lock<std::mutex> OptimisticTransactionDBImpl::LockBucket(
33     size_t idx) {
34   assert(idx < bucketed_locks_.size());
35   return std::unique_lock<std::mutex>(*bucketed_locks_[idx]);
36 }
37 
Open(const Options & options,const std::string & dbname,OptimisticTransactionDB ** dbptr)38 Status OptimisticTransactionDB::Open(const Options& options,
39                                      const std::string& dbname,
40                                      OptimisticTransactionDB** dbptr) {
41   DBOptions db_options(options);
42   ColumnFamilyOptions cf_options(options);
43   std::vector<ColumnFamilyDescriptor> column_families;
44   column_families.push_back(
45       ColumnFamilyDescriptor(kDefaultColumnFamilyName, cf_options));
46   std::vector<ColumnFamilyHandle*> handles;
47   Status s = Open(db_options, dbname, column_families, &handles, dbptr);
48   if (s.ok()) {
49     assert(handles.size() == 1);
50     // i can delete the handle since DBImpl is always holding a reference to
51     // default column family
52     delete handles[0];
53   }
54 
55   return s;
56 }
57 
Open(const DBOptions & db_options,const std::string & dbname,const std::vector<ColumnFamilyDescriptor> & column_families,std::vector<ColumnFamilyHandle * > * handles,OptimisticTransactionDB ** dbptr)58 Status OptimisticTransactionDB::Open(
59     const DBOptions& db_options, const std::string& dbname,
60     const std::vector<ColumnFamilyDescriptor>& column_families,
61     std::vector<ColumnFamilyHandle*>* handles,
62     OptimisticTransactionDB** dbptr) {
63   return OptimisticTransactionDB::Open(db_options,
64                                        OptimisticTransactionDBOptions(), dbname,
65                                        column_families, handles, dbptr);
66 }
67 
Open(const DBOptions & db_options,const OptimisticTransactionDBOptions & occ_options,const std::string & dbname,const std::vector<ColumnFamilyDescriptor> & column_families,std::vector<ColumnFamilyHandle * > * handles,OptimisticTransactionDB ** dbptr)68 Status OptimisticTransactionDB::Open(
69     const DBOptions& db_options,
70     const OptimisticTransactionDBOptions& occ_options,
71     const std::string& dbname,
72     const std::vector<ColumnFamilyDescriptor>& column_families,
73     std::vector<ColumnFamilyHandle*>* handles,
74     OptimisticTransactionDB** dbptr) {
75   Status s;
76   DB* db;
77 
78   std::vector<ColumnFamilyDescriptor> column_families_copy = column_families;
79 
80   // Enable MemTable History if not already enabled
81   for (auto& column_family : column_families_copy) {
82     ColumnFamilyOptions* options = &column_family.options;
83 
84     if (options->max_write_buffer_size_to_maintain == 0 &&
85         options->max_write_buffer_number_to_maintain == 0) {
86       // Setting to -1 will set the History size to
87       // max_write_buffer_number * write_buffer_size.
88       options->max_write_buffer_size_to_maintain = -1;
89     }
90   }
91 
92   s = DB::Open(db_options, dbname, column_families_copy, handles, &db);
93 
94   if (s.ok()) {
95     *dbptr = new OptimisticTransactionDBImpl(db, occ_options);
96   }
97 
98   return s;
99 }
100 
ReinitializeTransaction(Transaction * txn,const WriteOptions & write_options,const OptimisticTransactionOptions & txn_options)101 void OptimisticTransactionDBImpl::ReinitializeTransaction(
102     Transaction* txn, const WriteOptions& write_options,
103     const OptimisticTransactionOptions& txn_options) {
104   assert(dynamic_cast<OptimisticTransaction*>(txn) != nullptr);
105   auto txn_impl = reinterpret_cast<OptimisticTransaction*>(txn);
106 
107   txn_impl->Reinitialize(this, write_options, txn_options);
108 }
109 
110 }  //  namespace rocksdb
111 #endif  // ROCKSDB_LITE
112