|
|
|
@ -465,6 +465,7 @@ struct BlockBasedTableBuilder::Rep { |
|
|
|
|
BlockHandle pending_handle; // Handle to add to index block
|
|
|
|
|
|
|
|
|
|
std::string compressed_output; |
|
|
|
|
bool skip_flush; |
|
|
|
|
std::unique_ptr<FlushBlockPolicy> flush_block_policy; |
|
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<IntTblPropCollector>> table_properties_collectors; |
|
|
|
@ -476,7 +477,8 @@ struct BlockBasedTableBuilder::Rep { |
|
|
|
|
int_tbl_prop_collector_factories, |
|
|
|
|
uint32_t column_family_id, WritableFileWriter* f, |
|
|
|
|
const CompressionType _compression_type, |
|
|
|
|
const CompressionOptions& _compression_opts, const bool skip_filters) |
|
|
|
|
const CompressionOptions& _compression_opts,
|
|
|
|
|
const bool skip_filters, const bool skip_flush) |
|
|
|
|
: ioptions(_ioptions), |
|
|
|
|
table_options(table_opt), |
|
|
|
|
internal_comparator(icomparator), |
|
|
|
@ -490,6 +492,7 @@ struct BlockBasedTableBuilder::Rep { |
|
|
|
|
compression_opts(_compression_opts), |
|
|
|
|
filter_block(skip_filters ? nullptr : CreateFilterBlockBuilder( |
|
|
|
|
_ioptions, table_options)), |
|
|
|
|
skip_flush(skip_flush), |
|
|
|
|
flush_block_policy( |
|
|
|
|
table_options.flush_block_policy_factory->NewFlushBlockPolicy( |
|
|
|
|
table_options, data_block)) { |
|
|
|
@ -512,7 +515,8 @@ BlockBasedTableBuilder::BlockBasedTableBuilder( |
|
|
|
|
int_tbl_prop_collector_factories, |
|
|
|
|
uint32_t column_family_id, WritableFileWriter* file, |
|
|
|
|
const CompressionType compression_type, |
|
|
|
|
const CompressionOptions& compression_opts, const bool skip_filters) { |
|
|
|
|
const CompressionOptions& compression_opts, |
|
|
|
|
const bool skip_filters, const bool skip_flush) { |
|
|
|
|
BlockBasedTableOptions sanitized_table_options(table_options); |
|
|
|
|
if (sanitized_table_options.format_version == 0 && |
|
|
|
|
sanitized_table_options.checksum != kCRC32c) { |
|
|
|
@ -526,7 +530,7 @@ BlockBasedTableBuilder::BlockBasedTableBuilder( |
|
|
|
|
|
|
|
|
|
rep_ = new Rep(ioptions, sanitized_table_options, internal_comparator, |
|
|
|
|
int_tbl_prop_collector_factories, column_family_id, file, |
|
|
|
|
compression_type, compression_opts, skip_filters); |
|
|
|
|
compression_type, compression_opts, skip_filters, skip_flush); |
|
|
|
|
|
|
|
|
|
if (rep_->filter_block != nullptr) { |
|
|
|
|
rep_->filter_block->StartBlock(0); |
|
|
|
@ -552,11 +556,12 @@ void BlockBasedTableBuilder::Add(const Slice& key, const Slice& value) { |
|
|
|
|
assert(r->internal_comparator.Compare(key, Slice(r->last_key)) > 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto should_flush = r->flush_block_policy->Update(key, value); |
|
|
|
|
if (should_flush) { |
|
|
|
|
auto should_seal = r->flush_block_policy->Update(key, value); |
|
|
|
|
if (should_seal) { |
|
|
|
|
assert(!r->data_block.empty()); |
|
|
|
|
SealDataBlock(); |
|
|
|
|
Flush(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add item to index block.
|
|
|
|
|
// We do not emit the index entry for a block until we have seen the
|
|
|
|
|
// first key for the next data block. This allows us to use shorter
|
|
|
|
@ -587,19 +592,23 @@ void BlockBasedTableBuilder::Add(const Slice& key, const Slice& value) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void BlockBasedTableBuilder::Flush() { |
|
|
|
|
Rep* r = rep_; |
|
|
|
|
if (ok() && !r->skip_flush) { |
|
|
|
|
r->status = r->file->Flush(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void BlockBasedTableBuilder::SealDataBlock() { |
|
|
|
|
Rep* r = rep_; |
|
|
|
|
assert(!r->closed); |
|
|
|
|
if (!ok()) return; |
|
|
|
|
if (r->data_block.empty()) return; |
|
|
|
|
WriteBlock(&r->data_block, &r->pending_handle); |
|
|
|
|
if (ok()) { |
|
|
|
|
r->status = r->file->Flush(); |
|
|
|
|
} |
|
|
|
|
if (r->filter_block != nullptr) { |
|
|
|
|
r->filter_block->StartBlock(r->offset); |
|
|
|
|
} |
|
|
|
|
r->props.data_size = r->offset; |
|
|
|
|
++r->props.num_data_blocks; |
|
|
|
|
++r->props.num_data_blocks;
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void BlockBasedTableBuilder::WriteBlock(BlockBuilder* block, |
|
|
|
@ -728,6 +737,7 @@ Status BlockBasedTableBuilder::InsertBlockInCache(const Slice& block_contents, |
|
|
|
|
Status BlockBasedTableBuilder::Finish() { |
|
|
|
|
Rep* r = rep_; |
|
|
|
|
bool empty_data_block = r->data_block.empty(); |
|
|
|
|
SealDataBlock(); |
|
|
|
|
Flush(); |
|
|
|
|
assert(!r->closed); |
|
|
|
|
r->closed = true; |
|
|
|
|