file_pri.h 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. #include <algorithm>
  8. #include "db/version_edit.h"
  9. namespace ROCKSDB_NAMESPACE {
  10. // We boost files that are closer to TTL limit. This boosting could be
  11. // through FileMetaData.compensated_file_size but this compensated size
  12. // is widely used as something similar to file size so dramatically boost
  13. // the value might cause unintended consequences.
  14. //
  15. // This boosting algorithm can go very fancy, but here we use a simple
  16. // formula which can satisify:
  17. // (1) Different levels are triggered slightly differently to avoid
  18. // too many cascading cases
  19. // (2) Files in the same level get boosting more when TTL gets closer.
  20. //
  21. // Don't do any boosting before TTL has past by half. This is to make
  22. // sure lower write amp for most of the case. And all levels should be
  23. // fully boosted when total TTL compaction threshold triggers.
  24. // Differientiate boosting ranges of each level by 1/2. This will make
  25. // range for each level exponentially increasing. We could do it by
  26. // having them to be equal, or go even fancier. We can adjust it after
  27. // we observe the behavior in production.
  28. // The threshold starting boosting:
  29. // +------------------------------------------------------------------ +
  30. // ^ ^ ^ ^ ^ ^
  31. // Age 0 ... | | second last level thresold
  32. // | |
  33. // | third last level
  34. // |
  35. // forth last level
  36. //
  37. // We arbitrarily set with 0 when a file is aged boost_age_start and
  38. // grow linearly. The ratio is arbitrarily set so that when the next level
  39. // starts to boost, the previous level's boosting amount is 16.
  40. class FileTtlBooster {
  41. public:
  42. FileTtlBooster(uint64_t current_time, uint64_t ttl, int num_non_empty_levels,
  43. int level)
  44. : current_time_(current_time) {
  45. if (ttl == 0 || level == 0 || level >= num_non_empty_levels - 1) {
  46. enabled_ = false;
  47. boost_age_start_ = 0;
  48. boost_step_ = 1;
  49. } else {
  50. enabled_ = true;
  51. uint64_t all_boost_start_age = ttl / 2;
  52. uint64_t all_boost_age_range = (ttl / 32) * 31 - all_boost_start_age;
  53. // TODO(cbi): more reasonable algorithm that gives different values
  54. // when num_non_empty_levels - level - 1 > 63.
  55. uint64_t boost_age_range =
  56. all_boost_age_range >> std::min(63, num_non_empty_levels - level - 1);
  57. boost_age_start_ = all_boost_start_age + boost_age_range;
  58. const uint64_t kBoostRatio = 16;
  59. // prevent 0 value to avoid divide 0 error.
  60. boost_step_ = std::max(boost_age_range / kBoostRatio, uint64_t{1});
  61. }
  62. }
  63. uint64_t GetBoostScore(FileMetaData* f) {
  64. if (!enabled_) {
  65. return 1;
  66. }
  67. uint64_t oldest_ancester_time = f->TryGetOldestAncesterTime();
  68. if (oldest_ancester_time >= current_time_) {
  69. return 1;
  70. }
  71. uint64_t age = current_time_ - oldest_ancester_time;
  72. if (age > boost_age_start_) {
  73. // Use integer just for convenience.
  74. // We could make all file_to_order double if we want.
  75. // Technically this can overflow if users override timing and
  76. // give a very high current time. Ignore the case for simplicity.
  77. // Boosting is addition to current value, so +1. This will effectively
  78. // make boosting to kick in after the first boost_step_ is reached.
  79. return (age - boost_age_start_) / boost_step_ + 1;
  80. }
  81. return 1;
  82. }
  83. private:
  84. bool enabled_;
  85. uint64_t current_time_;
  86. uint64_t boost_age_start_;
  87. uint64_t boost_step_;
  88. };
  89. } // namespace ROCKSDB_NAMESPACE