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 #pragma once 7 #ifndef ROCKSDB_LITE 8 #ifndef OS_WIN 9 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" 14 15 // Lock Tree library: 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" 19 20 namespace ROCKSDB_NAMESPACE { 21 22 using namespace toku; 23 24 typedef DeadlockInfoBufferTempl<RangeDeadlockPath> RangeDeadlockInfoBuffer; 25 26 // A Range Lock Manager that uses PerconaFT's locktree library 27 class RangeTreeLockManager : public RangeLockManagerBase, 28 public RangeLockManagerHandle { 29 public: getLockManager()30 LockManager* getLockManager() override { return this; } 31 32 void AddColumnFamily(const ColumnFamilyHandle* cfh) override; 33 void RemoveColumnFamily(const ColumnFamilyHandle* cfh) override; 34 35 void Resize(uint32_t) override; 36 std::vector<DeadlockPath> GetDeadlockInfoBuffer() override; 37 38 std::vector<RangeDeadlockPath> GetRangeDeadlockInfoBuffer() override; 39 void SetRangeDeadlockInfoBufferSize(uint32_t target_size) override; 40 41 // Get a lock on a range 42 // @note only exclusive locks are currently supported (requesting a 43 // non-exclusive lock will get an exclusive one) 44 using LockManager::TryLock; 45 Status TryLock(PessimisticTransaction* txn, ColumnFamilyId column_family_id, 46 const Endpoint& start_endp, const Endpoint& end_endp, Env* env, 47 bool exclusive) override; 48 49 void UnLock(PessimisticTransaction* txn, const LockTracker& tracker, 50 Env* env) override; 51 void UnLock(PessimisticTransaction* txn, ColumnFamilyId column_family_id, 52 const std::string& key, Env* env) override; UnLock(PessimisticTransaction *,ColumnFamilyId,const Endpoint &,const Endpoint &,Env *)53 void UnLock(PessimisticTransaction*, ColumnFamilyId, const Endpoint&, 54 const Endpoint&, Env*) override { 55 // TODO: range unlock does nothing... 56 } 57 58 explicit RangeTreeLockManager( 59 std::shared_ptr<TransactionDBMutexFactory> mutex_factory); 60 61 ~RangeTreeLockManager() override; 62 SetMaxLockMemory(size_t max_lock_memory)63 int SetMaxLockMemory(size_t max_lock_memory) override { 64 return ltm_.set_max_lock_memory(max_lock_memory); 65 } 66 GetMaxLockMemory()67 size_t GetMaxLockMemory() override { return ltm_.get_max_lock_memory(); } 68 69 Counters GetStatus() override; 70 IsPointLockSupported()71 bool IsPointLockSupported() const override { 72 // One could have acquired a point lock (it is reduced to range lock) 73 return true; 74 } 75 76 PointLockStatus GetPointLockStatus() override; 77 78 // This is from LockManager 79 LockManager::RangeLockStatus GetRangeLockStatus() override; 80 81 // This has the same meaning as GetRangeLockStatus but is from 82 // RangeLockManagerHandle GetRangeLockStatusData()83 RangeLockManagerHandle::RangeLockStatus GetRangeLockStatusData() override { 84 return GetRangeLockStatus(); 85 } 86 IsRangeLockSupported()87 bool IsRangeLockSupported() const override { return true; } 88 GetLockTrackerFactory()89 const LockTrackerFactory& GetLockTrackerFactory() const override { 90 return RangeTreeLockTrackerFactory::Get(); 91 } 92 93 // Get the locktree which stores locks for the Column Family with given cf_id 94 std::shared_ptr<locktree> GetLockTreeForCF(ColumnFamilyId cf_id); 95 96 private: 97 toku::locktree_manager ltm_; 98 99 std::shared_ptr<TransactionDBMutexFactory> mutex_factory_; 100 101 // Map from cf_id to locktree*. Can only be accessed while holding the 102 // ltree_map_mutex_. Must use a custom deleter that calls ltm_.release_lt 103 using LockTreeMap = 104 std::unordered_map<ColumnFamilyId, std::shared_ptr<locktree>>; 105 LockTreeMap ltree_map_; 106 107 InstrumentedMutex ltree_map_mutex_; 108 109 // Per-thread cache of ltree_map_. 110 // (uses the same approach as TransactionLockMgr::lock_maps_cache_) 111 std::unique_ptr<ThreadLocalPtr> ltree_lookup_cache_; 112 113 RangeDeadlockInfoBuffer dlock_buffer_; 114 115 std::shared_ptr<locktree> MakeLockTreePtr(locktree* lt); 116 static int CompareDbtEndpoints(void* arg, const DBT* a_key, const DBT* b_key); 117 118 // Callbacks on_create(locktree *,void *)119 static int on_create(locktree*, void*) { return 0; /* no error */ } on_destroy(locktree *)120 static void on_destroy(locktree*) {} 121 static void on_escalate(TXNID txnid, const locktree* lt, 122 const range_buffer& buffer, void* extra); 123 }; 124 125 void serialize_endpoint(const Endpoint& endp, std::string* buf); 126 void wait_callback_for_locktree(void* cdata, lock_wait_infos* infos); 127 128 } // namespace ROCKSDB_NAMESPACE 129 #endif // OS_WIN 130 #endif // ROCKSDB_LITE 131