Skip to content

Commit 798f52f

Browse files
committed
feat: implement block_builder
1 parent 711c757 commit 798f52f

2 files changed

Lines changed: 135 additions & 0 deletions

File tree

src/table/block_build.cc

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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

src/table/block_builder.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#pragma once
2+
3+
#include <cstddef>
4+
#include <cstdint>
5+
#include <vector>
6+
7+
#include "slice.h"
8+
9+
namespace db {
10+
11+
struct Options;
12+
13+
// * Block Format
14+
// [Data-Entry-A]
15+
// [Data-Entry-B]
16+
// [Data-Entry-C]
17+
// [RestartArray]
18+
// [Restart-Size]
19+
class BlockBuilder {
20+
public:
21+
explicit BlockBuilder(const Options* options);
22+
23+
BlockBuilder(const BlockBuilder&) = delete;
24+
BlockBuilder& operator=(const BlockBuilder&) = delete;
25+
26+
// Reset all data as if the BlockBuilder was just constructed.
27+
void Reset();
28+
29+
// NOTICE: DO NOT call Add() after Finish() called
30+
// REQUIRES: key is larger than
31+
void Add(const Slice& key, const Slice& value);
32+
33+
// Finish building the block and returns a slice that refers to the
34+
// block contents. The returned slice will remain valid until Reset()
35+
// is called or the BlockBuilder deconstructed.
36+
//
37+
// Add() should not called if Finish() has been called. It is because Finish()
38+
// will append [restart array][restart count] at the end of the block.
39+
// If Add() called after Finish(), the Block's format will be wrong.
40+
Slice Finish();
41+
42+
// Return an estimate of current size of the block
43+
size_t CurrentSizeEstimate() const;
44+
45+
// return true iff no entries have been added since the last Reset()
46+
bool empty() const {
47+
return buffer_.empty();
48+
}
49+
50+
private:
51+
const Options* options_;
52+
std::string buffer_;
53+
std::vector<uint32_t> restarts_;
54+
int counter_;
55+
bool finished_;
56+
std::string last_key_;
57+
};
58+
59+
} // namespace db

0 commit comments

Comments
 (0)