leveldb-ruby 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,66 @@
|
|
|
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_SNAPSHOT_H_
|
|
6
|
+
#define STORAGE_LEVELDB_DB_SNAPSHOT_H_
|
|
7
|
+
|
|
8
|
+
#include "leveldb/db.h"
|
|
9
|
+
|
|
10
|
+
namespace leveldb {
|
|
11
|
+
|
|
12
|
+
class SnapshotList;
|
|
13
|
+
|
|
14
|
+
// Snapshots are kept in a doubly-linked list in the DB.
|
|
15
|
+
// Each SnapshotImpl corresponds to a particular sequence number.
|
|
16
|
+
class SnapshotImpl : public Snapshot {
|
|
17
|
+
public:
|
|
18
|
+
SequenceNumber number_; // const after creation
|
|
19
|
+
|
|
20
|
+
private:
|
|
21
|
+
friend class SnapshotList;
|
|
22
|
+
|
|
23
|
+
// SnapshotImpl is kept in a doubly-linked circular list
|
|
24
|
+
SnapshotImpl* prev_;
|
|
25
|
+
SnapshotImpl* next_;
|
|
26
|
+
|
|
27
|
+
SnapshotList* list_; // just for sanity checks
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
class SnapshotList {
|
|
31
|
+
public:
|
|
32
|
+
SnapshotList() {
|
|
33
|
+
list_.prev_ = &list_;
|
|
34
|
+
list_.next_ = &list_;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
bool empty() const { return list_.next_ == &list_; }
|
|
38
|
+
SnapshotImpl* oldest() const { assert(!empty()); return list_.next_; }
|
|
39
|
+
SnapshotImpl* newest() const { assert(!empty()); return list_.prev_; }
|
|
40
|
+
|
|
41
|
+
const SnapshotImpl* New(SequenceNumber seq) {
|
|
42
|
+
SnapshotImpl* s = new SnapshotImpl;
|
|
43
|
+
s->number_ = seq;
|
|
44
|
+
s->list_ = this;
|
|
45
|
+
s->next_ = &list_;
|
|
46
|
+
s->prev_ = list_.prev_;
|
|
47
|
+
s->prev_->next_ = s;
|
|
48
|
+
s->next_->prev_ = s;
|
|
49
|
+
return s;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void Delete(const SnapshotImpl* s) {
|
|
53
|
+
assert(s->list_ == this);
|
|
54
|
+
s->prev_->next_ = s->next_;
|
|
55
|
+
s->next_->prev_ = s->prev_;
|
|
56
|
+
delete s;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private:
|
|
60
|
+
// Dummy head of doubly-linked list of snapshots
|
|
61
|
+
SnapshotImpl list_;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
#include "db/table_cache.h"
|
|
6
|
+
|
|
7
|
+
#include "db/filename.h"
|
|
8
|
+
#include "leveldb/env.h"
|
|
9
|
+
#include "leveldb/table.h"
|
|
10
|
+
#include "util/coding.h"
|
|
11
|
+
|
|
12
|
+
namespace leveldb {
|
|
13
|
+
|
|
14
|
+
struct TableAndFile {
|
|
15
|
+
RandomAccessFile* file;
|
|
16
|
+
Table* table;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
static void DeleteEntry(const Slice& key, void* value) {
|
|
20
|
+
TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);
|
|
21
|
+
delete tf->table;
|
|
22
|
+
delete tf->file;
|
|
23
|
+
delete tf;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static void UnrefEntry(void* arg1, void* arg2) {
|
|
27
|
+
Cache* cache = reinterpret_cast<Cache*>(arg1);
|
|
28
|
+
Cache::Handle* h = reinterpret_cast<Cache::Handle*>(arg2);
|
|
29
|
+
cache->Release(h);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
TableCache::TableCache(const std::string& dbname,
|
|
33
|
+
const Options* options,
|
|
34
|
+
int entries)
|
|
35
|
+
: env_(options->env),
|
|
36
|
+
dbname_(dbname),
|
|
37
|
+
options_(options),
|
|
38
|
+
cache_(NewLRUCache(entries)) {
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
TableCache::~TableCache() {
|
|
42
|
+
delete cache_;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Iterator* TableCache::NewIterator(const ReadOptions& options,
|
|
46
|
+
uint64_t file_number,
|
|
47
|
+
uint64_t file_size,
|
|
48
|
+
Table** tableptr) {
|
|
49
|
+
if (tableptr != NULL) {
|
|
50
|
+
*tableptr = NULL;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
char buf[sizeof(file_number)];
|
|
54
|
+
EncodeFixed64(buf, file_number);
|
|
55
|
+
Slice key(buf, sizeof(buf));
|
|
56
|
+
Cache::Handle* handle = cache_->Lookup(key);
|
|
57
|
+
if (handle == NULL) {
|
|
58
|
+
std::string fname = TableFileName(dbname_, file_number);
|
|
59
|
+
RandomAccessFile* file = NULL;
|
|
60
|
+
Table* table = NULL;
|
|
61
|
+
Status s = env_->NewRandomAccessFile(fname, &file);
|
|
62
|
+
if (s.ok()) {
|
|
63
|
+
s = Table::Open(*options_, file, file_size, &table);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!s.ok()) {
|
|
67
|
+
assert(table == NULL);
|
|
68
|
+
delete file;
|
|
69
|
+
// We do not cache error results so that if the error is transient,
|
|
70
|
+
// or somebody repairs the file, we recover automatically.
|
|
71
|
+
return NewErrorIterator(s);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
TableAndFile* tf = new TableAndFile;
|
|
75
|
+
tf->file = file;
|
|
76
|
+
tf->table = table;
|
|
77
|
+
handle = cache_->Insert(key, tf, 1, &DeleteEntry);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
Table* table = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
|
|
81
|
+
Iterator* result = table->NewIterator(options);
|
|
82
|
+
result->RegisterCleanup(&UnrefEntry, cache_, handle);
|
|
83
|
+
if (tableptr != NULL) {
|
|
84
|
+
*tableptr = table;
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void TableCache::Evict(uint64_t file_number) {
|
|
90
|
+
char buf[sizeof(file_number)];
|
|
91
|
+
EncodeFixed64(buf, file_number);
|
|
92
|
+
cache_->Erase(Slice(buf, sizeof(buf)));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
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
|
+
// Thread-safe (provides internal synchronization)
|
|
6
|
+
|
|
7
|
+
#ifndef STORAGE_LEVELDB_DB_TABLE_CACHE_H_
|
|
8
|
+
#define STORAGE_LEVELDB_DB_TABLE_CACHE_H_
|
|
9
|
+
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <stdint.h>
|
|
12
|
+
#include "db/dbformat.h"
|
|
13
|
+
#include "leveldb/cache.h"
|
|
14
|
+
#include "leveldb/table.h"
|
|
15
|
+
#include "port/port.h"
|
|
16
|
+
|
|
17
|
+
namespace leveldb {
|
|
18
|
+
|
|
19
|
+
class Env;
|
|
20
|
+
|
|
21
|
+
class TableCache {
|
|
22
|
+
public:
|
|
23
|
+
TableCache(const std::string& dbname, const Options* options, int entries);
|
|
24
|
+
~TableCache();
|
|
25
|
+
|
|
26
|
+
// Return an iterator for the specified file number (the corresponding
|
|
27
|
+
// file length must be exactly "file_size" bytes). If "tableptr" is
|
|
28
|
+
// non-NULL, also sets "*tableptr" to point to the Table object
|
|
29
|
+
// underlying the returned iterator, or NULL if no Table object underlies
|
|
30
|
+
// the returned iterator. The returned "*tableptr" object is owned by
|
|
31
|
+
// the cache and should not be deleted, and is valid for as long as the
|
|
32
|
+
// returned iterator is live.
|
|
33
|
+
Iterator* NewIterator(const ReadOptions& options,
|
|
34
|
+
uint64_t file_number,
|
|
35
|
+
uint64_t file_size,
|
|
36
|
+
Table** tableptr = NULL);
|
|
37
|
+
|
|
38
|
+
// Evict any entry for the specified file number
|
|
39
|
+
void Evict(uint64_t file_number);
|
|
40
|
+
|
|
41
|
+
private:
|
|
42
|
+
Env* const env_;
|
|
43
|
+
const std::string dbname_;
|
|
44
|
+
const Options* options_;
|
|
45
|
+
Cache* cache_;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#endif // STORAGE_LEVELDB_DB_TABLE_CACHE_H_
|
|
@@ -0,0 +1,268 @@
|
|
|
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
|
+
#include "db/version_edit.h"
|
|
6
|
+
|
|
7
|
+
#include "db/version_set.h"
|
|
8
|
+
#include "util/coding.h"
|
|
9
|
+
|
|
10
|
+
namespace leveldb {
|
|
11
|
+
|
|
12
|
+
// Tag numbers for serialized VersionEdit. These numbers are written to
|
|
13
|
+
// disk and should not be changed.
|
|
14
|
+
enum Tag {
|
|
15
|
+
kComparator = 1,
|
|
16
|
+
kLogNumber = 2,
|
|
17
|
+
kNextFileNumber = 3,
|
|
18
|
+
kLastSequence = 4,
|
|
19
|
+
kCompactPointer = 5,
|
|
20
|
+
kDeletedFile = 6,
|
|
21
|
+
kNewFile = 7,
|
|
22
|
+
// 8 was used for large value refs
|
|
23
|
+
kPrevLogNumber = 9,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
void VersionEdit::Clear() {
|
|
27
|
+
comparator_.clear();
|
|
28
|
+
log_number_ = 0;
|
|
29
|
+
prev_log_number_ = 0;
|
|
30
|
+
last_sequence_ = 0;
|
|
31
|
+
next_file_number_ = 0;
|
|
32
|
+
has_comparator_ = false;
|
|
33
|
+
has_log_number_ = false;
|
|
34
|
+
has_prev_log_number_ = false;
|
|
35
|
+
has_next_file_number_ = false;
|
|
36
|
+
has_last_sequence_ = false;
|
|
37
|
+
deleted_files_.clear();
|
|
38
|
+
new_files_.clear();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
void VersionEdit::EncodeTo(std::string* dst) const {
|
|
42
|
+
if (has_comparator_) {
|
|
43
|
+
PutVarint32(dst, kComparator);
|
|
44
|
+
PutLengthPrefixedSlice(dst, comparator_);
|
|
45
|
+
}
|
|
46
|
+
if (has_log_number_) {
|
|
47
|
+
PutVarint32(dst, kLogNumber);
|
|
48
|
+
PutVarint64(dst, log_number_);
|
|
49
|
+
}
|
|
50
|
+
if (has_prev_log_number_) {
|
|
51
|
+
PutVarint32(dst, kPrevLogNumber);
|
|
52
|
+
PutVarint64(dst, prev_log_number_);
|
|
53
|
+
}
|
|
54
|
+
if (has_next_file_number_) {
|
|
55
|
+
PutVarint32(dst, kNextFileNumber);
|
|
56
|
+
PutVarint64(dst, next_file_number_);
|
|
57
|
+
}
|
|
58
|
+
if (has_last_sequence_) {
|
|
59
|
+
PutVarint32(dst, kLastSequence);
|
|
60
|
+
PutVarint64(dst, last_sequence_);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (size_t i = 0; i < compact_pointers_.size(); i++) {
|
|
64
|
+
PutVarint32(dst, kCompactPointer);
|
|
65
|
+
PutVarint32(dst, compact_pointers_[i].first); // level
|
|
66
|
+
PutLengthPrefixedSlice(dst, compact_pointers_[i].second.Encode());
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
|
|
70
|
+
iter != deleted_files_.end();
|
|
71
|
+
++iter) {
|
|
72
|
+
PutVarint32(dst, kDeletedFile);
|
|
73
|
+
PutVarint32(dst, iter->first); // level
|
|
74
|
+
PutVarint64(dst, iter->second); // file number
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
for (size_t i = 0; i < new_files_.size(); i++) {
|
|
78
|
+
const FileMetaData& f = new_files_[i].second;
|
|
79
|
+
PutVarint32(dst, kNewFile);
|
|
80
|
+
PutVarint32(dst, new_files_[i].first); // level
|
|
81
|
+
PutVarint64(dst, f.number);
|
|
82
|
+
PutVarint64(dst, f.file_size);
|
|
83
|
+
PutLengthPrefixedSlice(dst, f.smallest.Encode());
|
|
84
|
+
PutLengthPrefixedSlice(dst, f.largest.Encode());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static bool GetInternalKey(Slice* input, InternalKey* dst) {
|
|
89
|
+
Slice str;
|
|
90
|
+
if (GetLengthPrefixedSlice(input, &str)) {
|
|
91
|
+
dst->DecodeFrom(str);
|
|
92
|
+
return true;
|
|
93
|
+
} else {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static bool GetLevel(Slice* input, int* level) {
|
|
99
|
+
uint32_t v;
|
|
100
|
+
if (GetVarint32(input, &v) &&
|
|
101
|
+
v < config::kNumLevels) {
|
|
102
|
+
*level = v;
|
|
103
|
+
return true;
|
|
104
|
+
} else {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
Status VersionEdit::DecodeFrom(const Slice& src) {
|
|
110
|
+
Clear();
|
|
111
|
+
Slice input = src;
|
|
112
|
+
const char* msg = NULL;
|
|
113
|
+
uint32_t tag;
|
|
114
|
+
|
|
115
|
+
// Temporary storage for parsing
|
|
116
|
+
int level;
|
|
117
|
+
uint64_t number;
|
|
118
|
+
FileMetaData f;
|
|
119
|
+
Slice str;
|
|
120
|
+
InternalKey key;
|
|
121
|
+
|
|
122
|
+
while (msg == NULL && GetVarint32(&input, &tag)) {
|
|
123
|
+
switch (tag) {
|
|
124
|
+
case kComparator:
|
|
125
|
+
if (GetLengthPrefixedSlice(&input, &str)) {
|
|
126
|
+
comparator_ = str.ToString();
|
|
127
|
+
has_comparator_ = true;
|
|
128
|
+
} else {
|
|
129
|
+
msg = "comparator name";
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
|
|
133
|
+
case kLogNumber:
|
|
134
|
+
if (GetVarint64(&input, &log_number_)) {
|
|
135
|
+
has_log_number_ = true;
|
|
136
|
+
} else {
|
|
137
|
+
msg = "log number";
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
|
|
141
|
+
case kPrevLogNumber:
|
|
142
|
+
if (GetVarint64(&input, &prev_log_number_)) {
|
|
143
|
+
has_prev_log_number_ = true;
|
|
144
|
+
} else {
|
|
145
|
+
msg = "previous log number";
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
|
|
149
|
+
case kNextFileNumber:
|
|
150
|
+
if (GetVarint64(&input, &next_file_number_)) {
|
|
151
|
+
has_next_file_number_ = true;
|
|
152
|
+
} else {
|
|
153
|
+
msg = "next file number";
|
|
154
|
+
}
|
|
155
|
+
break;
|
|
156
|
+
|
|
157
|
+
case kLastSequence:
|
|
158
|
+
if (GetVarint64(&input, &last_sequence_)) {
|
|
159
|
+
has_last_sequence_ = true;
|
|
160
|
+
} else {
|
|
161
|
+
msg = "last sequence number";
|
|
162
|
+
}
|
|
163
|
+
break;
|
|
164
|
+
|
|
165
|
+
case kCompactPointer:
|
|
166
|
+
if (GetLevel(&input, &level) &&
|
|
167
|
+
GetInternalKey(&input, &key)) {
|
|
168
|
+
compact_pointers_.push_back(std::make_pair(level, key));
|
|
169
|
+
} else {
|
|
170
|
+
msg = "compaction pointer";
|
|
171
|
+
}
|
|
172
|
+
break;
|
|
173
|
+
|
|
174
|
+
case kDeletedFile:
|
|
175
|
+
if (GetLevel(&input, &level) &&
|
|
176
|
+
GetVarint64(&input, &number)) {
|
|
177
|
+
deleted_files_.insert(std::make_pair(level, number));
|
|
178
|
+
} else {
|
|
179
|
+
msg = "deleted file";
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
|
|
183
|
+
case kNewFile:
|
|
184
|
+
if (GetLevel(&input, &level) &&
|
|
185
|
+
GetVarint64(&input, &f.number) &&
|
|
186
|
+
GetVarint64(&input, &f.file_size) &&
|
|
187
|
+
GetInternalKey(&input, &f.smallest) &&
|
|
188
|
+
GetInternalKey(&input, &f.largest)) {
|
|
189
|
+
new_files_.push_back(std::make_pair(level, f));
|
|
190
|
+
} else {
|
|
191
|
+
msg = "new-file entry";
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
|
|
195
|
+
default:
|
|
196
|
+
msg = "unknown tag";
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (msg == NULL && !input.empty()) {
|
|
202
|
+
msg = "invalid tag";
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
Status result;
|
|
206
|
+
if (msg != NULL) {
|
|
207
|
+
result = Status::Corruption("VersionEdit", msg);
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
std::string VersionEdit::DebugString() const {
|
|
213
|
+
std::string r;
|
|
214
|
+
r.append("VersionEdit {");
|
|
215
|
+
if (has_comparator_) {
|
|
216
|
+
r.append("\n Comparator: ");
|
|
217
|
+
r.append(comparator_);
|
|
218
|
+
}
|
|
219
|
+
if (has_log_number_) {
|
|
220
|
+
r.append("\n LogNumber: ");
|
|
221
|
+
AppendNumberTo(&r, log_number_);
|
|
222
|
+
}
|
|
223
|
+
if (has_prev_log_number_) {
|
|
224
|
+
r.append("\n PrevLogNumber: ");
|
|
225
|
+
AppendNumberTo(&r, prev_log_number_);
|
|
226
|
+
}
|
|
227
|
+
if (has_next_file_number_) {
|
|
228
|
+
r.append("\n NextFile: ");
|
|
229
|
+
AppendNumberTo(&r, next_file_number_);
|
|
230
|
+
}
|
|
231
|
+
if (has_last_sequence_) {
|
|
232
|
+
r.append("\n LastSeq: ");
|
|
233
|
+
AppendNumberTo(&r, last_sequence_);
|
|
234
|
+
}
|
|
235
|
+
for (size_t i = 0; i < compact_pointers_.size(); i++) {
|
|
236
|
+
r.append("\n CompactPointer: ");
|
|
237
|
+
AppendNumberTo(&r, compact_pointers_[i].first);
|
|
238
|
+
r.append(" '");
|
|
239
|
+
AppendEscapedStringTo(&r, compact_pointers_[i].second.Encode());
|
|
240
|
+
r.append("'");
|
|
241
|
+
}
|
|
242
|
+
for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
|
|
243
|
+
iter != deleted_files_.end();
|
|
244
|
+
++iter) {
|
|
245
|
+
r.append("\n DeleteFile: ");
|
|
246
|
+
AppendNumberTo(&r, iter->first);
|
|
247
|
+
r.append(" ");
|
|
248
|
+
AppendNumberTo(&r, iter->second);
|
|
249
|
+
}
|
|
250
|
+
for (size_t i = 0; i < new_files_.size(); i++) {
|
|
251
|
+
const FileMetaData& f = new_files_[i].second;
|
|
252
|
+
r.append("\n AddFile: ");
|
|
253
|
+
AppendNumberTo(&r, new_files_[i].first);
|
|
254
|
+
r.append(" ");
|
|
255
|
+
AppendNumberTo(&r, f.number);
|
|
256
|
+
r.append(" ");
|
|
257
|
+
AppendNumberTo(&r, f.file_size);
|
|
258
|
+
r.append(" '");
|
|
259
|
+
AppendEscapedStringTo(&r, f.smallest.Encode());
|
|
260
|
+
r.append("' .. '");
|
|
261
|
+
AppendEscapedStringTo(&r, f.largest.Encode());
|
|
262
|
+
r.append("'");
|
|
263
|
+
}
|
|
264
|
+
r.append("\n}\n");
|
|
265
|
+
return r;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
}
|