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 <stdint.h>
9 #include <cassert>
10 #include <cstdlib>
11 #include <mutex>
12 #include <unordered_map>
13 #include <vector>
14 
15 #include "rocksdb/rocksdb_namespace.h"
16 
17 namespace ROCKSDB_NAMESPACE {
18 
19 // This class is used to track the log files with outstanding prepare entries.
20 class LogsWithPrepTracker {
21  public:
22   // Called when a transaction prepared in `log` has been committed or aborted.
23   void MarkLogAsHavingPrepSectionFlushed(uint64_t log);
24   // Called when a transaction is prepared in `log`.
25   void MarkLogAsContainingPrepSection(uint64_t log);
26   // Return the earliest log file with outstanding prepare entries.
27   uint64_t FindMinLogContainingOutstandingPrep();
TEST_PreparedSectionCompletedSize()28   size_t TEST_PreparedSectionCompletedSize() {
29     return prepared_section_completed_.size();
30   }
TEST_LogsWithPrepSize()31   size_t TEST_LogsWithPrepSize() { return logs_with_prep_.size(); }
32 
33  private:
34   // REQUIRES: logs_with_prep_mutex_ held
35   //
36   // sorted list of log numbers still containing prepared data.
37   // this is used by FindObsoleteFiles to determine which
38   // flushed logs we must keep around because they still
39   // contain prepared data which has not been committed or rolled back
40   struct LogCnt {
41     uint64_t log;  // the log number
42     uint64_t cnt;  // number of prepared sections in the log
43   };
44   std::vector<LogCnt> logs_with_prep_;
45   std::mutex logs_with_prep_mutex_;
46 
47   // REQUIRES: prepared_section_completed_mutex_ held
48   //
49   // to be used in conjunction with logs_with_prep_.
50   // once a transaction with data in log L is committed or rolled back
51   // rather than updating logs_with_prep_ directly we keep track of that
52   // in prepared_section_completed_ which maps LOG -> instance_count. This helps
53   // avoiding contention between a commit thread and the prepare threads.
54   //
55   // when trying to determine the minimum log still active we first
56   // consult logs_with_prep_. while that root value maps to
57   // an equal value in prepared_section_completed_ we erase the log from
58   // both logs_with_prep_ and prepared_section_completed_.
59   std::unordered_map<uint64_t, uint64_t> prepared_section_completed_;
60   std::mutex prepared_section_completed_mutex_;
61 
62 };
63 }  // namespace ROCKSDB_NAMESPACE
64