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}