job_context.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #pragma once
  10. #include <string>
  11. #include <vector>
  12. #include "db/log_writer.h"
  13. #include "db/column_family.h"
  14. namespace ROCKSDB_NAMESPACE {
  15. class MemTable;
  16. struct SuperVersion;
  17. struct SuperVersionContext {
  18. struct WriteStallNotification {
  19. WriteStallInfo write_stall_info;
  20. const ImmutableCFOptions* immutable_cf_options;
  21. };
  22. autovector<SuperVersion*> superversions_to_free;
  23. #ifndef ROCKSDB_DISABLE_STALL_NOTIFICATION
  24. autovector<WriteStallNotification> write_stall_notifications;
  25. #endif
  26. std::unique_ptr<SuperVersion>
  27. new_superversion; // if nullptr no new superversion
  28. explicit SuperVersionContext(bool create_superversion = false)
  29. : new_superversion(create_superversion ? new SuperVersion() : nullptr) {}
  30. explicit SuperVersionContext(SuperVersionContext&& other)
  31. : superversions_to_free(std::move(other.superversions_to_free)),
  32. #ifndef ROCKSDB_DISABLE_STALL_NOTIFICATION
  33. write_stall_notifications(std::move(other.write_stall_notifications)),
  34. #endif
  35. new_superversion(std::move(other.new_superversion)) {
  36. }
  37. void NewSuperVersion() {
  38. new_superversion = std::unique_ptr<SuperVersion>(new SuperVersion());
  39. }
  40. inline bool HaveSomethingToDelete() const {
  41. #ifndef ROCKSDB_DISABLE_STALL_NOTIFICATION
  42. return !superversions_to_free.empty() ||
  43. !write_stall_notifications.empty();
  44. #else
  45. return !superversions_to_free.empty();
  46. #endif
  47. }
  48. void PushWriteStallNotification(
  49. WriteStallCondition old_cond, WriteStallCondition new_cond,
  50. const std::string& name, const ImmutableCFOptions* ioptions) {
  51. #if !defined(ROCKSDB_LITE) && !defined(ROCKSDB_DISABLE_STALL_NOTIFICATION)
  52. WriteStallNotification notif;
  53. notif.write_stall_info.cf_name = name;
  54. notif.write_stall_info.condition.prev = old_cond;
  55. notif.write_stall_info.condition.cur = new_cond;
  56. notif.immutable_cf_options = ioptions;
  57. write_stall_notifications.push_back(notif);
  58. #else
  59. (void)old_cond;
  60. (void)new_cond;
  61. (void)name;
  62. (void)ioptions;
  63. #endif // !defined(ROCKSDB_LITE) && !defined(ROCKSDB_DISABLE_STALL_NOTIFICATION)
  64. }
  65. void Clean() {
  66. #if !defined(ROCKSDB_LITE) && !defined(ROCKSDB_DISABLE_STALL_NOTIFICATION)
  67. // notify listeners on changed write stall conditions
  68. for (auto& notif : write_stall_notifications) {
  69. for (auto& listener : notif.immutable_cf_options->listeners) {
  70. listener->OnStallConditionsChanged(notif.write_stall_info);
  71. }
  72. }
  73. write_stall_notifications.clear();
  74. #endif // !ROCKSDB_LITE
  75. // free superversions
  76. for (auto s : superversions_to_free) {
  77. delete s;
  78. }
  79. superversions_to_free.clear();
  80. }
  81. ~SuperVersionContext() {
  82. #ifndef ROCKSDB_DISABLE_STALL_NOTIFICATION
  83. assert(write_stall_notifications.empty());
  84. #endif
  85. assert(superversions_to_free.empty());
  86. }
  87. };
  88. struct JobContext {
  89. inline bool HaveSomethingToDelete() const {
  90. return full_scan_candidate_files.size() || sst_delete_files.size() ||
  91. log_delete_files.size() || manifest_delete_files.size();
  92. }
  93. inline bool HaveSomethingToClean() const {
  94. bool sv_have_sth = false;
  95. for (const auto& sv_ctx : superversion_contexts) {
  96. if (sv_ctx.HaveSomethingToDelete()) {
  97. sv_have_sth = true;
  98. break;
  99. }
  100. }
  101. return memtables_to_free.size() > 0 || logs_to_free.size() > 0 ||
  102. sv_have_sth;
  103. }
  104. // Structure to store information for candidate files to delete.
  105. struct CandidateFileInfo {
  106. std::string file_name;
  107. std::string file_path;
  108. CandidateFileInfo(std::string name, std::string path)
  109. : file_name(std::move(name)), file_path(std::move(path)) {}
  110. bool operator==(const CandidateFileInfo& other) const {
  111. return file_name == other.file_name &&
  112. file_path == other.file_path;
  113. }
  114. };
  115. // Unique job id
  116. int job_id;
  117. // a list of all files that we'll consider deleting
  118. // (every once in a while this is filled up with all files
  119. // in the DB directory)
  120. // (filled only if we're doing full scan)
  121. std::vector<CandidateFileInfo> full_scan_candidate_files;
  122. // the list of all live sst files that cannot be deleted
  123. std::vector<FileDescriptor> sst_live;
  124. // a list of sst files that we need to delete
  125. std::vector<ObsoleteFileInfo> sst_delete_files;
  126. // a list of log files that we need to delete
  127. std::vector<uint64_t> log_delete_files;
  128. // a list of log files that we need to preserve during full purge since they
  129. // will be reused later
  130. std::vector<uint64_t> log_recycle_files;
  131. // a list of manifest files that we need to delete
  132. std::vector<std::string> manifest_delete_files;
  133. // a list of memtables to be free
  134. autovector<MemTable*> memtables_to_free;
  135. // contexts for installing superversions for multiple column families
  136. std::vector<SuperVersionContext> superversion_contexts;
  137. autovector<log::Writer*> logs_to_free;
  138. // the current manifest_file_number, log_number and prev_log_number
  139. // that corresponds to the set of files in 'live'.
  140. uint64_t manifest_file_number;
  141. uint64_t pending_manifest_file_number;
  142. uint64_t log_number;
  143. uint64_t prev_log_number;
  144. uint64_t min_pending_output = 0;
  145. uint64_t prev_total_log_size = 0;
  146. size_t num_alive_log_files = 0;
  147. uint64_t size_log_to_delete = 0;
  148. // Snapshot taken before flush/compaction job.
  149. std::unique_ptr<ManagedSnapshot> job_snapshot;
  150. explicit JobContext(int _job_id, bool create_superversion = false) {
  151. job_id = _job_id;
  152. manifest_file_number = 0;
  153. pending_manifest_file_number = 0;
  154. log_number = 0;
  155. prev_log_number = 0;
  156. superversion_contexts.emplace_back(
  157. SuperVersionContext(create_superversion));
  158. }
  159. // For non-empty JobContext Clean() has to be called at least once before
  160. // before destruction (see asserts in ~JobContext()). Should be called with
  161. // unlocked DB mutex. Destructor doesn't call Clean() to avoid accidentally
  162. // doing potentially slow Clean() with locked DB mutex.
  163. void Clean() {
  164. // free superversions
  165. for (auto& sv_context : superversion_contexts) {
  166. sv_context.Clean();
  167. }
  168. // free pending memtables
  169. for (auto m : memtables_to_free) {
  170. delete m;
  171. }
  172. for (auto l : logs_to_free) {
  173. delete l;
  174. }
  175. memtables_to_free.clear();
  176. logs_to_free.clear();
  177. job_snapshot.reset();
  178. }
  179. ~JobContext() {
  180. assert(memtables_to_free.size() == 0);
  181. assert(logs_to_free.size() == 0);
  182. }
  183. };
  184. } // namespace ROCKSDB_NAMESPACE