1
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file. See the AUTHORS file for names of contributors.
10
// kTypeValue varstring varstring |
11
// kTypeDeletion varstring
16
#include "leveldb/write_batch.h"
18
#include "leveldb/db.h"
19
#include "db/dbformat.h"
20
#include "db/memtable.h"
21
#include "db/write_batch_internal.h"
22
#include "util/coding.h"
26
WriteBatch::WriteBatch() {
30
WriteBatch::~WriteBatch() { }
32
WriteBatch::Handler::~Handler() { }
34
void WriteBatch::Clear() {
39
Status WriteBatch::Iterate(Handler* handler) const {
41
if (input.size() < 12) {
42
return Status::Corruption("malformed WriteBatch (too small)");
45
input.remove_prefix(12);
48
while (!input.empty()) {
51
input.remove_prefix(1);
54
if (GetLengthPrefixedSlice(&input, &key) &&
55
GetLengthPrefixedSlice(&input, &value)) {
56
handler->Put(key, value);
58
return Status::Corruption("bad WriteBatch Put");
62
if (GetLengthPrefixedSlice(&input, &key)) {
65
return Status::Corruption("bad WriteBatch Delete");
69
return Status::Corruption("unknown WriteBatch tag");
72
if (found != WriteBatchInternal::Count(this)) {
73
return Status::Corruption("WriteBatch has wrong count");
79
int WriteBatchInternal::Count(const WriteBatch* b) {
80
return DecodeFixed32(b->rep_.data() + 8);
83
void WriteBatchInternal::SetCount(WriteBatch* b, int n) {
84
EncodeFixed32(&b->rep_[8], n);
87
SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {
88
return SequenceNumber(DecodeFixed64(b->rep_.data()));
91
void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {
92
EncodeFixed64(&b->rep_[0], seq);
95
void WriteBatch::Put(const Slice& key, const Slice& value) {
96
WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
97
rep_.push_back(static_cast<char>(kTypeValue));
98
PutLengthPrefixedSlice(&rep_, key);
99
PutLengthPrefixedSlice(&rep_, value);
102
void WriteBatch::Delete(const Slice& key) {
103
WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
104
rep_.push_back(static_cast<char>(kTypeDeletion));
105
PutLengthPrefixedSlice(&rep_, key);
109
class MemTableInserter : public WriteBatch::Handler {
111
SequenceNumber sequence_;
114
virtual void Put(const Slice& key, const Slice& value) {
115
mem_->Add(sequence_, kTypeValue, key, value);
118
virtual void Delete(const Slice& key) {
119
mem_->Add(sequence_, kTypeDeletion, key, Slice());
125
Status WriteBatchInternal::InsertInto(const WriteBatch* b,
126
MemTable* memtable) {
127
MemTableInserter inserter;
128
inserter.sequence_ = WriteBatchInternal::Sequence(b);
129
inserter.mem_ = memtable;
130
return b->Iterate(&inserter);
133
void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) {
134
assert(contents.size() >= 12);
135
b->rep_.assign(contents.data(), contents.size());
138
} // namespace leveldb