leveldb源码compact

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);
  }


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理