// 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).
#pragma once
// longer be valid and should be discarded after a call to ClearSnapshot().
virtual void ClearSnapshot() = 0;
- // Prepare the current transation for 2PC
+ // Prepare the current transaction for 2PC
virtual Status Prepare() = 0;
// Write all batched keys to the db atomically.
// If there is no previous call to SetSavePoint(), returns Status::NotFound()
virtual Status RollbackToSavePoint() = 0;
+ // Pop the most recent save point.
+ // If there is no previous call to SetSavePoint(), Status::NotFound()
+ // will be returned.
+ // Otherwise returns Status::OK().
+ virtual Status PopSavePoint() = 0;
+
// This function is similar to DB::Get() except it will also read pending
// changes in this transaction. Currently, this function will return
// Status::MergeInProgress if the most recent write to the queried key in
ColumnFamilyHandle* column_family, const Slice& key,
std::string* value) = 0;
+ // An overload of the above method that receives a PinnableSlice
+ // For backward compatibility a default implementation is provided
+ virtual Status Get(const ReadOptions& options,
+ ColumnFamilyHandle* column_family, const Slice& key,
+ PinnableSlice* pinnable_val) {
+ assert(pinnable_val != nullptr);
+ auto s = Get(options, column_family, key, pinnable_val->GetSelf());
+ pinnable_val->PinSelf();
+ return s;
+ }
+
virtual Status Get(const ReadOptions& options, const Slice& key,
std::string* value) = 0;
+ virtual Status Get(const ReadOptions& options, const Slice& key,
+ PinnableSlice* pinnable_val) {
+ assert(pinnable_val != nullptr);
+ auto s = Get(options, key, pinnable_val->GetSelf());
+ pinnable_val->PinSelf();
+ return s;
+ }
virtual std::vector<Status> MultiGet(
const ReadOptions& options,
const Slice& key, std::string* value,
bool exclusive = true) = 0;
+ // An overload of the above method that receives a PinnableSlice
+ // For backward compatibility a default implementation is provided
+ virtual Status GetForUpdate(const ReadOptions& options,
+ ColumnFamilyHandle* /*column_family*/,
+ const Slice& key, PinnableSlice* pinnable_val,
+ bool /*exclusive*/ = true) {
+ if (pinnable_val == nullptr) {
+ std::string* null_str = nullptr;
+ return GetForUpdate(options, key, null_str);
+ } else {
+ auto s = GetForUpdate(options, key, pinnable_val->GetSelf());
+ pinnable_val->PinSelf();
+ return s;
+ }
+ }
+
virtual Status GetForUpdate(const ReadOptions& options, const Slice& key,
std::string* value, bool exclusive = true) = 0;
// gets committed successfully. But unlike Transaction::Put(),
// no conflict checking will be done for this key.
//
- // If this Transaction was created on a TransactionDB, this function will
- // still acquire locks necessary to make sure this write doesn't cause
- // conflicts in other transactions and may return Status::Busy().
+ // If this Transaction was created on a PessimisticTransactionDB, this
+ // function will still acquire locks necessary to make sure this write doesn't
+ // cause conflicts in other transactions and may return Status::Busy().
virtual Status PutUntracked(ColumnFamilyHandle* column_family,
const Slice& key, const Slice& value) = 0;
virtual Status PutUntracked(const Slice& key, const Slice& value) = 0;
virtual Status DeleteUntracked(ColumnFamilyHandle* column_family,
const SliceParts& key) = 0;
virtual Status DeleteUntracked(const SliceParts& key) = 0;
+ virtual Status SingleDeleteUntracked(ColumnFamilyHandle* column_family,
+ const Slice& key) = 0;
+
+ virtual Status SingleDeleteUntracked(const Slice& key) = 0;
// Similar to WriteBatch::PutLogData
virtual void PutLogData(const Slice& blob) = 0;
virtual void EnableIndexing() = 0;
// Returns the number of distinct Keys being tracked by this transaction.
- // If this transaction was created by a TransactinDB, this is the number of
+ // If this transaction was created by a TransactionDB, this is the number of
// keys that are currently locked by this transaction.
// If this transaction was created by an OptimisticTransactionDB, this is the
// number of keys that need to be checked for conflicts at commit time.
virtual bool IsDeadlockDetect() const { return false; }
- virtual std::vector<TransactionID> GetWaitingTxns(uint32_t* column_family_id,
- std::string* key) const {
+ virtual std::vector<TransactionID> GetWaitingTxns(
+ uint32_t* /*column_family_id*/, std::string* /*key*/) const {
assert(false);
return std::vector<TransactionID>();
}
TransactionState GetState() const { return txn_state_; }
void SetState(TransactionState state) { txn_state_ = state; }
+ // NOTE: Experimental feature
+ // The globally unique id with which the transaction is identified. This id
+ // might or might not be set depending on the implementation. Similarly the
+ // implementation decides the point in lifetime of a transaction at which it
+ // assigns the id. Although currently it is the case, the id is not guaranteed
+ // to remain the same across restarts.
+ uint64_t GetId() { return id_; }
+
protected:
- explicit Transaction(const TransactionDB* db) {}
- Transaction() {}
+ explicit Transaction(const TransactionDB* /*db*/) {}
+ Transaction() : log_number_(0), txn_state_(STARTED) {}
// the log in which the prepared section for this txn resides
// (for two phase commit)
// Execution status of the transaction.
std::atomic<TransactionState> txn_state_;
+ uint64_t id_ = 0;
+ virtual void SetId(uint64_t id) {
+ assert(id_ == 0);
+ id_ = id;
+ }
+
private:
+ friend class PessimisticTransactionDB;
+ friend class WriteUnpreparedTxnDB;
// No copying allowed
Transaction(const Transaction&);
void operator=(const Transaction&);