bitcoinleveldb_meta/version_set.rs
1crate::ix!();
2
3//-------------------------------------------[.cpp/bitcoin/src/leveldb/db/version_set.h]
4
5//-------------------------------------------[.cpp/bitcoin/src/leveldb/db/version_set.cc]
6
7pub fn target_file_size(options: *const Options) -> usize {
8
9 todo!();
10 /*
11 return options->max_file_size;
12 */
13}
14
15/**
16 | Maximum bytes of overlaps in grandparent
17 | (i.e., level+2) before we stop building
18 | a single file in a level->level+1 compaction.
19 |
20 */
21pub fn max_grand_parent_overlap_bytes(options: *const Options) -> i64 {
22
23 todo!();
24 /*
25 return 10 * TargetFileSize(options);
26 */
27}
28
29/**
30 | Maximum number of bytes in all compacted files.
31 | We avoid expanding the lower level file set of
32 | a compaction if it would make the total
33 | compaction cover more than this many bytes.
34 */
35pub fn expanded_compaction_byte_size_limit(options: *const Options) -> i64 {
36
37 todo!();
38 /*
39 return 25 * TargetFileSize(options);
40 */
41}
42
43pub fn max_bytes_for_level(
44 options: *const Options,
45 level: i32) -> f64 {
46
47 todo!();
48 /*
49 // Note: the result for level zero is not really used since we set
50 // the level-0 compaction threshold based on number of files.
51
52 // Result for both level-0 and level-1
53 double result = 10. * 1048576.0;
54 while (level > 1) {
55 result *= 10;
56 level--;
57 }
58 return result;
59 */
60}
61
62pub fn max_file_size_for_level(
63 options: *const Options,
64 level: i32) -> u64 {
65
66 todo!();
67 /*
68 // We could vary per level to reduce number of files?
69 return TargetFileSize(options);
70 */
71}
72
73pub fn total_file_size(files: &Vec<*mut FileMetaData>) -> i64 {
74
75 todo!();
76 /*
77 int64_t sum = 0;
78 for (size_t i = 0; i < files.size(); i++) {
79 sum += files[i]->file_size;
80 }
81 return sum;
82 */
83}
84
85/**
86 | Return the smallest index i such that
87 | files[i]->largest >= key.
88 |
89 | Return files.size() if there is no such file.
90 |
91 | REQUIRES: "files" contains a sorted list of
92 | non-overlapping files.
93 */
94pub fn find_file(
95 icmp: &InternalKeyComparator,
96 files: &Vec<*mut FileMetaData>,
97 key_: &Slice) -> i32 {
98
99 todo!();
100 /*
101 uint32_t left = 0;
102 uint32_t right = files.size();
103 while (left < right) {
104 uint32_t mid = (left + right) / 2;
105 const FileMetaData* f = files[mid];
106 if (icmp.InternalKeyComparator::Compare(f->largest.Encode(), key) < 0) {
107 // Key at "mid.largest" is < "target". Therefore all
108 // files at or before "mid" are uninteresting.
109 left = mid + 1;
110 } else {
111 // Key at "mid.largest" is >= "target". Therefore all files
112 // after "mid" are uninteresting.
113 right = mid;
114 }
115 }
116 return right;
117 */
118}
119
120pub fn after_file(
121 ucmp: Box<dyn SliceComparator>,
122 user_key_: *const Slice,
123 f: *const FileMetaData) -> bool {
124
125 todo!();
126 /*
127 // null user_key occurs before all keys and is therefore never after *f
128 return (user_key != nullptr &&
129 ucmp->Compare(*user_key, f->largest.user_key()) > 0);
130 */
131}
132
133pub fn before_file(
134 ucmp: Box<dyn SliceComparator>,
135 user_key_: *const Slice,
136 f: *const FileMetaData) -> bool {
137
138 todo!();
139 /*
140 // null user_key occurs after all keys and is therefore never before *f
141 return (user_key != nullptr &&
142 ucmp->Compare(*user_key, f->smallest.user_key()) < 0);
143 */
144}
145
146/**
147 | Returns true iff some file in "files" overlaps
148 | the user key range [*smallest,*largest].
149 |
150 | smallest==nullptr represents a key smaller than
151 | all keys in the DB.
152 |
153 | largest==nullptr represents a key largest than
154 | all keys in the DB.
155 |
156 | REQUIRES: If disjoint_sorted_files, files[]
157 | contains disjoint ranges in sorted
158 | order.
159 */
160pub fn some_file_overlaps_range(
161 icmp: &InternalKeyComparator,
162 disjoint_sorted_files: bool,
163 files: &Vec<*mut FileMetaData>,
164 smallest_user_key_: *const Slice,
165 largest_user_key_: *const Slice) -> bool {
166
167 todo!();
168 /*
169 const Comparator* ucmp = icmp.user_comparator();
170 if (!disjoint_sorted_files) {
171 // Need to check against all files
172 for (size_t i = 0; i < files.size(); i++) {
173 const FileMetaData* f = files[i];
174 if (AfterFile(ucmp, smallest_user_key, f) ||
175 BeforeFile(ucmp, largest_user_key, f)) {
176 // No overlap
177 } else {
178 return true; // Overlap
179 }
180 }
181 return false;
182 }
183
184 // Binary search over file list
185 uint32_t index = 0;
186 if (smallest_user_key != nullptr) {
187 // Find the earliest possible internal key for smallest_user_key
188 InternalKey small_key(*smallest_user_key, kMaxSequenceNumber,
189 kValueTypeForSeek);
190 index = FindFile(icmp, files, small_key.Encode());
191 }
192
193 if (index >= files.size()) {
194 // beginning of range is after all files, so no overlap.
195 return false;
196 }
197
198 return !BeforeFile(ucmp, largest_user_key, files[index]);
199 */
200}
201
202pub fn get_file_iterator(
203 arg: *mut c_void,
204 options: &ReadOptions,
205 file_value: &Slice) -> *mut LevelDBIterator {
206
207 todo!();
208 /*
209 TableCache* cache = reinterpret_cast<TableCache*>(arg);
210 if (file_value.size() != 16) {
211 return NewErrorIterator(
212 Status::Corruption("FileReader invoked with unexpected value"));
213 } else {
214 return cache->NewIterator(options, DecodeFixed64(file_value.data()),
215 DecodeFixed64(file_value.data() + 8));
216 }
217 */
218}
219
220/**
221 | Callback from TableCache::Get()
222 |
223 */
224pub enum SaverState {
225 NotFound,
226 Found,
227 Deleted,
228 Corrupt,
229}
230
231pub struct Saver {
232 state: SaverState,
233 ucmp: Box<dyn SliceComparator>,
234 user_key_: Slice,
235 value: *mut String,
236}
237
238pub fn save_value(
239 arg: *mut c_void,
240 ikey_: &Slice,
241 v: &Slice) {
242
243 todo!();
244 /*
245 Saver* s = reinterpret_cast<Saver*>(arg);
246 ParsedInternalKey parsed_key;
247 if (!ParseInternalKey(ikey, &parsed_key)) {
248 s->state = kCorrupt;
249 } else {
250 if (s->ucmp->Compare(parsed_key.user_key, s->user_key) == 0) {
251 s->state = (parsed_key.type == kTypeValue) ? kFound : kDeleted;
252 if (s->state == kFound) {
253 s->value->assign(v.data(), v.size());
254 }
255 }
256 }
257 */
258}
259
260pub fn newest_first(
261 a: *mut FileMetaData,
262 b: *mut FileMetaData) -> bool {
263
264 todo!();
265 /*
266 return a->number > b->number;
267 */
268}
269
270/**
271 | Finds the largest key in a vector of files.
272 | Returns true if files it not empty.
273 |
274 */
275pub fn find_largest_key(
276 icmp: &InternalKeyComparator,
277 files: &Vec<*mut FileMetaData>,
278 largest_key_: *mut InternalKey) -> bool {
279
280 todo!();
281 /*
282 if (files.empty()) {
283 return false;
284 }
285 *largest_key = files[0]->largest;
286 for (size_t i = 1; i < files.size(); ++i) {
287 FileMetaData* f = files[i];
288 if (icmp.Compare(f->largest, *largest_key) > 0) {
289 *largest_key = f->largest;
290 }
291 }
292 return true;
293 */
294}
295
296/**
297 | Finds minimum file b2=(l2, u2) in level
298 | file for which l2 > u1 and user_key(l2)
299 | = user_key(u1)
300 |
301 */
302pub fn find_smallest_boundary_file(
303 icmp: &InternalKeyComparator,
304 level_files: &Vec<*mut FileMetaData>,
305 largest_key_: &InternalKey) -> *mut FileMetaData {
306
307 todo!();
308 /*
309 const Comparator* user_cmp = icmp.user_comparator();
310 FileMetaData* smallest_boundary_file = nullptr;
311 for (size_t i = 0; i < level_files.size(); ++i) {
312 FileMetaData* f = level_files[i];
313 if (icmp.Compare(f->smallest, largest_key) > 0 &&
314 user_cmp->Compare(f->smallest.user_key(), largest_key.user_key()) ==
315 0) {
316 if (smallest_boundary_file == nullptr ||
317 icmp.Compare(f->smallest, smallest_boundary_file->smallest) < 0) {
318 smallest_boundary_file = f;
319 }
320 }
321 }
322 return smallest_boundary_file;
323 */
324}
325
326/**
327 | Extracts the largest file b1 from
328 | |compaction_files| and then searches for a b2
329 | in |level_files| for which user_key(u1)
330 | = user_key(l2). If it finds such a file b2
331 | (known as a boundary file) it adds it to
332 | |compaction_files| and then searches again
333 | using this new upper bound.
334 |
335 | If there are two blocks, b1=(l1, u1) and
336 | b2=(l2, u2) and user_key(u1) = user_key(l2),
337 | and if we compact b1 but not b2 then
338 | a subsequent get operation will yield an
339 | incorrect result because it will return the
340 | record from b2 in level i rather than from b1
341 | because it searches level by level for records
342 | matching the supplied user key.
343 |
344 | parameters:
345 |
346 | in level_files: List of files to
347 | search for boundary files.
348 |
349 | in/out compaction_files: List of files to
350 | extend by adding boundary files.
351 */
352pub fn add_boundary_inputs(
353 icmp: &InternalKeyComparator,
354 level_files: &Vec<*mut FileMetaData>,
355 compaction_files: *mut Vec<*mut FileMetaData>) {
356
357 todo!();
358 /*
359 InternalKey largest_key;
360
361 // Quick return if compaction_files is empty.
362 if (!FindLargestKey(icmp, *compaction_files, &largest_key)) {
363 return;
364 }
365
366 bool continue_searching = true;
367 while (continue_searching) {
368 FileMetaData* smallest_boundary_file =
369 FindSmallestBoundaryFile(icmp, level_files, largest_key);
370
371 // If a boundary file was found advance largest_key, otherwise we're done.
372 if (smallest_boundary_file != NULL) {
373 compaction_files->push_back(smallest_boundary_file);
374 largest_key = smallest_boundary_file->largest;
375 } else {
376 continue_searching = false;
377 }
378 }
379 */
380}