@@ -31,16 +31,10 @@ struct WatchItem {
31
31
32
32
struct BlockingController ::WatchQueue {
33
33
deque<WatchItem> items;
34
- TxId notify_txid = UINT64_MAX;
35
34
36
35
// Updated by both coordinator and shard threads but at different times.
37
36
enum State { SUSPENDED, ACTIVE } state = SUSPENDED;
38
37
39
- void Suspend () {
40
- state = SUSPENDED;
41
- notify_txid = UINT64_MAX;
42
- }
43
-
44
38
auto Find (Transaction* tx) const {
45
39
return find_if (items.begin (), items.end (),
46
40
[tx](const WatchItem& wi) { return wi.get () == tx; });
@@ -49,7 +43,8 @@ struct BlockingController::WatchQueue {
49
43
50
44
// Watch state per db.
51
45
struct BlockingController ::DbWatchTable {
52
- WatchQueueMap queue_map;
46
+ // Watch queues per key
47
+ absl::flat_hash_map<std::string, std::unique_ptr<WatchQueue>> queue_map;
53
48
54
49
// awakened keys point to blocked keys that can potentially be unblocked.
55
50
absl::flat_hash_set<std::string> awakened_keys;
@@ -163,32 +158,16 @@ void BlockingController::NotifyPending() {
163
158
continue ;
164
159
165
160
context.db_index = index;
166
- DbWatchTable& wt = *dbit->second ;
167
- for (const auto & key : wt.awakened_keys ) {
168
- string_view sv_key = key;
169
- DVLOG (1 ) << " Processing awakened key " << sv_key;
170
- auto w_it = wt.queue_map .find (sv_key);
171
- if (w_it == wt.queue_map .end ()) {
172
- // This should not happen because we remove keys from awakened_keys every type we remove
173
- // the entry from queue_map. TODO: to make it a CHECK after Dec 2024
174
- LOG (ERROR) << " Internal error: Key " << sv_key
175
- << " was not found in the watch queue, wt.awakened_keys len is "
176
- << wt.awakened_keys .size () << " wt.queue_map len is " << wt.queue_map .size ();
177
- for (const auto & item : wt.awakened_keys ) {
178
- LOG (ERROR) << " Awakened key: " << item;
179
- }
180
-
181
- continue ;
182
- }
183
-
161
+ DbWatchTable& wt = *dbit->second ; // pointer stability due to node_hash_map
162
+ for (string_view key : wt.awakened_keys ) {
163
+ DVLOG (1 ) << " Processing awakened key " << key;
164
+ auto w_it = wt.queue_map .find (key);
184
165
CHECK (w_it != wt.queue_map .end ());
185
- DVLOG ( 1 ) << " Notify WQ: [ " << owner_-> shard_id () << " ] " << key;
166
+
186
167
WatchQueue* wq = w_it->second .get ();
187
- NotifyWatchQueue (sv_key, wq, context);
188
- if (wq->items .empty ()) {
189
- // we erase awakened_keys right after this loop finishes running.
168
+ NotifyWatchQueue (key, wq, context);
169
+ if (wq->items .empty ())
190
170
wt.queue_map .erase (w_it);
191
- }
192
171
}
193
172
wt.awakened_keys .clear ();
194
173
@@ -202,16 +181,15 @@ void BlockingController::NotifyPending() {
202
181
void BlockingController::AddWatched (Keys watch_keys, KeyReadyChecker krc, Transaction* trans) {
203
182
auto [dbit, added] = watched_dbs_.emplace (trans->GetDbIndex (), nullptr );
204
183
if (added) {
205
- dbit->second . reset ( new DbWatchTable);
184
+ dbit->second = make_unique< DbWatchTable>( );
206
185
}
207
186
208
187
DbWatchTable& wt = *dbit->second ;
209
188
210
189
for (auto key : watch_keys) {
211
190
auto [res, inserted] = wt.queue_map .emplace (key, nullptr );
212
- if (inserted) {
213
- res->second .reset (new WatchQueue);
214
- }
191
+ if (inserted)
192
+ res->second = make_unique<WatchQueue>();
215
193
216
194
if (!res->second ->items .empty ()) {
217
195
Transaction* last = res->second ->items .back ().get ();
@@ -227,7 +205,7 @@ void BlockingController::AddWatched(Keys watch_keys, KeyReadyChecker krc, Transa
227
205
}
228
206
229
207
// Called from commands like lpush.
230
- void BlockingController::AwakeWatched (DbIndex db_index, string_view db_key) {
208
+ void BlockingController::Awaken (DbIndex db_index, string_view db_key) {
231
209
auto it = watched_dbs_.find (db_index);
232
210
if (it == watched_dbs_.end ())
233
211
return ;
@@ -236,8 +214,7 @@ void BlockingController::AwakeWatched(DbIndex db_index, string_view db_key) {
236
214
DCHECK (!wt.queue_map .empty ());
237
215
238
216
if (wt.AddAwakeEvent (db_key)) {
239
- VLOG (1 ) << " AwakeWatched: db(" << db_index << " ) " << db_key;
240
-
217
+ VLOG (1 ) << " Touch: db(" << db_index << " ) " << db_key;
241
218
awakened_indices_.insert (db_index);
242
219
}
243
220
}
@@ -263,7 +240,6 @@ void BlockingController::NotifyWatchQueue(std::string_view key, WatchQueue* wq,
263
240
wq->state = WatchQueue::ACTIVE;
264
241
// We deliberately keep the notified transaction in the queue to know which queue
265
242
// must handled when this transaction finished.
266
- wq->notify_txid = owner_->committed_txid ();
267
243
awakened_transactions_.insert (head);
268
244
break ;
269
245
}
0 commit comments