共计 1726 个字符,预计需要花费 5 分钟才能阅读完成。
mem 到 table
用到了内存集合为块 4k。file 中写先写 64Kbuf 再 write、一个文件写完调 fsync
immem=>table
迭代器。循环。
计算当前,一块一次 flush(加入到 fd 的 buffer),一块加一次 index block,
这里简单的每个 block 一次 write。append 还做了留 64kbuf。在 write
一个 table 一次 fsync.
BuildTable
1.add 节点。for (; iter->Valid(); iter->Next()) {Slice key = iter->key();
meta->largest.DecodeFrom(key);
builder->Add(key, iter->value());
}
2. 加一些汇总 meta block 等
s = builder->Finish();
if (s.ok()) {meta->file_size = builder->FileSize();
assert(meta->file_size > 0);
}
delete builder;
// 落盘
if (s.ok()) {s = file->Sync(); // 封装 fsync
}
if (s.ok()) {s = file->Close();
}
针对 1add
数据结构要算出各部分偏移量,维持 4k。一块加一个索引
每 4k 调一次 flush( 自己实现)flush 维护 64K 的 buf。满了调用 write。否则只是放在 buf 中
if (r->pending_index_entry) {r->index_block.Add(r->last_key, Slice(handle_encoding));
r->pending_index_entry = false;
}
r->data_block.Add(key, value); // r 结构中改
const size_t estimated_block_size = r->data_block.CurrentSizeEstimate();
if (estimated_block_size >= r->options.block_size) {Flush();
}
Flush:
WriteBlock(&r->data_block, &r->pending_handle); //r->file->Append(block_contents);
if (ok()) {
r->pending_index_entry = true;
r->status = r->file->Flush(); // 调动 WriteUnbuffered 真正 write}
这里每 64k 调用一次 write。否则是 fd 的 buf
Status Append(const Slice& data) override {size_t write_size = data.size();
const char* write_data = data.data();
// Fit as much as possible into buffer.
size_t copy_size = std::min(write_size, kWritableFileBufferSize - pos_);
std::memcpy(buf_ + pos_, write_data, copy_size);
write_data += copy_size;
write_size -= copy_size;
pos_ += copy_size;
if (write_size == 0) {return Status::OK();
}
// Can't fit in buffer, so need to do at least one write.
Status status = FlushBuffer();
if (!status.ok()) {return status;}
// Small writes go to buffer, large writes are written directly.
if (write_size < kWritableFileBufferSize) { //64K
std::memcpy(buf_, write_data, write_size);
pos_ = write_size;
return Status::OK();}
return WriteUnbuffered(write_data, write_size);
}
正文完