类介绍
Block主要负责解析sstable文件中的block;
数据成员介绍
30 const char* data_; //对应整个block块数据
31 size_t size_; //对应整个block的大小
32 uint32_t restart_offset_; // 相对于data_的,重新开始点的第一个元素的偏移量
33 bool owned_; // 如果为true,当前block就需要释放data_
39 class Iter;//迭代器,后面再讲
成员方法介绍
23 Block::Block(const BlockContents& contents)
24 : data_(contents.data.data()),
25 size_(contents.data.size()),
26 owned_(contents.heap_allocated) {
27 if (size_ < sizeof(uint32_t)) {
28 size_ = 0; // Error marker
29 } else {
30 size_t max_restarts_allowed = (size_-sizeof(uint32_t)) / sizeof(uint32_t);//用总大小,减去保存在block末尾的num_restarts,再除以每个restart的大小,就是restart最多的个数
31 if (NumRestarts() > max_restarts_allowed) {
32 // The size is too small for NumRestarts()
33 size_ = 0;
34 } else {
35 restart_offset_ = size_ - (1 + NumRestarts()) * sizeof(uint32_t);
36 }
37 }
38 }
作用:构造函数,确定data_、size_、restart_offset_的值
18 inline uint32_t Block::NumRestarts() const {
19 assert(size_ >= sizeof(uint32_t));
20 return DecodeFixed32(data_ + size_ - sizeof(uint32_t));
21 }
作用:计算出重新开始点的个数;
53 static inline const char* DecodeEntry(const char* p, const char* limit,
54 uint32_t* shared,
55 uint32_t* non_shared,
56 uint32_t* value_length) {
57 if (limit - p < 3) return NULL;
58 *shared = reinterpret_cast<const unsigned char*>(p)[0];
59 *non_shared = reinterpret_cast<const unsigned char*>(p)[1];
60 *value_length = reinterpret_cast<const unsigned char*>(p)[2];
61 if ((*shared | *non_shared | *value_length) < 128) {
62 // 这里相当于做了一个优化,如果三个值之和都小于128,那肯定是每个值只占一个字节
63 p += 3;
64 } else {
65 if ((p = GetVarint32Ptr(p, limit, shared)) == NULL) return NULL;
66 if ((p = GetVarint32Ptr(p, limit, non_shared)) == NULL) return NULL;
67 if ((p = GetVarint32Ptr(p, limit, value_length)) == NULL) return NULL;
68 }
69
70 if (static_cast<uint32_t>(limit - p) < (*non_shared + *value_length)) {
71 return NULL;
72 }
73 return p;
74 }
作用:通过给出一条记录的初始位置和结束位置,解析出shared、non_shared、value_length,并返回key_delta的位置
256 Iterator* Block::NewIterator(const Comparator* cmp) {
257 if (size_ < sizeof(uint32_t)) {
258 return NewErrorIterator(Status::Corruption("bad block contents"));
259 }
260 const uint32_t num_restarts = NumRestarts();
261 if (num_restarts == 0) {
262 return NewEmptyIterator();
263 } else {
264 return new Iter(cmp, data_, restart_offset_, num_restarts);
265 }
266 }
作用:返回一个可以遍历block的迭代器
迭代器数据成员介绍
78 const Comparator* const comparator_;
79 const char* const data_; // underlying block contents
80 uint32_t const restarts_; // Offset of restart array (list of fixed32)
81 uint32_t const num_restarts_; // Number of uint32_t entries in restart array
82
83 // current_ is offset in data_ of current entry. >= restarts_ if !Valid
84 uint32_t current_;
85 uint32_t restart_index_; // Index of restart block in which current_ falls
86 std::string key_;
87 Slice value_;
88 Status status_;
迭代器成员方法介绍
165 virtual void Seek(const Slice& target) {
166 // Binary search in restart array to find the last restart point
167 // with a key < target
168 uint32_t left = 0;
169 uint32_t right = num_restarts_ - 1;
170 while (left < right) {
171 uint32_t mid = (left + right + 1) / 2;
172 uint32_t region_offset = GetRestartPoint(mid);
173 uint32_t shared, non_shared, value_length;
174 const char* key_ptr = DecodeEntry(data_ + region_offset,
175 data_ + restarts_,
176 &shared, &non_shared, &value_length);
177 if (key_ptr == NULL || (shared != 0)) {
178 CorruptionError();
179 return;
180 }
181 Slice mid_key(key_ptr, non_shared);
182 if (Compare(mid_key, target) < 0) {
183 // Key at "mid" is smaller than "target". Therefore all
184 // blocks before "mid" are uninteresting.
185 left = mid;
186 } else {
187 // Key at "mid" is >= "target". Therefore all blocks at or
188 // after "mid" are uninteresting.
189 right = mid - 1;
190 }
191 }
192
193 // Linear search (within restart block) for first key >= target
194 SeekToRestartPoint(left);
195 while (true) {
196 if (!ParseNextKey()) {
197 return;
198 }
199 if (Compare(key_, target) >= 0) {
200 return;
201 }
202 }
203 }
作用:通过给定的目标key(target)来查找key,value;采用二分法,在重新开始点的范围内查找,找到小于target的最大的key,然后通过线性方式查找,找到大于等于target的key;
226 bool ParseNextKey() {
227 current_ = NextEntryOffset();
228 const char* p = data_ + current_;
229 const char* limit = data_ + restarts_; // Restarts come right after data
230 if (p >= limit) {
231 // No more entries to return. Mark as invalid.
232 current_ = restarts_;
233 restart_index_ = num_restarts_;
234 return false;
235 }
236
237 // Decode next entry
238 uint32_t shared, non_shared, value_length;
239 p = DecodeEntry(p, limit, &shared, &non_shared, &value_length);
240 if (p == NULL || key_.size() < shared) {
241 CorruptionError();
242 return false;
243 } else {
244 key_.resize(shared);
245 key_.append(p, non_shared);
246 value_ = Slice(p + non_shared, value_length);
247 while (restart_index_ + 1 < num_restarts_ &&
248 GetRestartPoint(restart_index_ + 1) < current_) {
249 ++restart_index_;
250 }
251 return true;
252 }
253 }
254 };
作用:通过当前的value_的位置,计算出下一个记录的offset,然后根据这个offset,计算出对应的key_,value_