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