]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/transactions/optimistic_transaction_impl.cc
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / rocksdb / utilities / transactions / optimistic_transaction_impl.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
5
6 #ifndef ROCKSDB_LITE
7
8 #include "utilities/transactions/optimistic_transaction_impl.h"
9
10 #include <algorithm>
11 #include <string>
12 #include <vector>
13
14 #include "db/column_family.h"
15 #include "db/db_impl.h"
16 #include "rocksdb/comparator.h"
17 #include "rocksdb/db.h"
18 #include "rocksdb/status.h"
19 #include "rocksdb/utilities/optimistic_transaction_db.h"
20 #include "util/string_util.h"
21 #include "utilities/transactions/transaction_util.h"
22
23 namespace rocksdb {
24
25 struct WriteOptions;
26
27 OptimisticTransactionImpl::OptimisticTransactionImpl(
28 OptimisticTransactionDB* txn_db, const WriteOptions& write_options,
29 const OptimisticTransactionOptions& txn_options)
30 : TransactionBaseImpl(txn_db->GetBaseDB(), write_options), txn_db_(txn_db) {
31 Initialize(txn_options);
32 }
33
34 void OptimisticTransactionImpl::Initialize(
35 const OptimisticTransactionOptions& txn_options) {
36 if (txn_options.set_snapshot) {
37 SetSnapshot();
38 }
39 }
40
41 void OptimisticTransactionImpl::Reinitialize(
42 OptimisticTransactionDB* txn_db, const WriteOptions& write_options,
43 const OptimisticTransactionOptions& txn_options) {
44 TransactionBaseImpl::Reinitialize(txn_db->GetBaseDB(), write_options);
45 Initialize(txn_options);
46 }
47
48 OptimisticTransactionImpl::~OptimisticTransactionImpl() {
49 }
50
51 void OptimisticTransactionImpl::Clear() {
52 TransactionBaseImpl::Clear();
53 }
54
55 Status OptimisticTransactionImpl::Prepare() {
56 return Status::InvalidArgument(
57 "Two phase commit not supported for optimistic transactions.");
58 }
59
60 Status OptimisticTransactionImpl::Commit() {
61 // Set up callback which will call CheckTransactionForConflicts() to
62 // check whether this transaction is safe to be committed.
63 OptimisticTransactionCallback callback(this);
64
65 DBImpl* db_impl = dynamic_cast<DBImpl*>(db_->GetRootDB());
66 if (db_impl == nullptr) {
67 // This should only happen if we support creating transactions from
68 // a StackableDB and someone overrides GetRootDB().
69 return Status::InvalidArgument(
70 "DB::GetRootDB() returned an unexpected DB class");
71 }
72
73 Status s = db_impl->WriteWithCallback(
74 write_options_, GetWriteBatch()->GetWriteBatch(), &callback);
75
76 if (s.ok()) {
77 Clear();
78 }
79
80 return s;
81 }
82
83 Status OptimisticTransactionImpl::Rollback() {
84 Clear();
85 return Status::OK();
86 }
87
88 // Record this key so that we can check it for conflicts at commit time.
89 //
90 // 'exclusive' is unused for OptimisticTransaction.
91 Status OptimisticTransactionImpl::TryLock(ColumnFamilyHandle* column_family,
92 const Slice& key, bool read_only,
93 bool exclusive, bool untracked) {
94 if (untracked) {
95 return Status::OK();
96 }
97 uint32_t cfh_id = GetColumnFamilyID(column_family);
98
99 SetSnapshotIfNeeded();
100
101 SequenceNumber seq;
102 if (snapshot_) {
103 seq = snapshot_->GetSequenceNumber();
104 } else {
105 seq = db_->GetLatestSequenceNumber();
106 }
107
108 std::string key_str = key.ToString();
109
110 TrackKey(cfh_id, key_str, seq, read_only, exclusive);
111
112 // Always return OK. Confilct checking will happen at commit time.
113 return Status::OK();
114 }
115
116 // Returns OK if it is safe to commit this transaction. Returns Status::Busy
117 // if there are read or write conflicts that would prevent us from committing OR
118 // if we can not determine whether there would be any such conflicts.
119 //
120 // Should only be called on writer thread in order to avoid any race conditions
121 // in detecting write conflicts.
122 Status OptimisticTransactionImpl::CheckTransactionForConflicts(DB* db) {
123 Status result;
124
125 assert(dynamic_cast<DBImpl*>(db) != nullptr);
126 auto db_impl = reinterpret_cast<DBImpl*>(db);
127
128 // Since we are on the write thread and do not want to block other writers,
129 // we will do a cache-only conflict check. This can result in TryAgain
130 // getting returned if there is not sufficient memtable history to check
131 // for conflicts.
132 return TransactionUtil::CheckKeysForConflicts(db_impl, GetTrackedKeys(),
133 true /* cache_only */);
134 }
135
136 Status OptimisticTransactionImpl::SetName(const TransactionName& name) {
137 return Status::InvalidArgument("Optimistic transactions cannot be named.");
138 }
139
140 } // namespace rocksdb
141
142 #endif // ROCKSDB_LITE