小组成员: 曹可心-10223903406 朴祉燕-10224602413
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

58 lines
2.6 KiB

#include <cstdint>
#include "db/vlog_reader.h"
#include "leveldb/slice.h"
#include "leveldb/env.h"
#include "util/coding.h"
namespace leveldb{
namespace vlog{
VReader::VReader(SequentialFile* file) // A file abstraction for reading sequentially through a file
:file_(file){}
Status VReader::ReadRecord(uint64_t vfile_offset, std::string* record){
Status s;
Slice size_slice;
char size_buf[11];
uint64_t rec_size = 0;
s = file_->SkipFromHead(vfile_offset); // 将文件的读取位置移动到 vfile_offset
if(s.ok()) s = file_ -> Read(10, &size_slice, size_buf); // 先把Record 长度读出来, 最长10字节.
if(s.ok()){
if(GetVarint64(&size_slice, &rec_size) == false){ // 解析变长整数,得到记录的长度 rec_size
return Status::Corruption("Failed to decode vlog record size.");
}
std::string rec;
char* c_rec = new char[rec_size]; // 为记录分配一个临时缓冲区
//TODO: Should delete c_rec?
rec.resize(rec_size);
Slice rec_slice;
s = file_->SkipFromHead(vfile_offset + (size_slice.data() - size_buf)); // 将文件的读取位置移动
if(!s.ok()) return s;
s = file_-> Read(rec_size, &rec_slice, c_rec); // 从文件中读取 rec_size 字节的数据到 c_rec 中,并用 rec_slice 包装这些数据
if(!s.ok()) return s;
rec = std::string(c_rec, rec_size);
*record = std::move(std::string(rec));
}
return s;
}
Status VReader::ReadKV(uint64_t vfile_offset, std::string* key, std::string* val){
std::string record_str;
Status s = ReadRecord(vfile_offset, &record_str);
if(s.ok()){
Slice record = Slice(record_str);
//File the val
uint64_t key_size;
bool decode_flag = true;
decode_flag &= GetVarint64(&record, &key_size); // 获取键的长度
if(decode_flag){
*key = Slice(record.data(), key_size).ToString(); // 从record中截取键值
record = Slice(record.data() + key_size, record.size() - key_size); // 截取剩余的record
}
uint64_t val_size;
decode_flag &= GetVarint64(&record, &val_size); // 获取value的长度
if(decode_flag) *val = Slice(record.data(), val_size).ToString(); // 截取value的值
if(!decode_flag || val->size() != record.size()){
s = Status::Corruption("Failed to decode Record Read From vlog.");
}
}
return s;
}
}// namespace vlog.
}