leveldb 0.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.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +95 -0
  4. data/ext/Rakefile +11 -0
  5. data/ext/leveldb/LICENSE +27 -0
  6. data/ext/leveldb/Makefile +206 -0
  7. data/ext/leveldb/build_config.mk +13 -0
  8. data/ext/leveldb/db/builder.cc +88 -0
  9. data/ext/leveldb/db/builder.h +34 -0
  10. data/ext/leveldb/db/c.cc +595 -0
  11. data/ext/leveldb/db/c_test.c +390 -0
  12. data/ext/leveldb/db/corruption_test.cc +359 -0
  13. data/ext/leveldb/db/db_bench.cc +979 -0
  14. data/ext/leveldb/db/db_impl.cc +1485 -0
  15. data/ext/leveldb/db/db_impl.h +203 -0
  16. data/ext/leveldb/db/db_iter.cc +299 -0
  17. data/ext/leveldb/db/db_iter.h +26 -0
  18. data/ext/leveldb/db/db_test.cc +2092 -0
  19. data/ext/leveldb/db/dbformat.cc +140 -0
  20. data/ext/leveldb/db/dbformat.h +227 -0
  21. data/ext/leveldb/db/dbformat_test.cc +112 -0
  22. data/ext/leveldb/db/filename.cc +139 -0
  23. data/ext/leveldb/db/filename.h +80 -0
  24. data/ext/leveldb/db/filename_test.cc +122 -0
  25. data/ext/leveldb/db/leveldb_main.cc +238 -0
  26. data/ext/leveldb/db/log_format.h +35 -0
  27. data/ext/leveldb/db/log_reader.cc +259 -0
  28. data/ext/leveldb/db/log_reader.h +108 -0
  29. data/ext/leveldb/db/log_test.cc +500 -0
  30. data/ext/leveldb/db/log_writer.cc +103 -0
  31. data/ext/leveldb/db/log_writer.h +48 -0
  32. data/ext/leveldb/db/memtable.cc +145 -0
  33. data/ext/leveldb/db/memtable.h +91 -0
  34. data/ext/leveldb/db/repair.cc +389 -0
  35. data/ext/leveldb/db/skiplist.h +379 -0
  36. data/ext/leveldb/db/skiplist_test.cc +378 -0
  37. data/ext/leveldb/db/snapshot.h +66 -0
  38. data/ext/leveldb/db/table_cache.cc +121 -0
  39. data/ext/leveldb/db/table_cache.h +61 -0
  40. data/ext/leveldb/db/version_edit.cc +266 -0
  41. data/ext/leveldb/db/version_edit.h +107 -0
  42. data/ext/leveldb/db/version_edit_test.cc +46 -0
  43. data/ext/leveldb/db/version_set.cc +1443 -0
  44. data/ext/leveldb/db/version_set.h +383 -0
  45. data/ext/leveldb/db/version_set_test.cc +179 -0
  46. data/ext/leveldb/db/write_batch.cc +147 -0
  47. data/ext/leveldb/db/write_batch_internal.h +49 -0
  48. data/ext/leveldb/db/write_batch_test.cc +120 -0
  49. data/ext/leveldb/doc/bench/db_bench_sqlite3.cc +718 -0
  50. data/ext/leveldb/doc/bench/db_bench_tree_db.cc +528 -0
  51. data/ext/leveldb/helpers/memenv/memenv.cc +384 -0
  52. data/ext/leveldb/helpers/memenv/memenv.h +20 -0
  53. data/ext/leveldb/helpers/memenv/memenv_test.cc +232 -0
  54. data/ext/leveldb/include/leveldb/c.h +291 -0
  55. data/ext/leveldb/include/leveldb/cache.h +99 -0
  56. data/ext/leveldb/include/leveldb/comparator.h +63 -0
  57. data/ext/leveldb/include/leveldb/db.h +161 -0
  58. data/ext/leveldb/include/leveldb/env.h +333 -0
  59. data/ext/leveldb/include/leveldb/filter_policy.h +70 -0
  60. data/ext/leveldb/include/leveldb/iterator.h +100 -0
  61. data/ext/leveldb/include/leveldb/options.h +195 -0
  62. data/ext/leveldb/include/leveldb/slice.h +109 -0
  63. data/ext/leveldb/include/leveldb/status.h +106 -0
  64. data/ext/leveldb/include/leveldb/table.h +85 -0
  65. data/ext/leveldb/include/leveldb/table_builder.h +92 -0
  66. data/ext/leveldb/include/leveldb/write_batch.h +64 -0
  67. data/ext/leveldb/issues/issue178_test.cc +92 -0
  68. data/ext/leveldb/port/atomic_pointer.h +224 -0
  69. data/ext/leveldb/port/port.h +19 -0
  70. data/ext/leveldb/port/port_example.h +135 -0
  71. data/ext/leveldb/port/port_posix.cc +54 -0
  72. data/ext/leveldb/port/port_posix.h +157 -0
  73. data/ext/leveldb/port/thread_annotations.h +59 -0
  74. data/ext/leveldb/port/win/stdint.h +24 -0
  75. data/ext/leveldb/table/block.cc +268 -0
  76. data/ext/leveldb/table/block.h +44 -0
  77. data/ext/leveldb/table/block_builder.cc +109 -0
  78. data/ext/leveldb/table/block_builder.h +57 -0
  79. data/ext/leveldb/table/filter_block.cc +111 -0
  80. data/ext/leveldb/table/filter_block.h +68 -0
  81. data/ext/leveldb/table/filter_block_test.cc +128 -0
  82. data/ext/leveldb/table/format.cc +145 -0
  83. data/ext/leveldb/table/format.h +108 -0
  84. data/ext/leveldb/table/iterator.cc +67 -0
  85. data/ext/leveldb/table/iterator_wrapper.h +63 -0
  86. data/ext/leveldb/table/merger.cc +197 -0
  87. data/ext/leveldb/table/merger.h +26 -0
  88. data/ext/leveldb/table/table.cc +275 -0
  89. data/ext/leveldb/table/table_builder.cc +270 -0
  90. data/ext/leveldb/table/table_test.cc +868 -0
  91. data/ext/leveldb/table/two_level_iterator.cc +182 -0
  92. data/ext/leveldb/table/two_level_iterator.h +34 -0
  93. data/ext/leveldb/util/arena.cc +68 -0
  94. data/ext/leveldb/util/arena.h +68 -0
  95. data/ext/leveldb/util/arena_test.cc +68 -0
  96. data/ext/leveldb/util/bloom.cc +95 -0
  97. data/ext/leveldb/util/bloom_test.cc +160 -0
  98. data/ext/leveldb/util/cache.cc +325 -0
  99. data/ext/leveldb/util/cache_test.cc +186 -0
  100. data/ext/leveldb/util/coding.cc +194 -0
  101. data/ext/leveldb/util/coding.h +104 -0
  102. data/ext/leveldb/util/coding_test.cc +196 -0
  103. data/ext/leveldb/util/comparator.cc +81 -0
  104. data/ext/leveldb/util/crc32c.cc +332 -0
  105. data/ext/leveldb/util/crc32c.h +45 -0
  106. data/ext/leveldb/util/crc32c_test.cc +72 -0
  107. data/ext/leveldb/util/env.cc +96 -0
  108. data/ext/leveldb/util/env_posix.cc +698 -0
  109. data/ext/leveldb/util/env_test.cc +104 -0
  110. data/ext/leveldb/util/filter_policy.cc +11 -0
  111. data/ext/leveldb/util/hash.cc +52 -0
  112. data/ext/leveldb/util/hash.h +19 -0
  113. data/ext/leveldb/util/histogram.cc +139 -0
  114. data/ext/leveldb/util/histogram.h +42 -0
  115. data/ext/leveldb/util/logging.cc +81 -0
  116. data/ext/leveldb/util/logging.h +47 -0
  117. data/ext/leveldb/util/mutexlock.h +41 -0
  118. data/ext/leveldb/util/options.cc +29 -0
  119. data/ext/leveldb/util/posix_logger.h +98 -0
  120. data/ext/leveldb/util/random.h +59 -0
  121. data/ext/leveldb/util/status.cc +75 -0
  122. data/ext/leveldb/util/testharness.cc +77 -0
  123. data/ext/leveldb/util/testharness.h +138 -0
  124. data/ext/leveldb/util/testutil.cc +51 -0
  125. data/ext/leveldb/util/testutil.h +53 -0
  126. data/lib/leveldb/version.rb +3 -0
  127. data/lib/leveldb.rb +1006 -0
  128. metadata +228 -0
