Coverage Report

Created: 2026-04-10 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rocksdb/db/compaction/subcompaction_state.cc
Line
Count
Source
1
//  Copyright (c) Meta Platforms, Inc. and affiliates.
2
//
3
//  This source code is licensed under both the GPLv2 (found in the
4
//  COPYING file in the root directory) and Apache 2.0 License
5
//  (found in the LICENSE.Apache file in the root directory).
6
//
7
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
8
// Use of this source code is governed by a BSD-style license that can be
9
// found in the LICENSE file. See the AUTHORS file for names of contributors.
10
11
#include "db/compaction/subcompaction_state.h"
12
13
#include "rocksdb/sst_partitioner.h"
14
15
namespace ROCKSDB_NAMESPACE {
16
void SubcompactionState::AggregateCompactionOutputStats(
17
3.42k
    InternalStats::CompactionStatsFull& internal_stats) const {
18
  // Outputs should be closed. By extension, any files created just for
19
  // range deletes have already been written also.
20
3.42k
  assert(compaction_outputs_.HasBuilder() == false);
21
3.42k
  assert(proximal_level_outputs_.HasBuilder() == false);
22
23
  // FIXME: These stats currently include abandonned output files
24
  // assert(compaction_outputs_.stats_.num_output_files ==
25
  //        compaction_outputs_.outputs_.size());
26
  // assert(proximal_level_outputs_.stats_.num_output_files ==
27
  //        proximal_level_outputs_.outputs_.size());
28
29
3.42k
  internal_stats.output_level_stats.Add(compaction_outputs_.stats_);
30
3.42k
  if (proximal_level_outputs_.HasOutput()) {
31
0
    internal_stats.has_proximal_level_output = true;
32
0
    internal_stats.proximal_level_stats.Add(proximal_level_outputs_.stats_);
33
0
  }
34
3.42k
}
35
36
7.63k
OutputIterator SubcompactionState::GetOutputs() const {
37
7.63k
  return OutputIterator(proximal_level_outputs_.outputs_,
38
7.63k
                        compaction_outputs_.outputs_);
39
7.63k
}
40
41
3.42k
void SubcompactionState::Cleanup(Cache* cache, const Status& overall_status) {
42
3.42k
  proximal_level_outputs_.Cleanup();
43
3.42k
  compaction_outputs_.Cleanup();
44
45
3.42k
  if (!status.ok() || !overall_status.ok()) {
46
1.32k
    for (const auto& out : GetOutputs()) {
47
      // If this file was inserted into the table cache then remove it here
48
      // because this compaction was not committed. This is not strictly
49
      // required because of a backstop TableCache::Evict() in
50
      // PurgeObsoleteFiles() but is our opportunity to apply
51
      // uncache_aggressiveness. TODO: instead, put these files into the
52
      // VersionSet::obsolete_files_ pipeline so that they don't have to
53
      // be picked up by scanning the DB directory.
54
0
      TableCache::ReleaseObsolete(
55
0
          cache, out.meta.fd.GetNumber(), nullptr /*handle*/,
56
0
          compaction->mutable_cf_options().uncache_aggressiveness);
57
0
    }
58
1.32k
  }
59
  // TODO: sub_compact.io_status is not checked like status. Not sure if thats
60
  // intentional. So ignoring the io_status as of now.
61
3.42k
  io_status.PermitUncheckedError();
62
3.42k
}
63
64
1.27k
Slice SubcompactionState::SmallestUserKey() const {
65
1.27k
  if (proximal_level_outputs_.HasOutput()) {
66
0
    Slice a = compaction_outputs_.SmallestUserKey();
67
0
    Slice b = proximal_level_outputs_.SmallestUserKey();
68
0
    if (a.empty()) {
69
0
      return b;
70
0
    }
71
0
    if (b.empty()) {
72
0
      return a;
73
0
    }
74
0
    const Comparator* user_cmp =
75
0
        compaction->column_family_data()->user_comparator();
76
0
    if (user_cmp->Compare(a, b) > 0) {
77
0
      return b;
78
0
    } else {
79
0
      return a;
80
0
    }
81
1.27k
  } else {
82
1.27k
    return compaction_outputs_.SmallestUserKey();
83
1.27k
  }
84
1.27k
}
85
86
1.27k
Slice SubcompactionState::LargestUserKey() const {
87
1.27k
  if (proximal_level_outputs_.HasOutput()) {
88
0
    Slice a = compaction_outputs_.LargestUserKey();
89
0
    Slice b = proximal_level_outputs_.LargestUserKey();
90
0
    if (a.empty()) {
91
0
      return b;
92
0
    }
93
0
    if (b.empty()) {
94
0
      return a;
95
0
    }
96
0
    const Comparator* user_cmp =
97
0
        compaction->column_family_data()->user_comparator();
98
0
    if (user_cmp->Compare(a, b) < 0) {
99
0
      return b;
100
0
    } else {
101
0
      return a;
102
0
    }
103
1.27k
  } else {
104
1.27k
    return compaction_outputs_.LargestUserKey();
105
1.27k
  }
106
1.27k
}
107
108
Status SubcompactionState::AddToOutput(
109
    const CompactionIterator& iter, bool use_proximal_output,
110
    const CompactionFileOpenFunc& open_file_func,
111
    const CompactionFileCloseFunc& close_file_func,
112
2.17k
    const ParsedInternalKey& prev_iter_output_internal_key) {
113
  // update target output
114
2.17k
  current_outputs_ =
115
2.17k
      use_proximal_output ? &proximal_level_outputs_ : &compaction_outputs_;
116
2.17k
  return current_outputs_->AddToOutput(iter, open_file_func, close_file_func,
117
2.17k
                                       prev_iter_output_internal_key);
118
2.17k
}
119
120
}  // namespace ROCKSDB_NAMESPACE