#include "kv_sep/kvlog.h"
|
|
#include "db/dbformat.h"
|
|
#include "db/filename.h"
|
|
#include "db/write_batch_internal.h"
|
|
#include <cstdint>
|
|
#include "leveldb/env.h"
|
|
#include "leveldb/slice.h"
|
|
#include "leveldb/status.h"
|
|
#include "util/coding.h"
|
|
|
|
namespace leveldb {
|
|
void EncodeFP(const struct FilePointer &fp, char *scratch) {
|
|
EncodeFixed64(scratch, fp.FileNumber);
|
|
EncodeFixed64(scratch + 8, fp.FileOffset);
|
|
EncodeFixed64(scratch + 16, fp.Size);
|
|
|
|
}
|
|
|
|
void DecodeFp(struct FilePointer &fp, char *src) {
|
|
|
|
fp.FileNumber = DecodeFixed64(src);
|
|
fp.FileOffset = DecodeFixed64(src + 8);
|
|
fp.Size = DecodeFixed64(src + 16);
|
|
}
|
|
|
|
KVLog::KVLog(WritableFile *dest,uint64_t file_number):
|
|
dest_(dest),pos_(0),file_number(file_number) {}
|
|
|
|
KVLog::KVLog(WritableFile *dest, uint64_t dest_length,uint64_t file_number):
|
|
dest_(dest),pos_(dest_length),file_number(file_number) {}
|
|
|
|
Status KVLog::AddRecord(const Slice &slice, FilePointer &fp) {
|
|
//写入slice大小
|
|
EncodeFixed64(buf, slice.size());
|
|
Status s = dest_->Append(Slice(buf,8));
|
|
pos_ += 8;
|
|
//写入slice
|
|
fp.FileNumber = file_number;
|
|
fp.FileOffset = pos_;
|
|
fp.Size = slice.size();
|
|
s = dest_->Append(slice);
|
|
pos_ += slice.size();
|
|
if(s.ok()) {
|
|
s = dest_->Flush();
|
|
}
|
|
return s;
|
|
}
|
|
|
|
void KVLogReader::Next() {
|
|
if(input.empty()) {
|
|
NextWriteBatch();
|
|
if(!Valid()) return;
|
|
}
|
|
NextKV();
|
|
}
|
|
|
|
void KVLogReader::NextWriteBatch() {
|
|
Slice num;
|
|
file->Read(8, &num, number);
|
|
if(num.size() !=8) {
|
|
valid = false;
|
|
return;
|
|
}
|
|
uint64_t batch_size = DecodeFixed64(number);
|
|
if(batch_size > rep_size) {
|
|
delete[] rep_;
|
|
rep_ = new char[batch_size];
|
|
rep_size = batch_size;
|
|
}
|
|
input.clear();
|
|
file->Read(batch_size,&input,rep_);
|
|
if(input.size() != batch_size) {
|
|
valid = false;
|
|
return;
|
|
}
|
|
seq = DecodeFixed64(input.data()) - 1;//-1是为了和后面的nextkv的实现对齐
|
|
input.remove_prefix(12); //remove writebatch header
|
|
}
|
|
|
|
void KVLogReader::NextKV() {
|
|
seq++;
|
|
type = (ValueType)input[0];
|
|
input.remove_prefix(1);
|
|
switch (type) {
|
|
case kTypeValue:
|
|
if(GetLengthPrefixedSlice(&input, &key) &&
|
|
GetLengthPrefixedSlice(&input, &value)) {
|
|
|
|
} else {
|
|
valid = false;
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case kTypeDeletion:
|
|
if(GetLengthPrefixedSlice(&input, &key)) {
|
|
|
|
} else {
|
|
valid = false;
|
|
return;
|
|
}
|
|
break;
|
|
default:
|
|
valid = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|