leveldb-ruby 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/README +17 -0
  2. data/ext/leveldb/extconf.rb +10 -0
  3. data/ext/leveldb/leveldb.cc +181 -0
  4. data/leveldb/Makefile +172 -0
  5. data/leveldb/db/builder.cc +90 -0
  6. data/leveldb/db/builder.h +36 -0
  7. data/leveldb/db/corruption_test.cc +354 -0
  8. data/leveldb/db/db_bench.cc +677 -0
  9. data/leveldb/db/db_impl.cc +1236 -0
  10. data/leveldb/db/db_impl.h +180 -0
  11. data/leveldb/db/db_iter.cc +298 -0
  12. data/leveldb/db/db_iter.h +26 -0
  13. data/leveldb/db/db_test.cc +1192 -0
  14. data/leveldb/db/dbformat.cc +87 -0
  15. data/leveldb/db/dbformat.h +165 -0
  16. data/leveldb/db/dbformat_test.cc +112 -0
  17. data/leveldb/db/filename.cc +135 -0
  18. data/leveldb/db/filename.h +80 -0
  19. data/leveldb/db/filename_test.cc +122 -0
  20. data/leveldb/db/log_format.h +35 -0
  21. data/leveldb/db/log_reader.cc +254 -0
  22. data/leveldb/db/log_reader.h +108 -0
  23. data/leveldb/db/log_test.cc +500 -0
  24. data/leveldb/db/log_writer.cc +103 -0
  25. data/leveldb/db/log_writer.h +48 -0
  26. data/leveldb/db/memtable.cc +108 -0
  27. data/leveldb/db/memtable.h +85 -0
  28. data/leveldb/db/repair.cc +384 -0
  29. data/leveldb/db/skiplist.h +378 -0
  30. data/leveldb/db/skiplist_test.cc +378 -0
  31. data/leveldb/db/snapshot.h +66 -0
  32. data/leveldb/db/table_cache.cc +95 -0
  33. data/leveldb/db/table_cache.h +50 -0
  34. data/leveldb/db/version_edit.cc +268 -0
  35. data/leveldb/db/version_edit.h +106 -0
  36. data/leveldb/db/version_edit_test.cc +46 -0
  37. data/leveldb/db/version_set.cc +1060 -0
  38. data/leveldb/db/version_set.h +306 -0
  39. data/leveldb/db/write_batch.cc +138 -0
  40. data/leveldb/db/write_batch_internal.h +45 -0
  41. data/leveldb/db/write_batch_test.cc +89 -0
  42. data/leveldb/include/leveldb/cache.h +99 -0
  43. data/leveldb/include/leveldb/comparator.h +63 -0
  44. data/leveldb/include/leveldb/db.h +148 -0
  45. data/leveldb/include/leveldb/env.h +302 -0
  46. data/leveldb/include/leveldb/iterator.h +100 -0
  47. data/leveldb/include/leveldb/options.h +198 -0
  48. data/leveldb/include/leveldb/slice.h +109 -0
  49. data/leveldb/include/leveldb/status.h +100 -0
  50. data/leveldb/include/leveldb/table.h +70 -0
  51. data/leveldb/include/leveldb/table_builder.h +91 -0
  52. data/leveldb/include/leveldb/write_batch.h +64 -0
  53. data/leveldb/port/port.h +23 -0
  54. data/leveldb/port/port_android.cc +64 -0
  55. data/leveldb/port/port_android.h +150 -0
  56. data/leveldb/port/port_chromium.cc +80 -0
  57. data/leveldb/port/port_chromium.h +97 -0
  58. data/leveldb/port/port_example.h +115 -0
  59. data/leveldb/port/port_osx.cc +50 -0
  60. data/leveldb/port/port_osx.h +125 -0
  61. data/leveldb/port/port_posix.cc +50 -0
  62. data/leveldb/port/port_posix.h +94 -0
  63. data/leveldb/port/sha1_portable.cc +298 -0
  64. data/leveldb/port/sha1_portable.h +25 -0
  65. data/leveldb/port/sha1_test.cc +39 -0
  66. data/leveldb/port/win/stdint.h +24 -0
  67. data/leveldb/table/block.cc +263 -0
  68. data/leveldb/table/block.h +43 -0
  69. data/leveldb/table/block_builder.cc +109 -0
  70. data/leveldb/table/block_builder.h +57 -0
  71. data/leveldb/table/format.cc +131 -0
  72. data/leveldb/table/format.h +103 -0
  73. data/leveldb/table/iterator.cc +67 -0
  74. data/leveldb/table/iterator_wrapper.h +63 -0
  75. data/leveldb/table/merger.cc +197 -0
  76. data/leveldb/table/merger.h +26 -0
  77. data/leveldb/table/table.cc +175 -0
  78. data/leveldb/table/table_builder.cc +227 -0
  79. data/leveldb/table/table_test.cc +845 -0
  80. data/leveldb/table/two_level_iterator.cc +182 -0
  81. data/leveldb/table/two_level_iterator.h +34 -0
  82. data/leveldb/util/arena.cc +68 -0
  83. data/leveldb/util/arena.h +68 -0
  84. data/leveldb/util/arena_test.cc +68 -0
  85. data/leveldb/util/cache.cc +255 -0
  86. data/leveldb/util/cache_test.cc +169 -0
  87. data/leveldb/util/coding.cc +194 -0
  88. data/leveldb/util/coding.h +104 -0
  89. data/leveldb/util/coding_test.cc +173 -0
  90. data/leveldb/util/comparator.cc +72 -0
  91. data/leveldb/util/crc32c.cc +332 -0
  92. data/leveldb/util/crc32c.h +45 -0
  93. data/leveldb/util/crc32c_test.cc +72 -0
  94. data/leveldb/util/env.cc +77 -0
  95. data/leveldb/util/env_chromium.cc +612 -0
  96. data/leveldb/util/env_posix.cc +606 -0
  97. data/leveldb/util/env_test.cc +102 -0
  98. data/leveldb/util/hash.cc +45 -0
  99. data/leveldb/util/hash.h +19 -0
  100. data/leveldb/util/histogram.cc +128 -0
  101. data/leveldb/util/histogram.h +41 -0
  102. data/leveldb/util/logging.cc +81 -0
  103. data/leveldb/util/logging.h +47 -0
  104. data/leveldb/util/mutexlock.h +39 -0
  105. data/leveldb/util/options.cc +28 -0
  106. data/leveldb/util/random.h +59 -0
  107. data/leveldb/util/status.cc +75 -0
  108. data/leveldb/util/testharness.cc +65 -0
  109. data/leveldb/util/testharness.h +129 -0
  110. data/leveldb/util/testutil.cc +51 -0
  111. data/leveldb/util/testutil.h +53 -0
  112. data/lib/leveldb.rb +36 -0
  113. metadata +183 -0
