Coverage Report

Created: 2024-07-27 06:53

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