]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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 | #include "db/logs_with_prep_tracker.h" | |
7 | ||
8 | #include "port/likely.h" | |
9 | ||
f67539c2 | 10 | namespace ROCKSDB_NAMESPACE { |
11fdf7f2 TL |
11 | void LogsWithPrepTracker::MarkLogAsHavingPrepSectionFlushed(uint64_t log) { |
12 | assert(log != 0); | |
13 | std::lock_guard<std::mutex> lock(prepared_section_completed_mutex_); | |
14 | auto it = prepared_section_completed_.find(log); | |
15 | if (UNLIKELY(it == prepared_section_completed_.end())) { | |
16 | prepared_section_completed_[log] = 1; | |
17 | } else { | |
18 | it->second += 1; | |
19 | } | |
20 | } | |
21 | ||
22 | void LogsWithPrepTracker::MarkLogAsContainingPrepSection(uint64_t log) { | |
23 | assert(log != 0); | |
24 | std::lock_guard<std::mutex> lock(logs_with_prep_mutex_); | |
25 | ||
26 | auto rit = logs_with_prep_.rbegin(); | |
27 | bool updated = false; | |
28 | // Most probably the last log is the one that is being marked for | |
29 | // having a prepare section; so search from the end. | |
30 | for (; rit != logs_with_prep_.rend() && rit->log >= log; ++rit) { | |
31 | if (rit->log == log) { | |
32 | rit->cnt++; | |
33 | updated = true; | |
34 | break; | |
35 | } | |
36 | } | |
37 | if (!updated) { | |
38 | // We are either at the start, or at a position with rit->log < log | |
39 | logs_with_prep_.insert(rit.base(), {log, 1}); | |
40 | } | |
41 | } | |
42 | ||
43 | uint64_t LogsWithPrepTracker::FindMinLogContainingOutstandingPrep() { | |
44 | std::lock_guard<std::mutex> lock(logs_with_prep_mutex_); | |
45 | auto it = logs_with_prep_.begin(); | |
46 | // start with the smallest log | |
47 | for (; it != logs_with_prep_.end();) { | |
48 | auto min_log = it->log; | |
49 | { | |
50 | std::lock_guard<std::mutex> lock2(prepared_section_completed_mutex_); | |
51 | auto completed_it = prepared_section_completed_.find(min_log); | |
52 | if (completed_it == prepared_section_completed_.end() || | |
53 | completed_it->second < it->cnt) { | |
54 | return min_log; | |
55 | } | |
56 | assert(completed_it != prepared_section_completed_.end() && | |
57 | completed_it->second == it->cnt); | |
58 | prepared_section_completed_.erase(completed_it); | |
59 | } | |
60 | // erase from beginning in vector is not efficient but this function is not | |
61 | // on the fast path. | |
62 | it = logs_with_prep_.erase(it); | |
63 | } | |
64 | // no such log found | |
65 | return 0; | |
66 | } | |
f67539c2 | 67 | } // namespace ROCKSDB_NAMESPACE |