#include "table/blob_file.h"
|
|
#include "util/coding.h"
|
|
#include "util/crc32c.h"
|
|
#include <cassert>
|
|
|
|
namespace leveldb {
|
|
namespace blob {
|
|
|
|
BlobFile::BlobFile(WritableFile* dest) : dest_(dest), head_(0) {}
|
|
|
|
BlobFile::BlobFile(WritableFile* dest, uint64_t dest_length)
|
|
: dest_(dest), head_(dest_length) {}
|
|
|
|
BlobFile::~BlobFile() = default;
|
|
|
|
Status BlobFile::AddRecord(const Slice& key, const Slice& value, uint64_t& offset) {
|
|
// 动态写入记录,返回写入的偏移量
|
|
return EmitDynamicRecord(key, value, offset);
|
|
}
|
|
|
|
Status BlobFile::EmitDynamicRecord(const Slice& key, const Slice& value, uint64_t& offset) {
|
|
// 记录头部,包括 key 和 value 的长度
|
|
char header[8]; // 4 字节 key 长度 + 4 字节 value 长度
|
|
|
|
uint32_t key_size = static_cast<uint32_t>(key.size());
|
|
uint32_t value_size = static_cast<uint32_t>(value.size());
|
|
|
|
// 编码 key 和 value 长度
|
|
EncodeFixed32(header, key_size);
|
|
EncodeFixed32(header + 4, value_size);
|
|
|
|
// 写入头部
|
|
Status s = dest_->Append(Slice(header, sizeof(header)));
|
|
if (!s.ok()) {
|
|
return s;
|
|
}
|
|
|
|
// 写入 key 和 value 数据
|
|
s = dest_->Append(key);
|
|
if (!s.ok()) {
|
|
return s;
|
|
}
|
|
|
|
s = dest_->Append(value);
|
|
if (!s.ok()) {
|
|
return s;
|
|
}
|
|
|
|
// 刷新文件到磁盘
|
|
s = dest_->Flush();
|
|
if (!s.ok()) {
|
|
return s;
|
|
}
|
|
|
|
// 更新偏移量
|
|
offset = head_;
|
|
head_ += sizeof(header) + key_size + value_size;
|
|
|
|
return Status::OK();
|
|
}
|
|
|
|
} // namespace blob
|
|
} // namespace leveldb
|