LCOV - code coverage report
Current view: top level - src/leveldb/table - block_builder.cc (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 100.0 % 46 46
Test Date: 2026-02-04 04:43:42 Functions: 100.0 % 5 5
Branches: 63.6 % 44 28

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
       2                 :             : // Use of this source code is governed by a BSD-style license that can be
       3                 :             : // found in the LICENSE file. See the AUTHORS file for names of contributors.
       4                 :             : //
       5                 :             : // BlockBuilder generates blocks where keys are prefix-compressed:
       6                 :             : //
       7                 :             : // When we store a key, we drop the prefix shared with the previous
       8                 :             : // string.  This helps reduce the space requirement significantly.
       9                 :             : // Furthermore, once every K keys, we do not apply the prefix
      10                 :             : // compression and store the entire key.  We call this a "restart
      11                 :             : // point".  The tail end of the block stores the offsets of all of the
      12                 :             : // restart points, and can be used to do a binary search when looking
      13                 :             : // for a particular key.  Values are stored as-is (without compression)
      14                 :             : // immediately following the corresponding key.
      15                 :             : //
      16                 :             : // An entry for a particular key-value pair has the form:
      17                 :             : //     shared_bytes: varint32
      18                 :             : //     unshared_bytes: varint32
      19                 :             : //     value_length: varint32
      20                 :             : //     key_delta: char[unshared_bytes]
      21                 :             : //     value: char[value_length]
      22                 :             : // shared_bytes == 0 for restart points.
      23                 :             : //
      24                 :             : // The trailer of the block has the form:
      25                 :             : //     restarts: uint32[num_restarts]
      26                 :             : //     num_restarts: uint32
      27                 :             : // restarts[i] contains the offset within the block of the ith restart point.
      28                 :             : 
      29                 :             : #include "table/block_builder.h"
      30                 :             : 
      31                 :             : #include <assert.h>
      32                 :             : 
      33                 :             : #include <algorithm>
      34                 :             : 
      35                 :             : #include "leveldb/comparator.h"
      36                 :             : #include "leveldb/options.h"
      37                 :             : #include "util/coding.h"
      38                 :             : 
      39                 :             : namespace leveldb {
      40                 :             : 
      41                 :         221 : BlockBuilder::BlockBuilder(const Options* options)
      42         [ -  + ]:         221 :     : options_(options), restarts_(), counter_(0), finished_(false) {
      43         [ -  + ]:         221 :   assert(options->block_restart_interval >= 1);
      44         [ +  - ]:         221 :   restarts_.push_back(0);  // First restart point is at offset 0
      45                 :         221 : }
      46                 :             : 
      47                 :         564 : void BlockBuilder::Reset() {
      48         [ +  - ]:         564 :   buffer_.clear();
      49         [ +  - ]:         564 :   restarts_.clear();
      50                 :         564 :   restarts_.push_back(0);  // First restart point is at offset 0
      51                 :         564 :   counter_ = 0;
      52                 :         564 :   finished_ = false;
      53                 :         564 :   last_key_.clear();
      54                 :         564 : }
      55                 :             : 
      56                 :       28387 : size_t BlockBuilder::CurrentSizeEstimate() const {
      57         [ -  + ]:       28387 :   return (buffer_.size() +                       // Raw data buffer
      58         [ -  + ]:       28387 :           restarts_.size() * sizeof(uint32_t) +  // Restart array
      59                 :       28387 :           sizeof(uint32_t));                     // Restart array length
      60                 :             : }
      61                 :             : 
      62                 :         564 : Slice BlockBuilder::Finish() {
      63                 :             :   // Append restart array
      64   [ -  +  +  + ]:        3031 :   for (size_t i = 0; i < restarts_.size(); i++) {
      65                 :        2467 :     PutFixed32(&buffer_, restarts_[i]);
      66                 :             :   }
      67                 :         564 :   PutFixed32(&buffer_, restarts_.size());
      68                 :         564 :   finished_ = true;
      69         [ -  + ]:         564 :   return Slice(buffer_);
      70                 :             : }
      71                 :             : 
      72                 :       28878 : void BlockBuilder::Add(const Slice& key, const Slice& value) {
      73         [ -  + ]:       28878 :   Slice last_key_piece(last_key_);
      74         [ -  + ]:       28878 :   assert(!finished_);
      75         [ -  + ]:       28878 :   assert(counter_ <= options_->block_restart_interval);
      76   [ +  +  -  + ]:       28878 :   assert(buffer_.empty()  // No values yet?
      77                 :             :          || options_->comparator->Compare(key, last_key_piece) > 0);
      78                 :       28878 :   size_t shared = 0;
      79         [ +  + ]:       28878 :   if (counter_ < options_->block_restart_interval) {
      80                 :             :     // See how much sharing to do with previous string
      81         [ +  + ]:       26974 :     const size_t min_length = std::min(last_key_piece.size(), key.size());
      82   [ +  +  +  + ]:      645204 :     while ((shared < min_length) && (last_key_piece[shared] == key[shared])) {
      83                 :      618230 :       shared++;
      84                 :             :     }
      85                 :             :   } else {
      86                 :             :     // Restart compression
      87         [ -  + ]:        1904 :     restarts_.push_back(buffer_.size());
      88                 :        1904 :     counter_ = 0;
      89                 :             :   }
      90                 :       28878 :   const size_t non_shared = key.size() - shared;
      91                 :             : 
      92                 :             :   // Add "<shared><non_shared><value_size>" to buffer_
      93                 :       28878 :   PutVarint32(&buffer_, shared);
      94                 :       28878 :   PutVarint32(&buffer_, non_shared);
      95                 :       28878 :   PutVarint32(&buffer_, value.size());
      96                 :             : 
      97                 :             :   // Add string delta to buffer_ followed by value
      98                 :       28878 :   buffer_.append(key.data() + shared, non_shared);
      99                 :       28878 :   buffer_.append(value.data(), value.size());
     100                 :             : 
     101                 :             :   // Update state
     102                 :       28878 :   last_key_.resize(shared);
     103                 :       28878 :   last_key_.append(key.data() + shared, non_shared);
     104   [ -  +  -  + ]:       28878 :   assert(Slice(last_key_) == key);
     105                 :       28878 :   counter_++;
     106                 :       28878 : }
     107                 :             : 
     108                 :             : }  // namespace leveldb
        

Generated by: LCOV version 2.0-1