1+ #include < cassert>
2+ #include < cstddef>
3+ #include < cstdint>
4+
5+ #include " options.h"
6+ #include " slice.h"
7+ #include " table/block_builder.h"
8+ #include " util/coding.h"
9+ namespace db {
10+
11+ BlockBuilder::BlockBuilder (const Options* options)
12+ : options_(options), restarts_(), counter_(0 ), finished_(false ) {
13+ assert (options->block_restart_interval >= 1 );
14+ restarts_.push_back (0 );
15+ }
16+
17+ void BlockBuilder::Reset () {
18+ buffer_.clear ();
19+ restarts_.clear ();
20+ restarts_.push_back (0 );
21+ counter_ = 0 ;
22+ finished_ = false ;
23+ last_key_.clear ();
24+ }
25+
26+ // Return the size of the current block if we finish it immediately without compression.
27+ size_t BlockBuilder::CurrentSizeEstimate () const {
28+ return (buffer_.size () + restarts_.size () * sizeof (uint32_t ) + sizeof (uint32_t ));
29+ }
30+
31+ Slice BlockBuilder::Finish () {
32+ for (size_t i = 0 ; i < restarts_.size (); i++) {
33+ PutFixed32 (&buffer_, restarts_[i]);
34+ }
35+ PutFixed32 (&buffer_, restarts_.size ());
36+ finished_ = true ;
37+ return Slice (buffer_);
38+ }
39+
40+ void BlockBuilder::Add (const Slice& key, const Slice& val) {
41+ Slice last_key_piece (last_key_);
42+ assert (!finished_);
43+ assert (counter_ <= options_->block_restart_interval );
44+ // ensure Sorted semantic for string table
45+ assert (buffer_.empty () || options_->comparator ->Compare (key, last_key_piece) > 0 );
46+ size_t shared = 0 ;
47+ // get max shared prefix
48+ if (counter_ < options_->block_restart_interval ) {
49+ const size_t min_lenghth = std::min (last_key_piece.Size (), key.Size ());
50+ while ((shared < min_lenghth) && (last_key_piece[shared] == key[shared])) {
51+ shared++;
52+ }
53+ } else {
54+ // case up to block's restart interval, set restarts and reset the counter
55+ restarts_.push_back (buffer_.size ());
56+ counter_ = 0 ;
57+ }
58+ const size_t non_shared = key.Size () - shared;
59+
60+ // metadata
61+ PutVarint32 (&buffer_, shared);
62+ PutVarint32 (&buffer_, non_shared);
63+ PutVarint32 (&buffer_, val.Size ());
64+
65+ // true data
66+ buffer_.append (key.Data () + shared, non_shared);
67+ buffer_.append (val.Data (), val.Size ());
68+
69+ // reset last_key
70+ last_key_.resize (shared);
71+ last_key_.append (key.Data () + shared, non_shared);
72+ assert (Slice (last_key_) == key);
73+ counter_++;
74+ }
75+
76+ } // namespace db
0 commit comments