leveldb-ruby 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +17 -0
- data/ext/leveldb/extconf.rb +10 -0
- data/ext/leveldb/leveldb.cc +181 -0
- data/leveldb/Makefile +172 -0
- data/leveldb/db/builder.cc +90 -0
- data/leveldb/db/builder.h +36 -0
- data/leveldb/db/corruption_test.cc +354 -0
- data/leveldb/db/db_bench.cc +677 -0
- data/leveldb/db/db_impl.cc +1236 -0
- data/leveldb/db/db_impl.h +180 -0
- data/leveldb/db/db_iter.cc +298 -0
- data/leveldb/db/db_iter.h +26 -0
- data/leveldb/db/db_test.cc +1192 -0
- data/leveldb/db/dbformat.cc +87 -0
- data/leveldb/db/dbformat.h +165 -0
- data/leveldb/db/dbformat_test.cc +112 -0
- data/leveldb/db/filename.cc +135 -0
- data/leveldb/db/filename.h +80 -0
- data/leveldb/db/filename_test.cc +122 -0
- data/leveldb/db/log_format.h +35 -0
- data/leveldb/db/log_reader.cc +254 -0
- data/leveldb/db/log_reader.h +108 -0
- data/leveldb/db/log_test.cc +500 -0
- data/leveldb/db/log_writer.cc +103 -0
- data/leveldb/db/log_writer.h +48 -0
- data/leveldb/db/memtable.cc +108 -0
- data/leveldb/db/memtable.h +85 -0
- data/leveldb/db/repair.cc +384 -0
- data/leveldb/db/skiplist.h +378 -0
- data/leveldb/db/skiplist_test.cc +378 -0
- data/leveldb/db/snapshot.h +66 -0
- data/leveldb/db/table_cache.cc +95 -0
- data/leveldb/db/table_cache.h +50 -0
- data/leveldb/db/version_edit.cc +268 -0
- data/leveldb/db/version_edit.h +106 -0
- data/leveldb/db/version_edit_test.cc +46 -0
- data/leveldb/db/version_set.cc +1060 -0
- data/leveldb/db/version_set.h +306 -0
- data/leveldb/db/write_batch.cc +138 -0
- data/leveldb/db/write_batch_internal.h +45 -0
- data/leveldb/db/write_batch_test.cc +89 -0
- data/leveldb/include/leveldb/cache.h +99 -0
- data/leveldb/include/leveldb/comparator.h +63 -0
- data/leveldb/include/leveldb/db.h +148 -0
- data/leveldb/include/leveldb/env.h +302 -0
- data/leveldb/include/leveldb/iterator.h +100 -0
- data/leveldb/include/leveldb/options.h +198 -0
- data/leveldb/include/leveldb/slice.h +109 -0
- data/leveldb/include/leveldb/status.h +100 -0
- data/leveldb/include/leveldb/table.h +70 -0
- data/leveldb/include/leveldb/table_builder.h +91 -0
- data/leveldb/include/leveldb/write_batch.h +64 -0
- data/leveldb/port/port.h +23 -0
- data/leveldb/port/port_android.cc +64 -0
- data/leveldb/port/port_android.h +150 -0
- data/leveldb/port/port_chromium.cc +80 -0
- data/leveldb/port/port_chromium.h +97 -0
- data/leveldb/port/port_example.h +115 -0
- data/leveldb/port/port_osx.cc +50 -0
- data/leveldb/port/port_osx.h +125 -0
- data/leveldb/port/port_posix.cc +50 -0
- data/leveldb/port/port_posix.h +94 -0
- data/leveldb/port/sha1_portable.cc +298 -0
- data/leveldb/port/sha1_portable.h +25 -0
- data/leveldb/port/sha1_test.cc +39 -0
- data/leveldb/port/win/stdint.h +24 -0
- data/leveldb/table/block.cc +263 -0
- data/leveldb/table/block.h +43 -0
- data/leveldb/table/block_builder.cc +109 -0
- data/leveldb/table/block_builder.h +57 -0
- data/leveldb/table/format.cc +131 -0
- data/leveldb/table/format.h +103 -0
- data/leveldb/table/iterator.cc +67 -0
- data/leveldb/table/iterator_wrapper.h +63 -0
- data/leveldb/table/merger.cc +197 -0
- data/leveldb/table/merger.h +26 -0
- data/leveldb/table/table.cc +175 -0
- data/leveldb/table/table_builder.cc +227 -0
- data/leveldb/table/table_test.cc +845 -0
- data/leveldb/table/two_level_iterator.cc +182 -0
- data/leveldb/table/two_level_iterator.h +34 -0
- data/leveldb/util/arena.cc +68 -0
- data/leveldb/util/arena.h +68 -0
- data/leveldb/util/arena_test.cc +68 -0
- data/leveldb/util/cache.cc +255 -0
- data/leveldb/util/cache_test.cc +169 -0
- data/leveldb/util/coding.cc +194 -0
- data/leveldb/util/coding.h +104 -0
- data/leveldb/util/coding_test.cc +173 -0
- data/leveldb/util/comparator.cc +72 -0
- data/leveldb/util/crc32c.cc +332 -0
- data/leveldb/util/crc32c.h +45 -0
- data/leveldb/util/crc32c_test.cc +72 -0
- data/leveldb/util/env.cc +77 -0
- data/leveldb/util/env_chromium.cc +612 -0
- data/leveldb/util/env_posix.cc +606 -0
- data/leveldb/util/env_test.cc +102 -0
- data/leveldb/util/hash.cc +45 -0
- data/leveldb/util/hash.h +19 -0
- data/leveldb/util/histogram.cc +128 -0
- data/leveldb/util/histogram.h +41 -0
- data/leveldb/util/logging.cc +81 -0
- data/leveldb/util/logging.h +47 -0
- data/leveldb/util/mutexlock.h +39 -0
- data/leveldb/util/options.cc +28 -0
- data/leveldb/util/random.h +59 -0
- data/leveldb/util/status.cc +75 -0
- data/leveldb/util/testharness.cc +65 -0
- data/leveldb/util/testharness.h +129 -0
- data/leveldb/util/testutil.cc +51 -0
- data/leveldb/util/testutil.h +53 -0
- data/lib/leveldb.rb +36 -0
- metadata +183 -0
@@ -0,0 +1,306 @@
|
|
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
|
+
// The representation of a DBImpl consists of a set of Versions. The
|
6
|
+
// newest version is called "current". Older versions may be kept
|
7
|
+
// around to provide a consistent view to live iterators.
|
8
|
+
//
|
9
|
+
// Each Version keeps track of a set of Table files per level. The
|
10
|
+
// entire set of versions is maintained in a VersionSet.
|
11
|
+
//
|
12
|
+
// Version,VersionSet are thread-compatible, but require external
|
13
|
+
// synchronization on all accesses.
|
14
|
+
|
15
|
+
#ifndef STORAGE_LEVELDB_DB_VERSION_SET_H_
|
16
|
+
#define STORAGE_LEVELDB_DB_VERSION_SET_H_
|
17
|
+
|
18
|
+
#include <map>
|
19
|
+
#include <set>
|
20
|
+
#include <vector>
|
21
|
+
#include "db/dbformat.h"
|
22
|
+
#include "db/version_edit.h"
|
23
|
+
#include "port/port.h"
|
24
|
+
|
25
|
+
namespace leveldb {
|
26
|
+
|
27
|
+
namespace log { class Writer; }
|
28
|
+
|
29
|
+
class Compaction;
|
30
|
+
class Iterator;
|
31
|
+
class MemTable;
|
32
|
+
class TableBuilder;
|
33
|
+
class TableCache;
|
34
|
+
class Version;
|
35
|
+
class VersionSet;
|
36
|
+
class WritableFile;
|
37
|
+
|
38
|
+
class Version {
|
39
|
+
public:
|
40
|
+
// Append to *iters a sequence of iterators that will
|
41
|
+
// yield the contents of this Version when merged together.
|
42
|
+
// REQUIRES: This version has been saved (see VersionSet::SaveTo)
|
43
|
+
void AddIterators(const ReadOptions&, std::vector<Iterator*>* iters);
|
44
|
+
|
45
|
+
// Reference count management (so Versions do not disappear out from
|
46
|
+
// under live iterators)
|
47
|
+
void Ref();
|
48
|
+
void Unref();
|
49
|
+
|
50
|
+
// Return a human readable string that describes this version's contents.
|
51
|
+
std::string DebugString() const;
|
52
|
+
|
53
|
+
private:
|
54
|
+
friend class Compaction;
|
55
|
+
friend class VersionSet;
|
56
|
+
|
57
|
+
class LevelFileNumIterator;
|
58
|
+
Iterator* NewConcatenatingIterator(const ReadOptions&, int level) const;
|
59
|
+
|
60
|
+
VersionSet* vset_; // VersionSet to which this Version belongs
|
61
|
+
Version* next_; // Next version in linked list
|
62
|
+
Version* prev_; // Previous version in linked list
|
63
|
+
int refs_; // Number of live refs to this version
|
64
|
+
|
65
|
+
// List of files per level
|
66
|
+
std::vector<FileMetaData*> files_[config::kNumLevels];
|
67
|
+
|
68
|
+
// Level that should be compacted next and its compaction score.
|
69
|
+
// Score < 1 means compaction is not strictly needed. These fields
|
70
|
+
// are initialized by Finalize().
|
71
|
+
double compaction_score_;
|
72
|
+
int compaction_level_;
|
73
|
+
|
74
|
+
explicit Version(VersionSet* vset)
|
75
|
+
: vset_(vset), next_(this), prev_(this), refs_(0),
|
76
|
+
compaction_score_(-1),
|
77
|
+
compaction_level_(-1) {
|
78
|
+
}
|
79
|
+
|
80
|
+
~Version();
|
81
|
+
|
82
|
+
// No copying allowed
|
83
|
+
Version(const Version&);
|
84
|
+
void operator=(const Version&);
|
85
|
+
};
|
86
|
+
|
87
|
+
class VersionSet {
|
88
|
+
public:
|
89
|
+
VersionSet(const std::string& dbname,
|
90
|
+
const Options* options,
|
91
|
+
TableCache* table_cache,
|
92
|
+
const InternalKeyComparator*);
|
93
|
+
~VersionSet();
|
94
|
+
|
95
|
+
// Apply *edit to the current version to form a new descriptor that
|
96
|
+
// is both saved to persistent state and installed as the new
|
97
|
+
// current version.
|
98
|
+
Status LogAndApply(VersionEdit* edit);
|
99
|
+
|
100
|
+
// Recover the last saved descriptor from persistent storage.
|
101
|
+
Status Recover();
|
102
|
+
|
103
|
+
// Save current contents to *log
|
104
|
+
Status WriteSnapshot(log::Writer* log);
|
105
|
+
|
106
|
+
// Return the current version.
|
107
|
+
Version* current() const { return current_; }
|
108
|
+
|
109
|
+
// Return the current manifest file number
|
110
|
+
uint64_t ManifestFileNumber() const { return manifest_file_number_; }
|
111
|
+
|
112
|
+
// Allocate and return a new file number
|
113
|
+
uint64_t NewFileNumber() { return next_file_number_++; }
|
114
|
+
|
115
|
+
// Return the number of Table files at the specified level.
|
116
|
+
int NumLevelFiles(int level) const;
|
117
|
+
|
118
|
+
// Return the combined file size of all files at the specified level.
|
119
|
+
int64_t NumLevelBytes(int level) const;
|
120
|
+
|
121
|
+
// Return the last sequence number.
|
122
|
+
uint64_t LastSequence() const { return last_sequence_; }
|
123
|
+
|
124
|
+
// Set the last sequence number to s.
|
125
|
+
void SetLastSequence(uint64_t s) {
|
126
|
+
assert(s >= last_sequence_);
|
127
|
+
last_sequence_ = s;
|
128
|
+
}
|
129
|
+
|
130
|
+
// Return the current log file number.
|
131
|
+
uint64_t LogNumber() const { return log_number_; }
|
132
|
+
|
133
|
+
// Return the log file number for the log file that is currently
|
134
|
+
// being compacted, or zero if there is no such log file.
|
135
|
+
uint64_t PrevLogNumber() const { return prev_log_number_; }
|
136
|
+
|
137
|
+
// Pick level and inputs for a new compaction.
|
138
|
+
// Returns NULL if there is no compaction to be done.
|
139
|
+
// Otherwise returns a pointer to a heap-allocated object that
|
140
|
+
// describes the compaction. Caller should delete the result.
|
141
|
+
Compaction* PickCompaction();
|
142
|
+
|
143
|
+
// Return a compaction object for compacting the range [begin,end] in
|
144
|
+
// the specified level. Returns NULL if there is nothing in that
|
145
|
+
// level that overlaps the specified range. Caller should delete
|
146
|
+
// the result.
|
147
|
+
Compaction* CompactRange(
|
148
|
+
int level,
|
149
|
+
const InternalKey& begin,
|
150
|
+
const InternalKey& end);
|
151
|
+
|
152
|
+
// Return the maximum overlapping data (in bytes) at next level for any
|
153
|
+
// file at a level >= 1.
|
154
|
+
int64_t MaxNextLevelOverlappingBytes();
|
155
|
+
|
156
|
+
// Create an iterator that reads over the compaction inputs for "*c".
|
157
|
+
// The caller should delete the iterator when no longer needed.
|
158
|
+
Iterator* MakeInputIterator(Compaction* c);
|
159
|
+
|
160
|
+
// Returns true iff some level needs a compaction.
|
161
|
+
bool NeedsCompaction() const { return current_->compaction_score_ >= 1; }
|
162
|
+
|
163
|
+
// Add all files listed in any live version to *live.
|
164
|
+
// May also mutate some internal state.
|
165
|
+
void AddLiveFiles(std::set<uint64_t>* live);
|
166
|
+
|
167
|
+
// Return the approximate offset in the database of the data for
|
168
|
+
// "key" as of version "v".
|
169
|
+
uint64_t ApproximateOffsetOf(Version* v, const InternalKey& key);
|
170
|
+
|
171
|
+
// Return a human-readable short (single-line) summary of the number
|
172
|
+
// of files per level. Uses *scratch as backing store.
|
173
|
+
struct LevelSummaryStorage {
|
174
|
+
char buffer[100];
|
175
|
+
};
|
176
|
+
const char* LevelSummary(LevelSummaryStorage* scratch) const;
|
177
|
+
|
178
|
+
private:
|
179
|
+
class Builder;
|
180
|
+
|
181
|
+
friend class Compaction;
|
182
|
+
friend class Version;
|
183
|
+
|
184
|
+
void Finalize(Version* v);
|
185
|
+
|
186
|
+
void GetOverlappingInputs(
|
187
|
+
int level,
|
188
|
+
const InternalKey& begin,
|
189
|
+
const InternalKey& end,
|
190
|
+
std::vector<FileMetaData*>* inputs);
|
191
|
+
|
192
|
+
void GetRange(const std::vector<FileMetaData*>& inputs,
|
193
|
+
InternalKey* smallest,
|
194
|
+
InternalKey* largest);
|
195
|
+
|
196
|
+
void GetRange2(const std::vector<FileMetaData*>& inputs1,
|
197
|
+
const std::vector<FileMetaData*>& inputs2,
|
198
|
+
InternalKey* smallest,
|
199
|
+
InternalKey* largest);
|
200
|
+
|
201
|
+
void SetupOtherInputs(Compaction* c);
|
202
|
+
|
203
|
+
void AppendVersion(Version* v);
|
204
|
+
|
205
|
+
Env* const env_;
|
206
|
+
const std::string dbname_;
|
207
|
+
const Options* const options_;
|
208
|
+
TableCache* const table_cache_;
|
209
|
+
const InternalKeyComparator icmp_;
|
210
|
+
uint64_t next_file_number_;
|
211
|
+
uint64_t manifest_file_number_;
|
212
|
+
uint64_t last_sequence_;
|
213
|
+
uint64_t log_number_;
|
214
|
+
uint64_t prev_log_number_; // 0 or backing store for memtable being compacted
|
215
|
+
|
216
|
+
// Opened lazily
|
217
|
+
WritableFile* descriptor_file_;
|
218
|
+
log::Writer* descriptor_log_;
|
219
|
+
Version dummy_versions_; // Head of circular doubly-linked list of versions.
|
220
|
+
Version* current_; // == dummy_versions_.prev_
|
221
|
+
|
222
|
+
// Per-level key at which the next compaction at that level should start.
|
223
|
+
// Either an empty string, or a valid InternalKey.
|
224
|
+
std::string compact_pointer_[config::kNumLevels];
|
225
|
+
|
226
|
+
// No copying allowed
|
227
|
+
VersionSet(const VersionSet&);
|
228
|
+
void operator=(const VersionSet&);
|
229
|
+
};
|
230
|
+
|
231
|
+
// A Compaction encapsulates information about a compaction.
|
232
|
+
class Compaction {
|
233
|
+
public:
|
234
|
+
~Compaction();
|
235
|
+
|
236
|
+
// Return the level that is being compacted. Inputs from "level"
|
237
|
+
// and "level+1" will be merged to produce a set of "level+1" files.
|
238
|
+
int level() const { return level_; }
|
239
|
+
|
240
|
+
// Return the object that holds the edits to the descriptor done
|
241
|
+
// by this compaction.
|
242
|
+
VersionEdit* edit() { return &edit_; }
|
243
|
+
|
244
|
+
// "which" must be either 0 or 1
|
245
|
+
int num_input_files(int which) const { return inputs_[which].size(); }
|
246
|
+
|
247
|
+
// Return the ith input file at "level()+which" ("which" must be 0 or 1).
|
248
|
+
FileMetaData* input(int which, int i) const { return inputs_[which][i]; }
|
249
|
+
|
250
|
+
// Maximum size of files to build during this compaction.
|
251
|
+
uint64_t MaxOutputFileSize() const { return max_output_file_size_; }
|
252
|
+
|
253
|
+
// Is this a trivial compaction that can be implemented by just
|
254
|
+
// moving a single input file to the next level (no merging or splitting)
|
255
|
+
bool IsTrivialMove() const;
|
256
|
+
|
257
|
+
// Add all inputs to this compaction as delete operations to *edit.
|
258
|
+
void AddInputDeletions(VersionEdit* edit);
|
259
|
+
|
260
|
+
// Returns true if the information we have available guarantees that
|
261
|
+
// the compaction is producing data in "level+1" for which no data exists
|
262
|
+
// in levels greater than "level+1".
|
263
|
+
bool IsBaseLevelForKey(const Slice& user_key);
|
264
|
+
|
265
|
+
// Returns true iff we should stop building the current output
|
266
|
+
// before processing "internal_key".
|
267
|
+
bool ShouldStopBefore(const Slice& internal_key);
|
268
|
+
|
269
|
+
// Release the input version for the compaction, once the compaction
|
270
|
+
// is successful.
|
271
|
+
void ReleaseInputs();
|
272
|
+
|
273
|
+
private:
|
274
|
+
friend class Version;
|
275
|
+
friend class VersionSet;
|
276
|
+
|
277
|
+
explicit Compaction(int level);
|
278
|
+
|
279
|
+
int level_;
|
280
|
+
uint64_t max_output_file_size_;
|
281
|
+
Version* input_version_;
|
282
|
+
VersionEdit edit_;
|
283
|
+
|
284
|
+
// Each compaction reads inputs from "level_" and "level_+1"
|
285
|
+
std::vector<FileMetaData*> inputs_[2]; // The two sets of inputs
|
286
|
+
|
287
|
+
// State used to check for number of of overlapping grandparent files
|
288
|
+
// (parent == level_ + 1, grandparent == level_ + 2)
|
289
|
+
std::vector<FileMetaData*> grandparents_;
|
290
|
+
size_t grandparent_index_; // Index in grandparent_starts_
|
291
|
+
bool seen_key_; // Some output key has been seen
|
292
|
+
int64_t overlapped_bytes_; // Bytes of overlap between current output
|
293
|
+
// and grandparent files
|
294
|
+
|
295
|
+
// State for implementing IsBaseLevelForKey
|
296
|
+
|
297
|
+
// level_ptrs_ holds indices into input_version_->levels_: our state
|
298
|
+
// is that we are positioned at one of the file ranges for each
|
299
|
+
// higher level than the ones involved in this compaction (i.e. for
|
300
|
+
// all L >= level_ + 2).
|
301
|
+
size_t level_ptrs_[config::kNumLevels];
|
302
|
+
};
|
303
|
+
|
304
|
+
}
|
305
|
+
|
306
|
+
#endif // STORAGE_LEVELDB_DB_VERSION_SET_H_
|
@@ -0,0 +1,138 @@
|
|
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
|
+
}
|
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
|
+
}
|
@@ -0,0 +1,45 @@
|
|
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
|
+
#ifndef STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_
|
6
|
+
#define STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_
|
7
|
+
|
8
|
+
#include "leveldb/write_batch.h"
|
9
|
+
|
10
|
+
namespace leveldb {
|
11
|
+
|
12
|
+
// WriteBatchInternal provides static methods for manipulating a
|
13
|
+
// WriteBatch that we don't want in the public WriteBatch interface.
|
14
|
+
class WriteBatchInternal {
|
15
|
+
public:
|
16
|
+
// Return the number of entries in the batch.
|
17
|
+
static int Count(const WriteBatch* batch);
|
18
|
+
|
19
|
+
// Set the count for the number of entries in the batch.
|
20
|
+
static void SetCount(WriteBatch* batch, int n);
|
21
|
+
|
22
|
+
// Return the seqeunce number for the start of this batch.
|
23
|
+
static SequenceNumber Sequence(const WriteBatch* batch);
|
24
|
+
|
25
|
+
// Store the specified number as the seqeunce number for the start of
|
26
|
+
// this batch.
|
27
|
+
static void SetSequence(WriteBatch* batch, SequenceNumber seq);
|
28
|
+
|
29
|
+
static Slice Contents(const WriteBatch* batch) {
|
30
|
+
return Slice(batch->rep_);
|
31
|
+
}
|
32
|
+
|
33
|
+
static size_t ByteSize(const WriteBatch* batch) {
|
34
|
+
return batch->rep_.size();
|
35
|
+
}
|
36
|
+
|
37
|
+
static void SetContents(WriteBatch* batch, const Slice& contents);
|
38
|
+
|
39
|
+
static Status InsertInto(const WriteBatch* batch, MemTable* memtable);
|
40
|
+
};
|
41
|
+
|
42
|
+
}
|
43
|
+
|
44
|
+
|
45
|
+
#endif // STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_
|