~ubuntu-branches/ubuntu/quantal/ceph/quantal

« back to all changes in this revision

Viewing changes to src/leveldb/db/write_batch.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-07-16 09:56:24 UTC
  • mfrom: (0.3.11)
  • mto: This revision was merged to the branch mainline in revision 17.
  • Revision ID: package-import@ubuntu.com-20120716095624-azr2w4hbhei1rxmx
Tags: upstream-0.48
ImportĀ upstreamĀ versionĀ 0.48

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
4
 
//
5
 
// WriteBatch::rep_ :=
6
 
//    sequence: fixed64
7
 
//    count: fixed32
8
 
//    data: record[count]
9
 
// record :=
10
 
//    kTypeValue varstring varstring         |
11
 
//    kTypeDeletion varstring
12
 
// varstring :=
13
 
//    len: varint32
14
 
//    data: uint8[len]
15
 
 
16
 
#include "leveldb/write_batch.h"
17
 
 
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"
23
 
 
24
 
namespace leveldb {
25
 
 
26
 
WriteBatch::WriteBatch() {
27
 
  Clear();
28
 
}
29
 
 
30
 
WriteBatch::~WriteBatch() { }
31
 
 
32
 
WriteBatch::Handler::~Handler() { }
33
 
 
34
 
void WriteBatch::Clear() {
35
 
  rep_.clear();
36
 
  rep_.resize(12);
37
 
}
38
 
 
39
 
Status WriteBatch::Iterate(Handler* handler) const {
40
 
  Slice input(rep_);
41
 
  if (input.size() < 12) {
42
 
    return Status::Corruption("malformed WriteBatch (too small)");
43
 
  }
44
 
 
45
 
  input.remove_prefix(12);
46
 
  Slice key, value;
47
 
  int found = 0;
48
 
  while (!input.empty()) {
49
 
    found++;
50
 
    char tag = input[0];
51
 
    input.remove_prefix(1);
52
 
    switch (tag) {
53
 
      case kTypeValue:
54
 
        if (GetLengthPrefixedSlice(&input, &key) &&
55
 
            GetLengthPrefixedSlice(&input, &value)) {
56
 
          handler->Put(key, value);
57
 
        } else {
58
 
          return Status::Corruption("bad WriteBatch Put");
59
 
        }
60
 
        break;
61
 
      case kTypeDeletion:
62
 
        if (GetLengthPrefixedSlice(&input, &key)) {
63
 
          handler->Delete(key);
64
 
        } else {
65
 
          return Status::Corruption("bad WriteBatch Delete");
66
 
        }
67
 
        break;
68
 
      default:
69
 
        return Status::Corruption("unknown WriteBatch tag");
70
 
    }
71
 
  }
72
 
  if (found != WriteBatchInternal::Count(this)) {
73
 
    return Status::Corruption("WriteBatch has wrong count");
74
 
  } else {
75
 
    return Status::OK();
76
 
  }
77
 
}
78
 
 
79
 
int WriteBatchInternal::Count(const WriteBatch* b) {
80
 
  return DecodeFixed32(b->rep_.data() + 8);
81
 
}
82
 
 
83
 
void WriteBatchInternal::SetCount(WriteBatch* b, int n) {
84
 
  EncodeFixed32(&b->rep_[8], n);
85
 
}
86
 
 
87
 
SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {
88
 
  return SequenceNumber(DecodeFixed64(b->rep_.data()));
89
 
}
90
 
 
91
 
void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {
92
 
  EncodeFixed64(&b->rep_[0], seq);
93
 
}
94
 
 
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);
100
 
}
101
 
 
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);
106
 
}
107
 
 
108
 
namespace {
109
 
class MemTableInserter : public WriteBatch::Handler {
110
 
 public:
111
 
  SequenceNumber sequence_;
112
 
  MemTable* mem_;
113
 
 
114
 
  virtual void Put(const Slice& key, const Slice& value) {
115
 
    mem_->Add(sequence_, kTypeValue, key, value);
116
 
    sequence_++;
117
 
  }
118
 
  virtual void Delete(const Slice& key) {
119
 
    mem_->Add(sequence_, kTypeDeletion, key, Slice());
120
 
    sequence_++;
121
 
  }
122
 
};
123
 
}  // namespace
124
 
 
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);
131
 
}
132
 
 
133
 
void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) {
134
 
  assert(contents.size() >= 12);
135
 
  b->rep_.assign(contents.data(), contents.size());
136
 
}
137
 
 
138
 
}  // namespace leveldb