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).
10 // For DeadlockInfoBuffer:
11 #include "util/thread_local.h"
12 #include "utilities/transactions/lock/point/point_lock_manager.h"
13 #include "utilities/transactions/lock/range/range_lock_manager.h"
16 #include "utilities/transactions/lock/range/range_tree/lib/locktree/lock_request.h"
17 #include "utilities/transactions/lock/range/range_tree/lib/locktree/locktree.h"
18 #include "utilities/transactions/lock/range/range_tree/range_tree_lock_tracker.h"
20 namespace ROCKSDB_NAMESPACE
{
22 typedef DeadlockInfoBufferTempl
<RangeDeadlockPath
> RangeDeadlockInfoBuffer
;
24 // A Range Lock Manager that uses PerconaFT's locktree library
25 class RangeTreeLockManager
: public RangeLockManagerBase
,
26 public RangeLockManagerHandle
{
28 LockManager
* getLockManager() override
{ return this; }
30 void AddColumnFamily(const ColumnFamilyHandle
* cfh
) override
;
31 void RemoveColumnFamily(const ColumnFamilyHandle
* cfh
) override
;
33 void Resize(uint32_t) override
;
34 std::vector
<DeadlockPath
> GetDeadlockInfoBuffer() override
;
36 std::vector
<RangeDeadlockPath
> GetRangeDeadlockInfoBuffer() override
;
37 void SetRangeDeadlockInfoBufferSize(uint32_t target_size
) override
;
39 // Get a lock on a range
40 // @note only exclusive locks are currently supported (requesting a
41 // non-exclusive lock will get an exclusive one)
42 using LockManager::TryLock
;
43 Status
TryLock(PessimisticTransaction
* txn
, ColumnFamilyId column_family_id
,
44 const Endpoint
& start_endp
, const Endpoint
& end_endp
, Env
* env
,
45 bool exclusive
) override
;
47 void UnLock(PessimisticTransaction
* txn
, const LockTracker
& tracker
,
49 void UnLock(PessimisticTransaction
* txn
, ColumnFamilyId column_family_id
,
50 const std::string
& key
, Env
* env
) override
;
51 void UnLock(PessimisticTransaction
*, ColumnFamilyId
, const Endpoint
&,
52 const Endpoint
&, Env
*) override
{
53 // TODO: range unlock does nothing...
56 explicit RangeTreeLockManager(
57 std::shared_ptr
<TransactionDBMutexFactory
> mutex_factory
);
59 ~RangeTreeLockManager() override
;
61 int SetMaxLockMemory(size_t max_lock_memory
) override
{
62 return ltm_
.set_max_lock_memory(max_lock_memory
);
65 size_t GetMaxLockMemory() override
{ return ltm_
.get_max_lock_memory(); }
67 Counters
GetStatus() override
;
69 bool IsPointLockSupported() const override
{
70 // One could have acquired a point lock (it is reduced to range lock)
74 PointLockStatus
GetPointLockStatus() override
;
76 // This is from LockManager
77 LockManager::RangeLockStatus
GetRangeLockStatus() override
;
79 // This has the same meaning as GetRangeLockStatus but is from
80 // RangeLockManagerHandle
81 RangeLockManagerHandle::RangeLockStatus
GetRangeLockStatusData() override
{
82 return GetRangeLockStatus();
85 bool IsRangeLockSupported() const override
{ return true; }
87 const LockTrackerFactory
& GetLockTrackerFactory() const override
{
88 return RangeTreeLockTrackerFactory::Get();
91 // Get the locktree which stores locks for the Column Family with given cf_id
92 std::shared_ptr
<toku::locktree
> GetLockTreeForCF(ColumnFamilyId cf_id
);
94 void SetEscalationBarrierFunc(EscalationBarrierFunc func
) override
{
99 toku::locktree_manager ltm_
;
101 EscalationBarrierFunc barrier_func_
=
102 [](const Endpoint
&, const Endpoint
&) -> bool { return false; };
104 std::shared_ptr
<TransactionDBMutexFactory
> mutex_factory_
;
106 // Map from cf_id to locktree*. Can only be accessed while holding the
107 // ltree_map_mutex_. Must use a custom deleter that calls ltm_.release_lt
109 std::unordered_map
<ColumnFamilyId
, std::shared_ptr
<toku::locktree
>>;
110 LockTreeMap ltree_map_
;
112 InstrumentedMutex ltree_map_mutex_
;
114 // Per-thread cache of ltree_map_.
115 // (uses the same approach as TransactionLockMgr::lock_maps_cache_)
116 std::unique_ptr
<ThreadLocalPtr
> ltree_lookup_cache_
;
118 RangeDeadlockInfoBuffer dlock_buffer_
;
120 std::shared_ptr
<toku::locktree
> MakeLockTreePtr(toku::locktree
* lt
);
121 static int CompareDbtEndpoints(void* arg
, const DBT
* a_key
, const DBT
* b_key
);
124 static int on_create(toku::locktree
*, void*);
125 static void on_destroy(toku::locktree
*) {}
126 static void on_escalate(TXNID txnid
, const toku::locktree
* lt
,
127 const toku::range_buffer
& buffer
, void* extra
);
129 static bool OnEscalationBarrierCheck(const DBT
* a
, const DBT
* b
, void* extra
);
132 void serialize_endpoint(const Endpoint
& endp
, std::string
* buf
);
133 void wait_callback_for_locktree(void* cdata
, toku::lock_wait_infos
* infos
);
135 } // namespace ROCKSDB_NAMESPACE
137 #endif // ROCKSDB_LITE