]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae FG |
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 | ||
10 | #include "db/db_impl.h" | |
11 | ||
12 | #ifndef __STDC_FORMAT_MACROS | |
13 | #define __STDC_FORMAT_MACROS | |
14 | #endif | |
15 | ||
16 | #include <inttypes.h> | |
17 | #include <vector> | |
18 | ||
19 | #include "db/column_family.h" | |
20 | #include "db/job_context.h" | |
21 | #include "db/version_set.h" | |
22 | #include "rocksdb/status.h" | |
23 | ||
24 | namespace rocksdb { | |
25 | ||
26 | #ifndef ROCKSDB_LITE | |
27 | Status DBImpl::SuggestCompactRange(ColumnFamilyHandle* column_family, | |
28 | const Slice* begin, const Slice* end) { | |
29 | auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); | |
30 | auto cfd = cfh->cfd(); | |
31 | InternalKey start_key, end_key; | |
32 | if (begin != nullptr) { | |
11fdf7f2 | 33 | start_key.SetMinPossibleForUserKey(*begin); |
7c673cae FG |
34 | } |
35 | if (end != nullptr) { | |
11fdf7f2 | 36 | end_key.SetMaxPossibleForUserKey(*end); |
7c673cae FG |
37 | } |
38 | { | |
39 | InstrumentedMutexLock l(&mutex_); | |
40 | auto vstorage = cfd->current()->storage_info(); | |
41 | for (int level = 0; level < vstorage->num_non_empty_levels() - 1; ++level) { | |
42 | std::vector<FileMetaData*> inputs; | |
43 | vstorage->GetOverlappingInputs( | |
44 | level, begin == nullptr ? nullptr : &start_key, | |
45 | end == nullptr ? nullptr : &end_key, &inputs); | |
46 | for (auto f : inputs) { | |
47 | f->marked_for_compaction = true; | |
48 | } | |
49 | } | |
50 | // Since we have some more files to compact, we should also recompute | |
51 | // compaction score | |
52 | vstorage->ComputeCompactionScore(*cfd->ioptions(), | |
53 | *cfd->GetLatestMutableCFOptions()); | |
54 | SchedulePendingCompaction(cfd); | |
55 | MaybeScheduleFlushOrCompaction(); | |
56 | } | |
57 | return Status::OK(); | |
58 | } | |
59 | ||
60 | Status DBImpl::PromoteL0(ColumnFamilyHandle* column_family, int target_level) { | |
61 | assert(column_family); | |
62 | ||
63 | if (target_level < 1) { | |
64 | ROCKS_LOG_INFO(immutable_db_options_.info_log, | |
65 | "PromoteL0 FAILED. Invalid target level %d\n", target_level); | |
66 | return Status::InvalidArgument("Invalid target level"); | |
67 | } | |
68 | ||
69 | Status status; | |
70 | VersionEdit edit; | |
71 | JobContext job_context(next_job_id_.fetch_add(1), true); | |
72 | { | |
73 | InstrumentedMutexLock l(&mutex_); | |
74 | auto* cfd = static_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); | |
75 | const auto* vstorage = cfd->current()->storage_info(); | |
76 | ||
77 | if (target_level >= vstorage->num_levels()) { | |
78 | ROCKS_LOG_INFO(immutable_db_options_.info_log, | |
79 | "PromoteL0 FAILED. Target level %d does not exist\n", | |
80 | target_level); | |
81 | job_context.Clean(); | |
82 | return Status::InvalidArgument("Target level does not exist"); | |
83 | } | |
84 | ||
85 | // Sort L0 files by range. | |
86 | const InternalKeyComparator* icmp = &cfd->internal_comparator(); | |
87 | auto l0_files = vstorage->LevelFiles(0); | |
88 | std::sort(l0_files.begin(), l0_files.end(), | |
89 | [icmp](FileMetaData* f1, FileMetaData* f2) { | |
90 | return icmp->Compare(f1->largest, f2->largest) < 0; | |
91 | }); | |
92 | ||
93 | // Check that no L0 file is being compacted and that they have | |
94 | // non-overlapping ranges. | |
95 | for (size_t i = 0; i < l0_files.size(); ++i) { | |
96 | auto f = l0_files[i]; | |
97 | if (f->being_compacted) { | |
98 | ROCKS_LOG_INFO(immutable_db_options_.info_log, | |
99 | "PromoteL0 FAILED. File %" PRIu64 " being compacted\n", | |
100 | f->fd.GetNumber()); | |
101 | job_context.Clean(); | |
102 | return Status::InvalidArgument("PromoteL0 called during L0 compaction"); | |
103 | } | |
104 | ||
105 | if (i == 0) continue; | |
106 | auto prev_f = l0_files[i - 1]; | |
107 | if (icmp->Compare(prev_f->largest, f->smallest) >= 0) { | |
108 | ROCKS_LOG_INFO(immutable_db_options_.info_log, | |
109 | "PromoteL0 FAILED. Files %" PRIu64 " and %" PRIu64 | |
110 | " have overlapping ranges\n", | |
111 | prev_f->fd.GetNumber(), f->fd.GetNumber()); | |
112 | job_context.Clean(); | |
113 | return Status::InvalidArgument("L0 has overlapping files"); | |
114 | } | |
115 | } | |
116 | ||
117 | // Check that all levels up to target_level are empty. | |
118 | for (int level = 1; level <= target_level; ++level) { | |
119 | if (vstorage->NumLevelFiles(level) > 0) { | |
120 | ROCKS_LOG_INFO(immutable_db_options_.info_log, | |
121 | "PromoteL0 FAILED. Level %d not empty\n", level); | |
122 | job_context.Clean(); | |
123 | return Status::InvalidArgument( | |
124 | "All levels up to target_level " | |
125 | "must be empty"); | |
126 | } | |
127 | } | |
128 | ||
129 | edit.SetColumnFamily(cfd->GetID()); | |
130 | for (const auto& f : l0_files) { | |
131 | edit.DeleteFile(0, f->fd.GetNumber()); | |
132 | edit.AddFile(target_level, f->fd.GetNumber(), f->fd.GetPathId(), | |
133 | f->fd.GetFileSize(), f->smallest, f->largest, | |
11fdf7f2 | 134 | f->fd.smallest_seqno, f->fd.largest_seqno, |
7c673cae FG |
135 | f->marked_for_compaction); |
136 | } | |
137 | ||
138 | status = versions_->LogAndApply(cfd, *cfd->GetLatestMutableCFOptions(), | |
139 | &edit, &mutex_, directories_.GetDbDir()); | |
140 | if (status.ok()) { | |
11fdf7f2 TL |
141 | InstallSuperVersionAndScheduleWork(cfd, |
142 | &job_context.superversion_contexts[0], | |
143 | *cfd->GetLatestMutableCFOptions()); | |
7c673cae FG |
144 | } |
145 | } // lock released here | |
146 | LogFlush(immutable_db_options_.info_log); | |
147 | job_context.Clean(); | |
148 | ||
149 | return status; | |
150 | } | |
151 | #endif // ROCKSDB_LITE | |
152 | ||
153 | } // namespace rocksdb |