@@ -0,0 +1,379 @@
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 safety
6
+ // -------------
7
+ //
8
+ // Writes require external synchronization, most likely a mutex.
9
+ // Reads require a guarantee that the SkipList will not be destroyed
10
+ // while the read is in progress. Apart from that, reads progress
11
+ // without any internal locking or synchronization.
12
+ //
13
+ // Invariants:
14
+ //
15
+ // (1) Allocated nodes are never deleted until the SkipList is
16
+ // destroyed. This is trivially guaranteed by the code since we
17
+ // never delete any skip list nodes.
18
+ //
19
+ // (2) The contents of a Node except for the next/prev pointers are
20
+ // immutable after the Node has been linked into the SkipList.
21
+ // Only Insert() modifies the list, and it is careful to initialize
22
+ // a node and use release-stores to publish the nodes in one or
23
+ // more lists.
24
+ //
25
+ // ... prev vs. next pointer ordering ...
26
+
27
+ #include <assert.h>
28
+ #include <stdlib.h>
29
+ #include "port/port.h"
30
+ #include "util/arena.h"
31
+ #include "util/random.h"
32
+
33
+ namespace leveldb {
34
+
35
+ class Arena;
36
+
37
+ template<typename Key, class Comparator>
38
+ class SkipList {
39
+ private:
40
+ struct Node;
41
+
42
+ public:
43
+ // Create a new SkipList object that will use "cmp" for comparing keys,
44
+ // and will allocate memory using "*arena". Objects allocated in the arena
45
+ // must remain allocated for the lifetime of the skiplist object.
46
+ explicit SkipList(Comparator cmp, Arena* arena);
47
+
48
+ // Insert key into the list.
49
+ // REQUIRES: nothing that compares equal to key is currently in the list.
50
+ void Insert(const Key& key);
51
+
52
+ // Returns true iff an entry that compares equal to key is in the list.
53
+ bool Contains(const Key& key) const;
54
+
55
+ // Iteration over the contents of a skip list
56
+ class Iterator {
57
+ public:
58
+ // Initialize an iterator over the specified list.
59
+ // The returned iterator is not valid.
60
+ explicit Iterator(const SkipList* list);
61
+
62
+ // Returns true iff the iterator is positioned at a valid node.
63
+ bool Valid() const;
64
+
65
+ // Returns the key at the current position.
66
+ // REQUIRES: Valid()
67
+ const Key& key() const;
68
+
69
+ // Advances to the next position.
70
+ // REQUIRES: Valid()
71
+ void Next();
72
+
73
+ // Advances to the previous position.
74
+ // REQUIRES: Valid()
75
+ void Prev();
76
+
77
+ // Advance to the first entry with a key >= target
78
+ void Seek(const Key& target);
79
+
80
+ // Position at the first entry in list.
81
+ // Final state of iterator is Valid() iff list is not empty.
82
+ void SeekToFirst();
83
+
84
+ // Position at the last entry in list.
85
+ // Final state of iterator is Valid() iff list is not empty.
86
+ void SeekToLast();
87
+
88
+ private:
89
+ const SkipList* list_;
90
+ Node* node_;
91
+ // Intentionally copyable
92
+ };
93
+
94
+ private:
95
+ enum { kMaxHeight = 12 };
96
+
97
+ // Immutable after construction
98
+ Comparator const compare_;
99
+ Arena* const arena_; // Arena used for allocations of nodes
100
+
101
+ Node* const head_;
102
+
103
+ // Modified only by Insert(). Read racily by readers, but stale
104
+ // values are ok.
105
+ port::AtomicPointer max_height_; // Height of the entire list
106
+
107
+ inline int GetMaxHeight() const {
108
+ return static_cast<int>(
109
+ reinterpret_cast<intptr_t>(max_height_.NoBarrier_Load()));
110
+ }
111
+
112
+ // Read/written only by Insert().
113
+ Random rnd_;
114
+
115
+ Node* NewNode(const Key& key, int height);
116
+ int RandomHeight();
117
+ bool Equal(const Key& a, const Key& b) const { return (compare_(a, b) == 0); }
118
+
119
+ // Return true if key is greater than the data stored in "n"
120
+ bool KeyIsAfterNode(const Key& key, Node* n) const;
121
+
122
+ // Return the earliest node that comes at or after key.
123
+ // Return NULL if there is no such node.
124
+ //
125
+ // If prev is non-NULL, fills prev[level] with pointer to previous
126
+ // node at "level" for every level in [0..max_height_-1].
127
+ Node* FindGreaterOrEqual(const Key& key, Node** prev) const;
128
+
129
+ // Return the latest node with a key < key.
130
+ // Return head_ if there is no such node.
131
+ Node* FindLessThan(const Key& key) const;
132
+
133
+ // Return the last node in the list.
134
+ // Return head_ if list is empty.
135
+ Node* FindLast() const;
136
+
137
+ // No copying allowed
138
+ SkipList(const SkipList&);
139
+ void operator=(const SkipList&);
140
+ };
141
+
142
+ // Implementation details follow
143
+ template<typename Key, class Comparator>
144
+ struct SkipList<Key,Comparator>::Node {
145
+ explicit Node(const Key& k) : key(k) { }
146
+
147
+ Key const key;
148
+
149
+ // Accessors/mutators for links. Wrapped in methods so we can
150
+ // add the appropriate barriers as necessary.
151
+ Node* Next(int n) {
152
+ assert(n >= 0);
153
+ // Use an 'acquire load' so that we observe a fully initialized
154
+ // version of the returned Node.
155
+ return reinterpret_cast<Node*>(next_[n].Acquire_Load());
156
+ }
157
+ void SetNext(int n, Node* x) {
158
+ assert(n >= 0);
159
+ // Use a 'release store' so that anybody who reads through this
160
+ // pointer observes a fully initialized version of the inserted node.
161
+ next_[n].Release_Store(x);
162
+ }
163
+
164
+ // No-barrier variants that can be safely used in a few locations.
165
+ Node* NoBarrier_Next(int n) {
166
+ assert(n >= 0);
167
+ return reinterpret_cast<Node*>(next_[n].NoBarrier_Load());
168
+ }
169
+ void NoBarrier_SetNext(int n, Node* x) {
170
+ assert(n >= 0);
171
+ next_[n].NoBarrier_Store(x);
172
+ }
173
+
174
+ private:
175
+ // Array of length equal to the node height. next_[0] is lowest level link.
176
+ port::AtomicPointer next_[1];
177
+ };
178
+
179
+ template<typename Key, class Comparator>
180
+ typename SkipList<Key,Comparator>::Node*
181
+ SkipList<Key,Comparator>::NewNode(const Key& key, int height) {
182
+ char* mem = arena_->AllocateAligned(
183
+ sizeof(Node) + sizeof(port::AtomicPointer) * (height - 1));
184
+ return new (mem) Node(key);
185
+ }
186
+
187
+ template<typename Key, class Comparator>
188
+ inline SkipList<Key,Comparator>::Iterator::Iterator(const SkipList* list) {
189
+ list_ = list;
190
+ node_ = NULL;
191
+ }
192
+
193
+ template<typename Key, class Comparator>
194
+ inline bool SkipList<Key,Comparator>::Iterator::Valid() const {
195
+ return node_ != NULL;
196
+ }
197
+
198
+ template<typename Key, class Comparator>
199
+ inline const Key& SkipList<Key,Comparator>::Iterator::key() const {
200
+ assert(Valid());
201
+ return node_->key;
202
+ }
203
+
204
+ template<typename Key, class Comparator>
205
+ inline void SkipList<Key,Comparator>::Iterator::Next() {
206
+ assert(Valid());
207
+ node_ = node_->Next(0);
208
+ }
209
+
210
+ template<typename Key, class Comparator>
211
+ inline void SkipList<Key,Comparator>::Iterator::Prev() {
212
+ // Instead of using explicit "prev" links, we just search for the
213
+ // last node that falls before key.
214
+ assert(Valid());
215
+ node_ = list_->FindLessThan(node_->key);
216
+ if (node_ == list_->head_) {
217
+ node_ = NULL;
218
+ }
219
+ }
220
+
221
+ template<typename Key, class Comparator>
222
+ inline void SkipList<Key,Comparator>::Iterator::Seek(const Key& target) {
223
+ node_ = list_->FindGreaterOrEqual(target, NULL);
224
+ }
225
+
226
+ template<typename Key, class Comparator>
227
+ inline void SkipList<Key,Comparator>::Iterator::SeekToFirst() {
228
+ node_ = list_->head_->Next(0);
229
+ }
230
+
231
+ template<typename Key, class Comparator>
232
+ inline void SkipList<Key,Comparator>::Iterator::SeekToLast() {
233
+ node_ = list_->FindLast();
234
+ if (node_ == list_->head_) {
235
+ node_ = NULL;
236
+ }
237
+ }
238
+
239
+ template<typename Key, class Comparator>
240
+ int SkipList<Key,Comparator>::RandomHeight() {
241
+ // Increase height with probability 1 in kBranching
242
+ static const unsigned int kBranching = 4;
243
+ int height = 1;
244
+ while (height < kMaxHeight && ((rnd_.Next() % kBranching) == 0)) {
245
+ height++;
246
+ }
247
+ assert(height > 0);
248
+ assert(height <= kMaxHeight);
249
+ return height;
250
+ }
251
+
252
+ template<typename Key, class Comparator>
253
+ bool SkipList<Key,Comparator>::KeyIsAfterNode(const Key& key, Node* n) const {
254
+ // NULL n is considered infinite
255
+ return (n != NULL) && (compare_(n->key, key) < 0);
256
+ }
257
+
258
+ template<typename Key, class Comparator>
259
+ typename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindGreaterOrEqual(const Key& key, Node** prev)
260
+ const {
261
+ Node* x = head_;
262
+ int level = GetMaxHeight() - 1;
263
+ while (true) {
264
+ Node* next = x->Next(level);
265
+ if (KeyIsAfterNode(key, next)) {
266
+ // Keep searching in this list
267
+ x = next;
268
+ } else {
269
+ if (prev != NULL) prev[level] = x;
270
+ if (level == 0) {
271
+ return next;
272
+ } else {
273
+ // Switch to next list
274
+ level--;
275
+ }
276
+ }
277
+ }
278
+ }
279
+
280
+ template<typename Key, class Comparator>
281
+ typename SkipList<Key,Comparator>::Node*
282
+ SkipList<Key,Comparator>::FindLessThan(const Key& key) const {
283
+ Node* x = head_;
284
+ int level = GetMaxHeight() - 1;
285
+ while (true) {
286
+ assert(x == head_ || compare_(x->key, key) < 0);
287
+ Node* next = x->Next(level);
288
+ if (next == NULL || compare_(next->key, key) >= 0) {
289
+ if (level == 0) {
290
+ return x;
291
+ } else {
292
+ // Switch to next list
293
+ level--;
294
+ }
295
+ } else {
296
+ x = next;
297
+ }
298
+ }
299
+ }
300
+
301
+ template<typename Key, class Comparator>
302
+ typename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindLast()
303
+ const {
304
+ Node* x = head_;
305
+ int level = GetMaxHeight() - 1;
306
+ while (true) {
307
+ Node* next = x->Next(level);
308
+ if (next == NULL) {
309
+ if (level == 0) {
310
+ return x;
311
+ } else {
312
+ // Switch to next list
313
+ level--;
314
+ }
315
+ } else {
316
+ x = next;
317
+ }
318
+ }
319
+ }
320
+
321
+ template<typename Key, class Comparator>
322
+ SkipList<Key,Comparator>::SkipList(Comparator cmp, Arena* arena)
323
+ : compare_(cmp),
324
+ arena_(arena),
325
+ head_(NewNode(0 /* any key will do */, kMaxHeight)),
326
+ max_height_(reinterpret_cast<void*>(1)),
327
+ rnd_(0xdeadbeef) {
328
+ for (int i = 0; i < kMaxHeight; i++) {
329
+ head_->SetNext(i, NULL);
330
+ }
331
+ }
332
+
333
+ template<typename Key, class Comparator>
334
+ void SkipList<Key,Comparator>::Insert(const Key& key) {
335
+ // TODO(opt): We can use a barrier-free variant of FindGreaterOrEqual()
336
+ // here since Insert() is externally synchronized.
337
+ Node* prev[kMaxHeight];
338
+ Node* x = FindGreaterOrEqual(key, prev);
339
+
340
+ // Our data structure does not allow duplicate insertion
341
+ assert(x == NULL || !Equal(key, x->key));
342
+
343
+ int height = RandomHeight();
344
+ if (height > GetMaxHeight()) {
345
+ for (int i = GetMaxHeight(); i < height; i++) {
346
+ prev[i] = head_;
347
+ }
348
+ //fprintf(stderr, "Change height from %d to %d\n", max_height_, height);
349
+
350
+ // It is ok to mutate max_height_ without any synchronization
351
+ // with concurrent readers. A concurrent reader that observes
352
+ // the new value of max_height_ will see either the old value of
353
+ // new level pointers from head_ (NULL), or a new value set in
354
+ // the loop below. In the former case the reader will
355
+ // immediately drop to the next level since NULL sorts after all
356
+ // keys. In the latter case the reader will use the new node.
357
+ max_height_.NoBarrier_Store(reinterpret_cast<void*>(height));
358
+ }
359
+
360
+ x = NewNode(key, height);
361
+ for (int i = 0; i < height; i++) {
362
+ // NoBarrier_SetNext() suffices since we will add a barrier when
363
+ // we publish a pointer to "x" in prev[i].
364
+ x->NoBarrier_SetNext(i, prev[i]->NoBarrier_Next(i));
365
+ prev[i]->SetNext(i, x);
366
+ }
367
+ }
368
+
369
+ template<typename Key, class Comparator>
370
+ bool SkipList<Key,Comparator>::Contains(const Key& key) const {
371
+ Node* x = FindGreaterOrEqual(key, NULL);
372
+ if (x != NULL && Equal(key, x->key)) {
373
+ return true;
374
+ } else {
375
+ return false;
376
+ }
377
+ }
378
+
379
+ } // namespace leveldb