leveldb源码compact

17次阅读

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


正文完
 0