2016-02-10 00:12:00 +01:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
2017-07-16 01:03:42 +02:00
|
|
|
// 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).
|
2015-05-29 23:36:35 +02:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
#ifndef ROCKSDB_LITE
|
|
|
|
|
2020-01-07 23:19:06 +01:00
|
|
|
#include <mutex>
|
|
|
|
#include <vector>
|
|
|
|
#include <algorithm>
|
|
|
|
|
2015-05-29 23:36:35 +02:00
|
|
|
#include "rocksdb/db.h"
|
|
|
|
#include "rocksdb/options.h"
|
|
|
|
#include "rocksdb/utilities/optimistic_transaction_db.h"
|
|
|
|
|
2020-02-20 21:07:53 +01:00
|
|
|
namespace ROCKSDB_NAMESPACE {
|
2015-05-29 23:36:35 +02:00
|
|
|
|
|
|
|
class OptimisticTransactionDBImpl : public OptimisticTransactionDB {
|
|
|
|
public:
|
2020-01-07 23:19:06 +01:00
|
|
|
explicit OptimisticTransactionDBImpl(
|
|
|
|
DB* db, const OptimisticTransactionDBOptions& occ_options,
|
|
|
|
bool take_ownership = true)
|
|
|
|
: OptimisticTransactionDB(db),
|
|
|
|
db_owner_(take_ownership),
|
|
|
|
validate_policy_(occ_options.validate_policy) {
|
|
|
|
if (validate_policy_ == OccValidationPolicy::kValidateParallel) {
|
|
|
|
uint32_t bucket_size = std::max(16u, occ_options.occ_lock_buckets);
|
|
|
|
bucketed_locks_.reserve(bucket_size);
|
|
|
|
for (size_t i = 0; i < bucket_size; ++i) {
|
|
|
|
bucketed_locks_.emplace_back(
|
|
|
|
std::unique_ptr<std::mutex>(new std::mutex));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-05-29 23:36:35 +02:00
|
|
|
|
2017-05-10 23:54:35 +02:00
|
|
|
~OptimisticTransactionDBImpl() {
|
2018-04-04 00:24:23 +02:00
|
|
|
// Prevent this stackable from destroying
|
|
|
|
// base db
|
2017-05-10 23:54:35 +02:00
|
|
|
if (!db_owner_) {
|
2018-04-04 00:24:23 +02:00
|
|
|
db_ = nullptr;
|
2017-05-10 23:54:35 +02:00
|
|
|
}
|
|
|
|
}
|
2015-05-29 23:36:35 +02:00
|
|
|
|
2016-03-04 01:33:26 +01:00
|
|
|
Transaction* BeginTransaction(const WriteOptions& write_options,
|
|
|
|
const OptimisticTransactionOptions& txn_options,
|
|
|
|
Transaction* old_txn) override;
|
2015-05-29 23:36:35 +02:00
|
|
|
|
2021-02-06 00:55:34 +01:00
|
|
|
// Transactional `DeleteRange()` is not yet supported.
|
|
|
|
virtual Status DeleteRange(const WriteOptions&, ColumnFamilyHandle*,
|
|
|
|
const Slice&, const Slice&) override {
|
|
|
|
return Status::NotSupported();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Range deletions also must not be snuck into `WriteBatch`es as they are
|
|
|
|
// incompatible with `OptimisticTransactionDB`.
|
|
|
|
virtual Status Write(const WriteOptions& write_opts,
|
|
|
|
WriteBatch* batch) override {
|
|
|
|
if (batch->HasDeleteRange()) {
|
|
|
|
return Status::NotSupported();
|
|
|
|
}
|
|
|
|
return OptimisticTransactionDB::Write(write_opts, batch);
|
|
|
|
}
|
|
|
|
|
2020-01-07 23:19:06 +01:00
|
|
|
size_t GetLockBucketsSize() const { return bucketed_locks_.size(); }
|
|
|
|
|
|
|
|
OccValidationPolicy GetValidatePolicy() const { return validate_policy_; }
|
|
|
|
|
|
|
|
std::unique_lock<std::mutex> LockBucket(size_t idx);
|
|
|
|
|
2015-05-29 23:36:35 +02:00
|
|
|
private:
|
2020-01-07 23:19:06 +01:00
|
|
|
// NOTE: used in validation phase. Each key is hashed into some
|
|
|
|
// bucket. We then take the lock in the hash value order to avoid deadlock.
|
|
|
|
std::vector<std::unique_ptr<std::mutex>> bucketed_locks_;
|
|
|
|
|
|
|
|
bool db_owner_;
|
2018-04-04 00:24:23 +02:00
|
|
|
|
2020-01-07 23:19:06 +01:00
|
|
|
const OccValidationPolicy validate_policy_;
|
2016-03-04 01:33:26 +01:00
|
|
|
|
|
|
|
void ReinitializeTransaction(Transaction* txn,
|
|
|
|
const WriteOptions& write_options,
|
|
|
|
const OptimisticTransactionOptions& txn_options =
|
|
|
|
OptimisticTransactionOptions());
|
2015-05-29 23:36:35 +02:00
|
|
|
};
|
|
|
|
|
2020-02-20 21:07:53 +01:00
|
|
|
} // namespace ROCKSDB_NAMESPACE
|
2015-05-29 23:36:35 +02:00
|
|
|
#endif // ROCKSDB_LITE
|