@@ -0,0 +1,180 @@
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_DB_IMPL_H_
6
+ #define STORAGE_LEVELDB_DB_DB_IMPL_H_
7
+
8
+ #include <set>
9
+ #include "db/dbformat.h"
10
+ #include "db/log_writer.h"
11
+ #include "db/snapshot.h"
12
+ #include "leveldb/db.h"
13
+ #include "leveldb/env.h"
14
+ #include "port/port.h"
15
+
16
+ namespace leveldb {
17
+
18
+ class MemTable;
19
+ class TableCache;
20
+ class Version;
21
+ class VersionEdit;
22
+ class VersionSet;
23
+
24
+ class DBImpl : public DB {
25
+ public:
26
+ DBImpl(const Options& options, const std::string& dbname);
27
+ virtual ~DBImpl();
28
+
29
+ // Implementations of the DB interface
30
+ virtual Status Put(const WriteOptions&, const Slice& key, const Slice& value);
31
+ virtual Status Delete(const WriteOptions&, const Slice& key);
32
+ virtual Status Write(const WriteOptions& options, WriteBatch* updates);
33
+ virtual Status Get(const ReadOptions& options,
34
+ const Slice& key,
35
+ std::string* value);
36
+ virtual Iterator* NewIterator(const ReadOptions&);
37
+ virtual const Snapshot* GetSnapshot();
38
+ virtual void ReleaseSnapshot(const Snapshot* snapshot);
39
+ virtual bool GetProperty(const Slice& property, std::string* value);
40
+ virtual void GetApproximateSizes(const Range* range, int n, uint64_t* sizes);
41
+
42
+ // Extra methods (for testing) that are not in the public DB interface
43
+
44
+ // Compact any files in the named level that overlap [begin,end]
45
+ void TEST_CompactRange(
46
+ int level,
47
+ const std::string& begin,
48
+ const std::string& end);
49
+
50
+ // Force current memtable contents to be compacted.
51
+ Status TEST_CompactMemTable();
52
+
53
+ // Return an internal iterator over the current state of the database.
54
+ // The keys of this iterator are internal keys (see format.h).
55
+ // The returned iterator should be deleted when no longer needed.
56
+ Iterator* TEST_NewInternalIterator();
57
+
58
+ // Return the maximum overlapping data (in bytes) at next level for any
59
+ // file at a level >= 1.
60
+ int64_t TEST_MaxNextLevelOverlappingBytes();
61
+
62
+ private:
63
+ friend class DB;
64
+
65
+ Iterator* NewInternalIterator(const ReadOptions&,
66
+ SequenceNumber* latest_snapshot);
67
+
68
+ Status NewDB();
69
+
70
+ // Recover the descriptor from persistent storage. May do a significant
71
+ // amount of work to recover recently logged updates. Any changes to
72
+ // be made to the descriptor are added to *edit.
73
+ Status Recover(VersionEdit* edit);
74
+
75
+ void MaybeIgnoreError(Status* s) const;
76
+
77
+ // Delete any unneeded files and stale in-memory entries.
78
+ void DeleteObsoleteFiles();
79
+
80
+ // Compact the in-memory write buffer to disk. Switches to a new
81
+ // log-file/memtable and writes a new descriptor iff successful.
82
+ Status CompactMemTable();
83
+
84
+ Status RecoverLogFile(uint64_t log_number,
85
+ VersionEdit* edit,
86
+ SequenceNumber* max_sequence);
87
+
88
+ Status WriteLevel0Table(MemTable* mem, VersionEdit* edit);
89
+
90
+ Status MakeRoomForWrite(bool force /* compact even if there is room? */);
91
+
92
+ struct CompactionState;
93
+
94
+ void MaybeScheduleCompaction();
95
+ static void BGWork(void* db);
96
+ void BackgroundCall();
97
+ void BackgroundCompaction();
98
+ void CleanupCompaction(CompactionState* compact);
99
+ Status DoCompactionWork(CompactionState* compact);
100
+
101
+ Status OpenCompactionOutputFile(CompactionState* compact);
102
+ Status FinishCompactionOutputFile(CompactionState* compact, Iterator* input);
103
+ Status InstallCompactionResults(CompactionState* compact);
104
+
105
+ // Constant after construction
106
+ Env* const env_;
107
+ const InternalKeyComparator internal_comparator_;
108
+ const Options options_; // options_.comparator == &internal_comparator_
109
+ bool owns_info_log_;
110
+ bool owns_cache_;
111
+ const std::string dbname_;
112
+
113
+ // table_cache_ provides its own synchronization
114
+ TableCache* table_cache_;
115
+
116
+ // Lock over the persistent DB state. Non-NULL iff successfully acquired.
117
+ FileLock* db_lock_;
118
+
119
+ // State below is protected by mutex_
120
+ port::Mutex mutex_;
121
+ port::AtomicPointer shutting_down_;
122
+ port::CondVar bg_cv_; // Signalled when !bg_compaction_scheduled_
123
+ port::CondVar compacting_cv_; // Signalled when !compacting_
124
+ MemTable* mem_;
125
+ MemTable* imm_; // Memtable being compacted
126
+ port::AtomicPointer has_imm_; // So bg thread can detect non-NULL imm_
127
+ WritableFile* logfile_;
128
+ log::Writer* log_;
129
+ SnapshotList snapshots_;
130
+
131
+ // Set of table files to protect from deletion because they are
132
+ // part of ongoing compactions.
133
+ std::set<uint64_t> pending_outputs_;
134
+
135
+ // Has a background compaction been scheduled or is running?
136
+ bool bg_compaction_scheduled_;
137
+
138
+ // Is there a compaction running?
139
+ bool compacting_;
140
+
141
+ VersionSet* versions_;
142
+
143
+ // Have we encountered a background error in paranoid mode?
144
+ Status bg_error_;
145
+
146
+ // Per level compaction stats. stats_[level] stores the stats for
147
+ // compactions that produced data for the specified "level".
148
+ struct CompactionStats {
149
+ int64_t micros;
150
+ int64_t bytes_read;
151
+ int64_t bytes_written;
152
+
153
+ CompactionStats() : micros(0), bytes_read(0), bytes_written(0) { }
154
+
155
+ void Add(const CompactionStats& c) {
156
+ this->micros += c.micros;
157
+ this->bytes_read += c.bytes_read;
158
+ this->bytes_written += c.bytes_written;
159
+ }
160
+ };
161
+ CompactionStats stats_[config::kNumLevels];
162
+
163
+ // No copying allowed
164
+ DBImpl(const DBImpl&);
165
+ void operator=(const DBImpl&);
166
+
167
+ const Comparator* user_comparator() const {
168
+ return internal_comparator_.user_comparator();
169
+ }
170
+ };
171
+
172
+ // Sanitize db options. The caller should delete result.info_log if
173
+ // it is not equal to src.info_log.
174
+ extern Options SanitizeOptions(const std::string& db,
175
+ const InternalKeyComparator* icmp,
176
+ const Options& src);
177
+
178
+ }
179
+
180
+ #endif // STORAGE_LEVELDB_DB_DB_IMPL_H_
@@ -0,0 +1,298 @@
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/db_iter.h"
6
+
7
+ #include "db/filename.h"
8
+ #include "db/dbformat.h"
9
+ #include "leveldb/env.h"
10
+ #include "leveldb/iterator.h"
11
+ #include "port/port.h"
12
+ #include "util/logging.h"
13
+ #include "util/mutexlock.h"
14
+
15
+ namespace leveldb {
16
+
17
+ #if 0
18
+ static void DumpInternalIter(Iterator* iter) {
19
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
20
+ ParsedInternalKey k;
21
+ if (!ParseInternalKey(iter->key(), &k)) {
22
+ fprintf(stderr, "Corrupt '%s'\n", EscapeString(iter->key()).c_str());
23
+ } else {
24
+ fprintf(stderr, "@ '%s'\n", k.DebugString().c_str());
25
+ }
26
+ }
27
+ }
28
+ #endif
29
+
30
+ namespace {
31
+
32
+ // Memtables and sstables that make the DB representation contain
33
+ // (userkey,seq,type) => uservalue entries. DBIter
34
+ // combines multiple entries for the same userkey found in the DB
35
+ // representation into a single entry while accounting for sequence
36
+ // numbers, deletion markers, overwrites, etc.
37
+ class DBIter: public Iterator {
38
+ public:
39
+ // Which direction is the iterator currently moving?
40
+ // (1) When moving forward, the internal iterator is positioned at
41
+ // the exact entry that yields this->key(), this->value()
42
+ // (2) When moving backwards, the internal iterator is positioned
43
+ // just before all entries whose user key == this->key().
44
+ enum Direction {
45
+ kForward,
46
+ kReverse
47
+ };
48
+
49
+ DBIter(const std::string* dbname, Env* env,
50
+ const Comparator* cmp, Iterator* iter, SequenceNumber s)
51
+ : dbname_(dbname),
52
+ env_(env),
53
+ user_comparator_(cmp),
54
+ iter_(iter),
55
+ sequence_(s),
56
+ direction_(kForward),
57
+ valid_(false) {
58
+ }
59
+ virtual ~DBIter() {
60
+ delete iter_;
61
+ }
62
+ virtual bool Valid() const { return valid_; }
63
+ virtual Slice key() const {
64
+ assert(valid_);
65
+ return (direction_ == kForward) ? ExtractUserKey(iter_->key()) : saved_key_;
66
+ }
67
+ virtual Slice value() const {
68
+ assert(valid_);
69
+ return (direction_ == kForward) ? iter_->value() : saved_value_;
70
+ }
71
+ virtual Status status() const {
72
+ if (status_.ok()) {
73
+ return iter_->status();
74
+ } else {
75
+ return status_;
76
+ }
77
+ }
78
+
79
+ virtual void Next();
80
+ virtual void Prev();
81
+ virtual void Seek(const Slice& target);
82
+ virtual void SeekToFirst();
83
+ virtual void SeekToLast();
84
+
85
+ private:
86
+ void FindNextUserEntry(bool skipping, std::string* skip);
87
+ void FindPrevUserEntry();
88
+ bool ParseKey(ParsedInternalKey* key);
89
+
90
+ inline void SaveKey(const Slice& k, std::string* dst) {
91
+ dst->assign(k.data(), k.size());
92
+ }
93
+
94
+ inline void ClearSavedValue() {
95
+ if (saved_value_.capacity() > 1048576) {
96
+ std::string empty;
97
+ swap(empty, saved_value_);
98
+ } else {
99
+ saved_value_.clear();
100
+ }
101
+ }
102
+
103
+ const std::string* const dbname_;
104
+ Env* const env_;
105
+ const Comparator* const user_comparator_;
106
+ Iterator* const iter_;
107
+ SequenceNumber const sequence_;
108
+
109
+ Status status_;
110
+ std::string saved_key_; // == current key when direction_==kReverse
111
+ std::string saved_value_; // == current raw value when direction_==kReverse
112
+ Direction direction_;
113
+ bool valid_;
114
+
115
+ // No copying allowed
116
+ DBIter(const DBIter&);
117
+ void operator=(const DBIter&);
118
+ };
119
+
120
+ inline bool DBIter::ParseKey(ParsedInternalKey* ikey) {
121
+ if (!ParseInternalKey(iter_->key(), ikey)) {
122
+ status_ = Status::Corruption("corrupted internal key in DBIter");
123
+ return false;
124
+ } else {
125
+ return true;
126
+ }
127
+ }
128
+
129
+ void DBIter::Next() {
130
+ assert(valid_);
131
+
132
+ if (direction_ == kReverse) { // Switch directions?
133
+ direction_ = kForward;
134
+ // iter_ is pointing just before the entries for this->key(),
135
+ // so advance into the range of entries for this->key() and then
136
+ // use the normal skipping code below.
137
+ if (!iter_->Valid()) {
138
+ iter_->SeekToFirst();
139
+ } else {
140
+ iter_->Next();
141
+ }
142
+ if (!iter_->Valid()) {
143
+ valid_ = false;
144
+ saved_key_.clear();
145
+ return;
146
+ }
147
+ }
148
+
149
+ // Temporarily use saved_key_ as storage for key to skip.
150
+ std::string* skip = &saved_key_;
151
+ SaveKey(ExtractUserKey(iter_->key()), skip);
152
+ FindNextUserEntry(true, skip);
153
+ }
154
+
155
+ void DBIter::FindNextUserEntry(bool skipping, std::string* skip) {
156
+ // Loop until we hit an acceptable entry to yield
157
+ assert(iter_->Valid());
158
+ assert(direction_ == kForward);
159
+ do {
160
+ ParsedInternalKey ikey;
161
+ if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
162
+ switch (ikey.type) {
163
+ case kTypeDeletion:
164
+ // Arrange to skip all upcoming entries for this key since
165
+ // they are hidden by this deletion.
166
+ SaveKey(ikey.user_key, skip);
167
+ skipping = true;
168
+ break;
169
+ case kTypeValue:
170
+ if (skipping &&
171
+ user_comparator_->Compare(ikey.user_key, *skip) <= 0) {
172
+ // Entry hidden
173
+ } else {
174
+ valid_ = true;
175
+ saved_key_.clear();
176
+ return;
177
+ }
178
+ break;
179
+ }
180
+ }
181
+ iter_->Next();
182
+ } while (iter_->Valid());
183
+ saved_key_.clear();
184
+ valid_ = false;
185
+ }
186
+
187
+ void DBIter::Prev() {
188
+ assert(valid_);
189
+
190
+ if (direction_ == kForward) { // Switch directions?
191
+ // iter_ is pointing at the current entry. Scan backwards until
192
+ // the key changes so we can use the normal reverse scanning code.
193
+ assert(iter_->Valid()); // Otherwise valid_ would have been false
194
+ SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
195
+ while (true) {
196
+ iter_->Prev();
197
+ if (!iter_->Valid()) {
198
+ valid_ = false;
199
+ saved_key_.clear();
200
+ ClearSavedValue();
201
+ return;
202
+ }
203
+ if (user_comparator_->Compare(ExtractUserKey(iter_->key()),
204
+ saved_key_) < 0) {
205
+ break;
206
+ }
207
+ }
208
+ direction_ = kReverse;
209
+ }
210
+
211
+ FindPrevUserEntry();
212
+ }
213
+
214
+ void DBIter::FindPrevUserEntry() {
215
+ assert(direction_ == kReverse);
216
+
217
+ ValueType value_type = kTypeDeletion;
218
+ if (iter_->Valid()) {
219
+ SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
220
+ do {
221
+ ParsedInternalKey ikey;
222
+ if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
223
+ if ((value_type != kTypeDeletion) &&
224
+ user_comparator_->Compare(ikey.user_key, saved_key_) < 0) {
225
+ // We encountered a non-deleted value in entries for previous keys,
226
+ break;
227
+ }
228
+ value_type = ikey.type;
229
+ if (value_type == kTypeDeletion) {
230
+ ClearSavedValue();
231
+ } else {
232
+ Slice raw_value = iter_->value();
233
+ if (saved_value_.capacity() > raw_value.size() + 1048576) {
234
+ std::string empty;
235
+ swap(empty, saved_value_);
236
+ }
237
+ saved_value_.assign(raw_value.data(), raw_value.size());
238
+ }
239
+ }
240
+ iter_->Prev();
241
+ } while (iter_->Valid());
242
+ }
243
+
244
+ if (value_type == kTypeDeletion) {
245
+ // End
246
+ valid_ = false;
247
+ saved_key_.clear();
248
+ ClearSavedValue();
249
+ direction_ = kForward;
250
+ } else {
251
+ valid_ = true;
252
+ }
253
+ }
254
+
255
+ void DBIter::Seek(const Slice& target) {
256
+ direction_ = kForward;
257
+ ClearSavedValue();
258
+ saved_key_.clear();
259
+ AppendInternalKey(
260
+ &saved_key_, ParsedInternalKey(target, sequence_, kValueTypeForSeek));
261
+ iter_->Seek(saved_key_);
262
+ if (iter_->Valid()) {
263
+ FindNextUserEntry(false, &saved_key_ /* temporary storage */);
264
+ } else {
265
+ valid_ = false;
266
+ }
267
+ }
268
+
269
+ void DBIter::SeekToFirst() {
270
+ direction_ = kForward;
271
+ ClearSavedValue();
272
+ iter_->SeekToFirst();
273
+ if (iter_->Valid()) {
274
+ FindNextUserEntry(false, &saved_key_ /* temporary storage */);
275
+ } else {
276
+ valid_ = false;
277
+ }
278
+ }
279
+
280
+ void DBIter::SeekToLast() {
281
+ direction_ = kReverse;
282
+ ClearSavedValue();
283
+ iter_->SeekToLast();
284
+ FindPrevUserEntry();
285
+ }
286
+
287
+ } // anonymous namespace
288
+
289
+ Iterator* NewDBIterator(
290
+ const std::string* dbname,
291
+ Env* env,
292
+ const Comparator* user_key_comparator,
293
+ Iterator* internal_iter,
294
+ const SequenceNumber& sequence) {
295
+ return new DBIter(dbname, env, user_key_comparator, internal_iter, sequence);
296
+ }
297
+
298
+ }