From 26da3676d9afbbd2afe84dd77272aa3befbd9349 Mon Sep 17 00:00:00 2001 From: Siying Dong Date: Fri, 18 May 2018 12:54:09 -0700 Subject: [PATCH] class Block to store num_restarts_ Summary: Right now, every Block::NewIterator() reads num_restarts_ from the block, which is already read in Block::Block(). This sometimes cause a CPU cache miss. Although fetching this cacheline can usually benefit follow-up block restart offset reading, as they are close to each other, it's almost free to get ride of this read by storing it in the Block class. Closes https://github.com/facebook/rocksdb/pull/3869 Differential Revision: D8052493 Pulled By: siying fbshipit-source-id: 9c72360f0c2d7329f3c198ce4eaedd2bc14b87c1 --- table/block.cc | 9 +++++---- table/block.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/table/block.cc b/table/block.cc index ce45f4316..d13c6eb21 100644 --- a/table/block.cc +++ b/table/block.cc @@ -402,12 +402,14 @@ Block::Block(BlockContents&& contents, SequenceNumber _global_seqno, data_(contents_.data.data()), size_(contents_.data.size()), restart_offset_(0), + num_restarts_(0), global_seqno_(_global_seqno) { if (size_ < sizeof(uint32_t)) { size_ = 0; // Error marker } else { + num_restarts_ = NumRestarts(); restart_offset_ = - static_cast(size_) - (1 + NumRestarts()) * sizeof(uint32_t); + static_cast(size_) - (1 + num_restarts_) * sizeof(uint32_t); if (restart_offset_ > size_ - sizeof(uint32_t)) { // The size is too small for NumRestarts() and therefore // restart_offset_ wrapped around. @@ -432,15 +434,14 @@ BlockIter* Block::NewIterator(const Comparator* cmp, BlockIter* iter, ret_iter->Invalidate(Status::Corruption("bad block contents")); return ret_iter; } - const uint32_t num_restarts = NumRestarts(); - if (num_restarts == 0) { + if (num_restarts_ == 0) { // Empty block. ret_iter->Invalidate(Status::OK()); return ret_iter; } else { BlockPrefixIndex* prefix_index_ptr = total_order_seek ? nullptr : prefix_index_.get(); - ret_iter->Initialize(cmp, data_, restart_offset_, num_restarts, + ret_iter->Initialize(cmp, data_, restart_offset_, num_restarts_, prefix_index_ptr, global_seqno_, read_amp_bitmap_.get()); diff --git a/table/block.h b/table/block.h index 6cc304cdc..0c0371b65 100644 --- a/table/block.h +++ b/table/block.h @@ -184,6 +184,7 @@ class Block { const char* data_; // contents_.data.data() size_t size_; // contents_.data.size() uint32_t restart_offset_; // Offset in data_ of restart array + uint32_t num_restarts_; std::unique_ptr prefix_index_; std::unique_ptr read_amp_bitmap_; // All keys in the block will have seqno = global_seqno_, regardless of