Skip to content

Commit 27b22f1

Browse files
committed
Merge pull request XRPLF#249 from tdfischer/decompression-refactoring
Decompression refactoring
2 parents 5600c8f + fb6456b commit 27b22f1

15 files changed

+153
-226
lines changed

table/block.cc

+3-8
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,7 @@ uint32_t Block::NumRestarts() const {
299299

300300
Block::Block(const BlockContents& contents)
301301
: data_(contents.data.data()),
302-
size_(contents.data.size()),
303-
owned_(contents.heap_allocated),
304-
cachable_(contents.cachable),
305-
compression_type_(contents.compression_type) {
302+
size_(contents.data.size()) {
306303
if (size_ < sizeof(uint32_t)) {
307304
size_ = 0; // Error marker
308305
} else {
@@ -315,10 +312,8 @@ Block::Block(const BlockContents& contents)
315312
}
316313
}
317314

318-
Block::~Block() {
319-
if (owned_) {
320-
delete[] data_;
321-
}
315+
Block::Block(BlockContents&& contents) : Block(contents) {
316+
contents_ = std::move(contents);
322317
}
323318

324319
Iterator* Block::NewIterator(

table/block.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
#include "rocksdb/iterator.h"
1515
#include "rocksdb/options.h"
1616
#include "db/dbformat.h"
17+
#include "table/block_prefix_index.h"
18+
#include "table/block_hash_index.h"
19+
20+
#include "format.h"
1721

1822
namespace rocksdb {
1923

@@ -26,15 +30,16 @@ class BlockPrefixIndex;
2630
class Block {
2731
public:
2832
// Initialize the block with the specified contents.
33+
explicit Block(BlockContents&& contents);
2934
explicit Block(const BlockContents& contents);
3035

31-
~Block();
36+
~Block() = default;
3237

3338
size_t size() const { return size_; }
3439
const char* data() const { return data_; }
35-
bool cachable() const { return cachable_; }
40+
bool cachable() const { return contents_.cachable; }
3641
uint32_t NumRestarts() const;
37-
CompressionType compression_type() const { return compression_type_; }
42+
CompressionType compression_type() const { return contents_.compression_type; }
3843

3944
// If hash index lookup is enabled and `use_hash_index` is true. This block
4045
// will do hash lookup for the key prefix.
@@ -58,12 +63,10 @@ class Block {
5863
size_t ApproximateMemoryUsage() const;
5964

6065
private:
66+
BlockContents contents_;
6167
const char* data_;
6268
size_t size_;
6369
uint32_t restart_offset_; // Offset in data_ of restart array
64-
bool owned_; // Block owns data_[]
65-
bool cachable_;
66-
CompressionType compression_type_;
6770
std::unique_ptr<BlockHashIndex> hash_index_;
6871
std::unique_ptr<BlockPrefixIndex> prefix_index_;
6972

table/block_based_filter_block.cc

+9-4
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void BlockBasedFilterBlockBuilder::GenerateFilter() {
138138
BlockBasedFilterBlockReader::BlockBasedFilterBlockReader(
139139
const SliceTransform* prefix_extractor,
140140
const BlockBasedTableOptions& table_opt,
141-
const Slice& contents, bool delete_contents_after_use)
141+
const Slice& contents)
142142
: policy_(table_opt.filter_policy.get()),
143143
prefix_extractor_(prefix_extractor),
144144
whole_key_filtering_(table_opt.whole_key_filtering),
@@ -155,9 +155,14 @@ BlockBasedFilterBlockReader::BlockBasedFilterBlockReader(
155155
data_ = contents.data();
156156
offset_ = data_ + last_word;
157157
num_ = (n - 5 - last_word) / 4;
158-
if (delete_contents_after_use) {
159-
filter_data.reset(contents.data());
160-
}
158+
}
159+
160+
BlockBasedFilterBlockReader::BlockBasedFilterBlockReader(
161+
const SliceTransform* prefix_extractor,
162+
const BlockBasedTableOptions& table_opt,
163+
BlockContents &&contents)
164+
: BlockBasedFilterBlockReader (prefix_extractor, table_opt, contents.data) {
165+
contents_ = std::move(contents);
161166
}
162167

163168
bool BlockBasedFilterBlockReader::KeyMayMatch(const Slice& key,

table/block_based_filter_block.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ class BlockBasedFilterBlockReader : public FilterBlockReader {
7474
// REQUIRES: "contents" and *policy must stay live while *this is live.
7575
BlockBasedFilterBlockReader(const SliceTransform* prefix_extractor,
7676
const BlockBasedTableOptions& table_opt,
77-
const Slice& contents,
78-
bool delete_contents_after_use = false);
77+
const Slice& contents);
78+
BlockBasedFilterBlockReader(const SliceTransform* prefix_extractor,
79+
const BlockBasedTableOptions& table_opt,
80+
BlockContents&& contents);
7981
virtual bool IsBlockBased() override { return true; }
8082
virtual bool KeyMayMatch(const Slice& key,
8183
uint64_t block_offset = kNotValid) override;
@@ -91,7 +93,7 @@ class BlockBasedFilterBlockReader : public FilterBlockReader {
9193
const char* offset_; // Pointer to beginning of offset array (at block-end)
9294
size_t num_; // Number of entries in offset array
9395
size_t base_lg_; // Encoding parameter (see kFilterBaseLg in .cc file)
94-
std::unique_ptr<const char[]> filter_data;
96+
BlockContents contents_;
9597

9698
bool MayMatch(const Slice& entry, uint64_t block_offset);
9799

table/block_based_table_builder.cc

+5-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <memory>
1818
#include <string>
1919
#include <unordered_map>
20+
#include <utility>
2021

2122
#include "db/dbformat.h"
2223

@@ -634,18 +635,13 @@ Status BlockBasedTableBuilder::InsertBlockInCache(const Slice& block_contents,
634635
Cache::Handle* cache_handle = nullptr;
635636
size_t size = block_contents.size();
636637

637-
char* ubuf = new char[size + 1]; // make a new copy
638-
memcpy(ubuf, block_contents.data(), size);
638+
std::unique_ptr<char[]> ubuf(new char[size+1]);
639+
memcpy(ubuf.get(), block_contents.data(), size);
639640
ubuf[size] = type;
640641

641-
BlockContents results;
642-
Slice sl(ubuf, size);
643-
results.data = sl;
644-
results.cachable = true; // XXX
645-
results.heap_allocated = true;
646-
results.compression_type = type;
642+
BlockContents results(std::move(ubuf), size, true, type);
647643

648-
Block* block = new Block(results);
644+
Block* block = new Block(std::move(results));
649645

650646
// make cache key by appending the file offset to the cache prefix id
651647
char* end = EncodeVarint64(

table/block_based_table_reader.cc

+9-31
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Status ReadBlockFromFile(RandomAccessFile* file, const Footer& footer,
6666
Status s = ReadBlockContents(file, footer, options, handle, &contents, env,
6767
do_uncompress);
6868
if (s.ok()) {
69-
*result = new Block(contents);
69+
*result = new Block(std::move(contents));
7070
}
7171

7272
return s;
@@ -252,9 +252,6 @@ class HashIndexReader : public IndexReader {
252252
&prefixes_meta_contents, env,
253253
true /* do decompression */);
254254
if (!s.ok()) {
255-
if (prefixes_contents.heap_allocated) {
256-
delete[] prefixes_contents.data.data();
257-
}
258255
// TODO: log error
259256
return Status::OK();
260257
}
@@ -269,7 +266,7 @@ class HashIndexReader : public IndexReader {
269266
// TODO: log error
270267
if (s.ok()) {
271268
new_index_reader->index_block_->SetBlockHashIndex(hash_index);
272-
new_index_reader->OwnPrefixesContents(prefixes_contents);
269+
new_index_reader->OwnPrefixesContents(std::move(prefixes_contents));
273270
}
274271
} else {
275272
BlockPrefixIndex* prefix_index = nullptr;
@@ -283,18 +280,6 @@ class HashIndexReader : public IndexReader {
283280
}
284281
}
285282

286-
// Always release prefix meta block
287-
if (prefixes_meta_contents.heap_allocated) {
288-
delete[] prefixes_meta_contents.data.data();
289-
}
290-
291-
// Release prefix content block if we don't own it.
292-
if (!new_index_reader->own_prefixes_contents_) {
293-
if (prefixes_contents.heap_allocated) {
294-
delete[] prefixes_contents.data.data();
295-
}
296-
}
297-
298283
return Status::OK();
299284
}
300285

@@ -314,24 +299,18 @@ class HashIndexReader : public IndexReader {
314299
private:
315300
HashIndexReader(const Comparator* comparator, Block* index_block)
316301
: IndexReader(comparator),
317-
index_block_(index_block),
318-
own_prefixes_contents_(false) {
302+
index_block_(index_block) {
319303
assert(index_block_ != nullptr);
320304
}
321305

322306
~HashIndexReader() {
323-
if (own_prefixes_contents_ && prefixes_contents_.heap_allocated) {
324-
delete[] prefixes_contents_.data.data();
325-
}
326307
}
327308

328-
void OwnPrefixesContents(const BlockContents& prefixes_contents) {
329-
prefixes_contents_ = prefixes_contents;
330-
own_prefixes_contents_ = true;
309+
void OwnPrefixesContents(BlockContents&& prefixes_contents) {
310+
prefixes_contents_ = std::move(prefixes_contents);
331311
}
332312

333313
std::unique_ptr<Block> index_block_;
334-
bool own_prefixes_contents_;
335314
BlockContents prefixes_contents_;
336315
};
337316

@@ -677,7 +656,7 @@ Status BlockBasedTable::GetDataBlockFromCache(
677656

678657
// Insert uncompressed block into block cache
679658
if (s.ok()) {
680-
block->value = new Block(contents); // uncompressed block
659+
block->value = new Block(std::move(contents)); // uncompressed block
681660
assert(block->value->compression_type() == kNoCompression);
682661
if (block_cache != nullptr && block->value->cachable() &&
683662
read_options.fill_cache) {
@@ -715,7 +694,7 @@ Status BlockBasedTable::PutDataBlockToCache(
715694
}
716695

717696
if (raw_block->compression_type() != kNoCompression) {
718-
block->value = new Block(contents); // uncompressed block
697+
block->value = new Block(std::move(contents)); // uncompressed block
719698
} else {
720699
block->value = raw_block;
721700
raw_block = nullptr;
@@ -768,15 +747,14 @@ FilterBlockReader* BlockBasedTable::ReadFilter(
768747
assert(rep->filter_policy);
769748
if (kFilterBlockPrefix == filter_block_prefix) {
770749
return new BlockBasedFilterBlockReader(rep->ioptions.prefix_extractor,
771-
rep->table_options, block.data, block.heap_allocated);
750+
rep->table_options, std::move(block));
772751
} else if (kFullFilterBlockPrefix == filter_block_prefix) {
773752
auto filter_bits_reader = rep->filter_policy->
774753
GetFilterBitsReader(block.data);
775754

776755
if (filter_bits_reader != nullptr) {
777756
return new FullFilterBlockReader(rep->ioptions.prefix_extractor,
778-
rep->table_options, block.data, filter_bits_reader,
779-
block.heap_allocated);
757+
rep->table_options, std::move(block), filter_bits_reader);
780758
}
781759
}
782760
return nullptr;

table/block_test.cc

+2-4
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ TEST(BlockTest, SimpleTest) {
9292
BlockContents contents;
9393
contents.data = rawblock;
9494
contents.cachable = false;
95-
contents.heap_allocated = false;
96-
Block reader(contents);
95+
Block reader(std::move(contents));
9796

9897
// read contents of block sequentially
9998
int count = 0;
@@ -143,12 +142,11 @@ BlockContents GetBlockContents(std::unique_ptr<BlockBuilder> *builder,
143142
BlockContents contents;
144143
contents.data = rawblock;
145144
contents.cachable = false;
146-
contents.heap_allocated = false;
147145

148146
return contents;
149147
}
150148

151-
void CheckBlockContents(BlockContents contents, const int max_key,
149+
void CheckBlockContents(const BlockContents &contents, const int max_key,
152150
const std::vector<std::string> &keys,
153151
const std::vector<std::string> &values) {
154152
const size_t prefix_size = 6;

table/filter_block.h

+5
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,22 @@
1818

1919
#pragma once
2020

21+
#include <memory>
2122
#include <stddef.h>
2223
#include <stdint.h>
2324
#include <string>
2425
#include <vector>
2526
#include "rocksdb/options.h"
2627
#include "rocksdb/slice.h"
28+
#include "rocksdb/slice_transform.h"
2729
#include "rocksdb/table.h"
30+
#include "util/hash.h"
31+
#include "format.h"
2832

2933
namespace rocksdb {
3034

3135
const uint64_t kNotValid = ULLONG_MAX;
36+
class FilterPolicy;
3237

3338
// A FilterBlockBuilder is used to construct all of the filters for a
3439
// particular Table. It generates a single string which is stored as

0 commit comments

Comments
 (0)