/src/rocksdb/utilities/transactions/lock/lock_tracker.h
Line | Count | Source |
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 | | |
8 | | #include <memory> |
9 | | |
10 | | #include "rocksdb/rocksdb_namespace.h" |
11 | | #include "rocksdb/status.h" |
12 | | #include "rocksdb/types.h" |
13 | | #include "rocksdb/utilities/transaction_db.h" |
14 | | |
15 | | namespace ROCKSDB_NAMESPACE { |
16 | | |
17 | | // Request for locking a single key. |
18 | | struct PointLockRequest { |
19 | | // The id of the key's column family. |
20 | | ColumnFamilyId column_family_id = 0; |
21 | | // The key to lock. |
22 | | std::string key; |
23 | | // The sequence number from which there is no concurrent update to key. |
24 | | SequenceNumber seq = 0; |
25 | | // Whether the lock is acquired only for read. |
26 | | bool read_only = false; |
27 | | // Whether the lock is in exclusive mode. |
28 | | bool exclusive = true; |
29 | | }; |
30 | | |
31 | | // Request for locking a range of keys. |
32 | | struct RangeLockRequest { |
33 | | // The id of the key's column family. |
34 | | ColumnFamilyId column_family_id; |
35 | | |
36 | | // The range to be locked |
37 | | Endpoint start_endp; |
38 | | Endpoint end_endp; |
39 | | }; |
40 | | |
41 | | struct PointLockStatus { |
42 | | // Whether the key is locked. |
43 | | bool locked = false; |
44 | | // Whether the key is locked in exclusive mode. |
45 | | bool exclusive = true; |
46 | | // The sequence number in the tracked PointLockRequest. |
47 | | SequenceNumber seq = 0; |
48 | | }; |
49 | | |
50 | | // Return status when calling LockTracker::Untrack. |
51 | | enum class UntrackStatus { |
52 | | // The lock is not tracked at all, so no lock to untrack. |
53 | | NOT_TRACKED, |
54 | | // The lock is untracked but not removed from the tracker. |
55 | | UNTRACKED, |
56 | | // The lock is removed from the tracker. |
57 | | REMOVED, |
58 | | }; |
59 | | |
60 | | // Tracks the lock requests. |
61 | | // In PessimisticTransaction, it tracks the locks acquired through LockMgr; |
62 | | // In OptimisticTransaction, since there is no LockMgr, it tracks the lock |
63 | | // intention. Not thread-safe. |
64 | | class LockTracker { |
65 | | public: |
66 | 0 | virtual ~LockTracker() {} |
67 | | |
68 | | // Whether supports locking a specific key. |
69 | | virtual bool IsPointLockSupported() const = 0; |
70 | | |
71 | | // Whether supports locking a range of keys. |
72 | | virtual bool IsRangeLockSupported() const = 0; |
73 | | |
74 | | // Tracks the acquirement of a lock on key. |
75 | | // |
76 | | // If this method is not supported, leave it as a no-op. |
77 | | virtual void Track(const PointLockRequest& /*lock_request*/) = 0; |
78 | | |
79 | | // Untracks the lock on a key. |
80 | | // seq and exclusive in lock_request are not used. |
81 | | // |
82 | | // If this method is not supported, leave it as a no-op and |
83 | | // returns NOT_TRACKED. |
84 | | virtual UntrackStatus Untrack(const PointLockRequest& /*lock_request*/) = 0; |
85 | | |
86 | | // Counterpart of Track(const PointLockRequest&) for RangeLockRequest. |
87 | | virtual void Track(const RangeLockRequest& /*lock_request*/) = 0; |
88 | | |
89 | | // Counterpart of Untrack(const PointLockRequest&) for RangeLockRequest. |
90 | | virtual UntrackStatus Untrack(const RangeLockRequest& /*lock_request*/) = 0; |
91 | | |
92 | | // Merges lock requests tracked in the specified tracker into the current |
93 | | // tracker. |
94 | | // |
95 | | // E.g. for point lock, if a key in tracker is not yet tracked, |
96 | | // track this new key; otherwise, merge the tracked information of the key |
97 | | // such as lock's exclusiveness, read/write statistics. |
98 | | // |
99 | | // If this method is not supported, leave it as a no-op. |
100 | | // |
101 | | // REQUIRED: the specified tracker must be of the same concrete class type as |
102 | | // the current tracker. |
103 | | virtual void Merge(const LockTracker& /*tracker*/) = 0; |
104 | | |
105 | | // This is a reverse operation of Merge. |
106 | | // |
107 | | // E.g. for point lock, if a key exists in both current and the sepcified |
108 | | // tracker, then subtract the information (such as read/write statistics) of |
109 | | // the key in the specified tracker from the current tracker. |
110 | | // |
111 | | // If this method is not supported, leave it as a no-op. |
112 | | // |
113 | | // REQUIRED: |
114 | | // The specified tracker must be of the same concrete class type as |
115 | | // the current tracker. |
116 | | // The tracked locks in the specified tracker must be a subset of those |
117 | | // tracked by the current tracker. |
118 | | virtual void Subtract(const LockTracker& /*tracker*/) = 0; |
119 | | |
120 | | // Clears all tracked locks. |
121 | | virtual void Clear() = 0; |
122 | | |
123 | | // Gets the new locks (excluding the locks that have been tracked before the |
124 | | // save point) tracked since the specified save point, the result is stored |
125 | | // in an internally constructed LockTracker and returned. |
126 | | // |
127 | | // save_point_tracker is the tracker used by a SavePoint to track locks |
128 | | // tracked after creating the SavePoint. |
129 | | // |
130 | | // The implementation should document whether point lock, or range lock, or |
131 | | // both are considered in this method. |
132 | | // If this method is not supported, returns nullptr. |
133 | | // |
134 | | // REQUIRED: |
135 | | // The save_point_tracker must be of the same concrete class type as the |
136 | | // current tracker. |
137 | | // The tracked locks in the specified tracker must be a subset of those |
138 | | // tracked by the current tracker. |
139 | | virtual LockTracker* GetTrackedLocksSinceSavePoint( |
140 | | const LockTracker& /*save_point_tracker*/) const = 0; |
141 | | |
142 | | // Gets lock related information of the key. |
143 | | // |
144 | | // If point lock is not supported, always returns LockStatus with |
145 | | // locked=false. |
146 | | virtual PointLockStatus GetPointLockStatus( |
147 | | ColumnFamilyId /*column_family_id*/, |
148 | | const std::string& /*key*/) const = 0; |
149 | | |
150 | | // Gets number of tracked point locks. |
151 | | // |
152 | | // If point lock is not supported, always returns 0. |
153 | | virtual uint64_t GetNumPointLocks() const = 0; |
154 | | |
155 | | class ColumnFamilyIterator { |
156 | | public: |
157 | 0 | virtual ~ColumnFamilyIterator() {} |
158 | | |
159 | | // Whether there are remaining column families. |
160 | | virtual bool HasNext() const = 0; |
161 | | |
162 | | // Gets next column family id. |
163 | | // |
164 | | // If HasNext is false, calling this method has undefined behavior. |
165 | | virtual ColumnFamilyId Next() = 0; |
166 | | }; |
167 | | |
168 | | // Gets an iterator for column families. |
169 | | // |
170 | | // Returned iterator must not be nullptr. |
171 | | // If there is no column family to iterate, |
172 | | // returns an empty non-null iterator. |
173 | | // Caller owns the returned pointer. |
174 | | virtual ColumnFamilyIterator* GetColumnFamilyIterator() const = 0; |
175 | | |
176 | | class KeyIterator { |
177 | | public: |
178 | 0 | virtual ~KeyIterator() {} |
179 | | |
180 | | // Whether there are remaining keys. |
181 | | virtual bool HasNext() const = 0; |
182 | | |
183 | | // Gets the next key. |
184 | | // |
185 | | // If HasNext is false, calling this method has undefined behavior. |
186 | | virtual const std::string& Next() = 0; |
187 | | }; |
188 | | |
189 | | // Gets an iterator for keys with tracked point locks in the column family. |
190 | | // |
191 | | // The column family must exist. |
192 | | // Returned iterator must not be nullptr. |
193 | | // Caller owns the returned pointer. |
194 | | virtual KeyIterator* GetKeyIterator( |
195 | | ColumnFamilyId /*column_family_id*/) const = 0; |
196 | | }; |
197 | | |
198 | | // LockTracker should always be constructed through this factory. |
199 | | // Each LockManager owns a LockTrackerFactory. |
200 | | class LockTrackerFactory { |
201 | | public: |
202 | | // Caller owns the returned pointer. |
203 | | virtual LockTracker* Create() const = 0; |
204 | 0 | virtual ~LockTrackerFactory() {} |
205 | | }; |
206 | | |
207 | | } // namespace ROCKSDB_NAMESPACE |