WriteBatch主要是用來對多個資料進行批量寫入。
依賴關系
writeBatch類主要依賴于以下幾個類,如圖:
其中,Handler為抽象類,定義了put和delete接口。WriteBatchInternal類為writebatch的實作。
MemTableInserter為Handler的具體實作,實作具體的put和delete操作。此處使用了抽象工廠模式,即Handler為抽象工廠,MemTableInserter定義了具體的工廠。在MemTableInserter中定義了MemTable的成員,通過此成員實作put和delete操作。
writeBatch的資料結構
一個Batch結構前8個位元組是序列号,接下來4個位元組是寫入資料的總長度,再接下來是資料。資料的格式按照 類型,key,value的方式來排列。
類型主要分兩種,一種是寫入資料,另一種是删除資料。删除資料可以看成是一種特殊的寫入。
相關函數
- 此函數用于疊代處理writebatch中的資料。即寫入
Status WriteBatch::Iterate(Handler* handler) const {
Slice input(rep_);
if (input.size() < kHeader) {
return Status::Corruption("malformed WriteBatch (too small)");
}
input.remove_prefix(kHeader); //删除字首,8個位元組的序列号,4個位元組的長度,一共12個位元組
Slice key, value;
int found = 0;
while (!input.empty()) {
found++;
char tag = input[0];
input.remove_prefix(1);
switch (tag) {
case kTypeValue: //正常的寫入資料
if (GetLengthPrefixedSlice(&input, &key) &&
GetLengthPrefixedSlice(&input, &value)) {
handler->Put(key, value);
} else {
return Status::Corruption("bad WriteBatch Put");
}
break;
case kTypeDeletion: //删除的資料
if (GetLengthPrefixedSlice(&input, &key)) {
handler->Delete(key);
} else {
return Status::Corruption("bad WriteBatch Delete");
}
break;
default:
return Status::Corruption("unknown WriteBatch tag");
}
}
if (found != WriteBatchInternal::Count(this)) {
return Status::Corruption("WriteBatch has wrong count");
} else {
return Status::OK();
}
}
- 求長度,資料的長度加上8個位元組序列号的長度即可
int WriteBatchInternal::Count(const WriteBatch* b) {
return DecodeFixed32(b->rep_.data() + 8);
}
- 設定長度值
void WriteBatchInternal::SetCount(WriteBatch* b, int n) {
EncodeFixed32(&b->rep_[8], n);
}
- 擷取序列号
SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {
return SequenceNumber(DecodeFixed64(b->rep_.data()));
}
- 設定序列号
void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {
EncodeFixed64(&b->rep_[0], seq);
}
- 寫入
//寫入實際上是先寫入到batch裡面
void WriteBatch::Put(const Slice& key, const Slice& value) {
WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
rep_.push_back(static_cast<char>(kTypeValue));
PutLengthPrefixedSlice(&rep_, key);
PutLengthPrefixedSlice(&rep_, value);
}
- 删除
//删除實際上是将key寫入,同時在key之前标注此key對應的資料删除
void WriteBatch::Delete(const Slice& key) {
WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
rep_.push_back(static_cast<char>(kTypeDeletion));
PutLengthPrefixedSlice(&rep_, key);
}
- writebatch追加
//兩個batch進行追加
void WriteBatch::Append(const WriteBatch &source) {
WriteBatchInternal::Append(this, &source);
}