filiptepper-leveldb-ruby 0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/LICENSE +24 -0
  2. data/README +72 -0
  3. data/ext/leveldb/extconf.rb +14 -0
  4. data/ext/leveldb/leveldb.cc +530 -0
  5. data/ext/leveldb/platform.rb +83 -0
  6. data/leveldb/Makefile +191 -0
  7. data/leveldb/build_detect_platform +160 -0
  8. data/leveldb/db/builder.cc +88 -0
  9. data/leveldb/db/builder.h +34 -0
  10. data/leveldb/db/c.cc +581 -0
  11. data/leveldb/db/corruption_test.cc +359 -0
  12. data/leveldb/db/db_bench.cc +970 -0
  13. data/leveldb/db/db_impl.cc +1448 -0
  14. data/leveldb/db/db_impl.h +194 -0
  15. data/leveldb/db/db_iter.cc +299 -0
  16. data/leveldb/db/db_iter.h +26 -0
  17. data/leveldb/db/db_test.cc +1901 -0
  18. data/leveldb/db/dbformat.cc +140 -0
  19. data/leveldb/db/dbformat.h +227 -0
  20. data/leveldb/db/dbformat_test.cc +112 -0
  21. data/leveldb/db/filename.cc +139 -0
  22. data/leveldb/db/filename.h +80 -0
  23. data/leveldb/db/filename_test.cc +122 -0
  24. data/leveldb/db/log_format.h +35 -0
  25. data/leveldb/db/log_reader.cc +259 -0
  26. data/leveldb/db/log_reader.h +108 -0
  27. data/leveldb/db/log_test.cc +500 -0
  28. data/leveldb/db/log_writer.cc +103 -0
  29. data/leveldb/db/log_writer.h +48 -0
  30. data/leveldb/db/memtable.cc +145 -0
  31. data/leveldb/db/memtable.h +91 -0
  32. data/leveldb/db/repair.cc +389 -0
  33. data/leveldb/db/skiplist.h +379 -0
  34. data/leveldb/db/skiplist_test.cc +378 -0
  35. data/leveldb/db/snapshot.h +66 -0
  36. data/leveldb/db/table_cache.cc +121 -0
  37. data/leveldb/db/table_cache.h +61 -0
  38. data/leveldb/db/version_edit.cc +266 -0
  39. data/leveldb/db/version_edit.h +107 -0
  40. data/leveldb/db/version_edit_test.cc +46 -0
  41. data/leveldb/db/version_set.cc +1402 -0
  42. data/leveldb/db/version_set.h +370 -0
  43. data/leveldb/db/version_set_test.cc +179 -0
  44. data/leveldb/db/write_batch.cc +147 -0
  45. data/leveldb/db/write_batch_internal.h +49 -0
  46. data/leveldb/db/write_batch_test.cc +120 -0
  47. data/leveldb/helpers/memenv/memenv.cc +374 -0
  48. data/leveldb/helpers/memenv/memenv.h +20 -0
  49. data/leveldb/helpers/memenv/memenv_test.cc +232 -0
  50. data/leveldb/include/leveldb/c.h +275 -0
  51. data/leveldb/include/leveldb/cache.h +99 -0
  52. data/leveldb/include/leveldb/comparator.h +63 -0
  53. data/leveldb/include/leveldb/db.h +161 -0
  54. data/leveldb/include/leveldb/env.h +323 -0
  55. data/leveldb/include/leveldb/filter_policy.h +70 -0
  56. data/leveldb/include/leveldb/iterator.h +100 -0
  57. data/leveldb/include/leveldb/options.h +195 -0
  58. data/leveldb/include/leveldb/slice.h +109 -0
  59. data/leveldb/include/leveldb/status.h +106 -0
  60. data/leveldb/include/leveldb/table.h +85 -0
  61. data/leveldb/include/leveldb/table_builder.h +92 -0
  62. data/leveldb/include/leveldb/write_batch.h +64 -0
  63. data/leveldb/port/atomic_pointer.h +144 -0
  64. data/leveldb/port/port.h +21 -0
  65. data/leveldb/port/port_android.cc +64 -0
  66. data/leveldb/port/port_android.h +159 -0
  67. data/leveldb/port/port_example.h +125 -0
  68. data/leveldb/port/port_posix.cc +50 -0
  69. data/leveldb/port/port_posix.h +129 -0
  70. data/leveldb/port/win/stdint.h +24 -0
  71. data/leveldb/table/block.cc +267 -0
  72. data/leveldb/table/block.h +44 -0
  73. data/leveldb/table/block_builder.cc +109 -0
  74. data/leveldb/table/block_builder.h +57 -0
  75. data/leveldb/table/filter_block.cc +111 -0
  76. data/leveldb/table/filter_block.h +68 -0
  77. data/leveldb/table/filter_block_test.cc +128 -0
  78. data/leveldb/table/format.cc +145 -0
  79. data/leveldb/table/format.h +108 -0
  80. data/leveldb/table/iterator.cc +67 -0
  81. data/leveldb/table/iterator_wrapper.h +63 -0
  82. data/leveldb/table/merger.cc +197 -0
  83. data/leveldb/table/merger.h +26 -0
  84. data/leveldb/table/table.cc +276 -0
  85. data/leveldb/table/table_builder.cc +270 -0
  86. data/leveldb/table/table_test.cc +838 -0
  87. data/leveldb/table/two_level_iterator.cc +182 -0
  88. data/leveldb/table/two_level_iterator.h +34 -0
  89. data/leveldb/util/arena.cc +68 -0
  90. data/leveldb/util/arena.h +68 -0
  91. data/leveldb/util/arena_test.cc +68 -0
  92. data/leveldb/util/bloom.cc +95 -0
  93. data/leveldb/util/bloom_test.cc +159 -0
  94. data/leveldb/util/cache.cc +328 -0
  95. data/leveldb/util/cache_test.cc +186 -0
  96. data/leveldb/util/coding.cc +194 -0
  97. data/leveldb/util/coding.h +104 -0
  98. data/leveldb/util/coding_test.cc +173 -0
  99. data/leveldb/util/comparator.cc +76 -0
  100. data/leveldb/util/crc32c.cc +332 -0
  101. data/leveldb/util/crc32c.h +45 -0
  102. data/leveldb/util/crc32c_test.cc +72 -0
  103. data/leveldb/util/env.cc +96 -0
  104. data/leveldb/util/env_posix.cc +609 -0
  105. data/leveldb/util/env_test.cc +104 -0
  106. data/leveldb/util/filter_policy.cc +11 -0
  107. data/leveldb/util/hash.cc +45 -0
  108. data/leveldb/util/hash.h +19 -0
  109. data/leveldb/util/histogram.cc +139 -0
  110. data/leveldb/util/histogram.h +42 -0
  111. data/leveldb/util/logging.cc +81 -0
  112. data/leveldb/util/logging.h +47 -0
  113. data/leveldb/util/mutexlock.h +39 -0
  114. data/leveldb/util/options.cc +29 -0
  115. data/leveldb/util/posix_logger.h +98 -0
  116. data/leveldb/util/random.h +59 -0
  117. data/leveldb/util/status.cc +75 -0
  118. data/leveldb/util/testharness.cc +77 -0
  119. data/leveldb/util/testharness.h +138 -0
  120. data/leveldb/util/testutil.cc +51 -0
  121. data/leveldb/util/testutil.h +53 -0
  122. data/lib/leveldb.rb +76 -0
  123. metadata +175 -0
@@ -0,0 +1,24 @@
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
+ // MSVC didn't ship with this file until the 2010 version.
6
+
7
+ #ifndef STORAGE_LEVELDB_PORT_WIN_STDINT_H_
8
+ #define STORAGE_LEVELDB_PORT_WIN_STDINT_H_
9
+
10
+ #if !defined(_MSC_VER)
11
+ #error This file should only be included when compiling with MSVC.
12
+ #endif
13
+
14
+ // Define C99 equivalent types.
15
+ typedef signed char int8_t;
16
+ typedef signed short int16_t;
17
+ typedef signed int int32_t;
18
+ typedef signed long long int64_t;
19
+ typedef unsigned char uint8_t;
20
+ typedef unsigned short uint16_t;
21
+ typedef unsigned int uint32_t;
22
+ typedef unsigned long long uint64_t;
23
+
24
+ #endif // STORAGE_LEVELDB_PORT_WIN_STDINT_H_
@@ -0,0 +1,267 @@
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
+ // Decodes the blocks generated by block_builder.cc.
6
+
7
+ #include "table/block.h"
8
+
9
+ #include <vector>
10
+ #include <algorithm>
11
+ #include "leveldb/comparator.h"
12
+ #include "table/format.h"
13
+ #include "util/coding.h"
14
+ #include "util/logging.h"
15
+
16
+ namespace leveldb {
17
+
18
+ inline uint32_t Block::NumRestarts() const {
19
+ assert(size_ >= 2*sizeof(uint32_t));
20
+ return DecodeFixed32(data_ + size_ - sizeof(uint32_t));
21
+ }
22
+
23
+ Block::Block(const BlockContents& contents)
24
+ : data_(contents.data.data()),
25
+ size_(contents.data.size()),
26
+ owned_(contents.heap_allocated) {
27
+ if (size_ < sizeof(uint32_t)) {
28
+ size_ = 0; // Error marker
29
+ } else {
30
+ restart_offset_ = size_ - (1 + NumRestarts()) * sizeof(uint32_t);
31
+ if (restart_offset_ > size_ - sizeof(uint32_t)) {
32
+ // The size is too small for NumRestarts() and therefore
33
+ // restart_offset_ wrapped around.
34
+ size_ = 0;
35
+ }
36
+ }
37
+ }
38
+
39
+ Block::~Block() {
40
+ if (owned_) {
41
+ delete[] data_;
42
+ }
43
+ }
44
+
45
+ // Helper routine: decode the next block entry starting at "p",
46
+ // storing the number of shared key bytes, non_shared key bytes,
47
+ // and the length of the value in "*shared", "*non_shared", and
48
+ // "*value_length", respectively. Will not derefence past "limit".
49
+ //
50
+ // If any errors are detected, returns NULL. Otherwise, returns a
51
+ // pointer to the key delta (just past the three decoded values).
52
+ static inline const char* DecodeEntry(const char* p, const char* limit,
53
+ uint32_t* shared,
54
+ uint32_t* non_shared,
55
+ uint32_t* value_length) {
56
+ if (limit - p < 3) return NULL;
57
+ *shared = reinterpret_cast<const unsigned char*>(p)[0];
58
+ *non_shared = reinterpret_cast<const unsigned char*>(p)[1];
59
+ *value_length = reinterpret_cast<const unsigned char*>(p)[2];
60
+ if ((*shared | *non_shared | *value_length) < 128) {
61
+ // Fast path: all three values are encoded in one byte each
62
+ p += 3;
63
+ } else {
64
+ if ((p = GetVarint32Ptr(p, limit, shared)) == NULL) return NULL;
65
+ if ((p = GetVarint32Ptr(p, limit, non_shared)) == NULL) return NULL;
66
+ if ((p = GetVarint32Ptr(p, limit, value_length)) == NULL) return NULL;
67
+ }
68
+
69
+ if (static_cast<uint32_t>(limit - p) < (*non_shared + *value_length)) {
70
+ return NULL;
71
+ }
72
+ return p;
73
+ }
74
+
75
+ class Block::Iter : public Iterator {
76
+ private:
77
+ const Comparator* const comparator_;
78
+ const char* const data_; // underlying block contents
79
+ uint32_t const restarts_; // Offset of restart array (list of fixed32)
80
+ uint32_t const num_restarts_; // Number of uint32_t entries in restart array
81
+
82
+ // current_ is offset in data_ of current entry. >= restarts_ if !Valid
83
+ uint32_t current_;
84
+ uint32_t restart_index_; // Index of restart block in which current_ falls
85
+ std::string key_;
86
+ Slice value_;
87
+ Status status_;
88
+
89
+ inline int Compare(const Slice& a, const Slice& b) const {
90
+ return comparator_->Compare(a, b);
91
+ }
92
+
93
+ // Return the offset in data_ just past the end of the current entry.
94
+ inline uint32_t NextEntryOffset() const {
95
+ return (value_.data() + value_.size()) - data_;
96
+ }
97
+
98
+ uint32_t GetRestartPoint(uint32_t index) {
99
+ assert(index < num_restarts_);
100
+ return DecodeFixed32(data_ + restarts_ + index * sizeof(uint32_t));
101
+ }
102
+
103
+ void SeekToRestartPoint(uint32_t index) {
104
+ key_.clear();
105
+ restart_index_ = index;
106
+ // current_ will be fixed by ParseNextKey();
107
+
108
+ // ParseNextKey() starts at the end of value_, so set value_ accordingly
109
+ uint32_t offset = GetRestartPoint(index);
110
+ value_ = Slice(data_ + offset, 0);
111
+ }
112
+
113
+ public:
114
+ Iter(const Comparator* comparator,
115
+ const char* data,
116
+ uint32_t restarts,
117
+ uint32_t num_restarts)
118
+ : comparator_(comparator),
119
+ data_(data),
120
+ restarts_(restarts),
121
+ num_restarts_(num_restarts),
122
+ current_(restarts_),
123
+ restart_index_(num_restarts_) {
124
+ assert(num_restarts_ > 0);
125
+ }
126
+
127
+ virtual bool Valid() const { return current_ < restarts_; }
128
+ virtual Status status() const { return status_; }
129
+ virtual Slice key() const {
130
+ assert(Valid());
131
+ return key_;
132
+ }
133
+ virtual Slice value() const {
134
+ assert(Valid());
135
+ return value_;
136
+ }
137
+
138
+ virtual void Next() {
139
+ assert(Valid());
140
+ ParseNextKey();
141
+ }
142
+
143
+ virtual void Prev() {
144
+ assert(Valid());
145
+
146
+ // Scan backwards to a restart point before current_
147
+ const uint32_t original = current_;
148
+ while (GetRestartPoint(restart_index_) >= original) {
149
+ if (restart_index_ == 0) {
150
+ // No more entries
151
+ current_ = restarts_;
152
+ restart_index_ = num_restarts_;
153
+ return;
154
+ }
155
+ restart_index_--;
156
+ }
157
+
158
+ SeekToRestartPoint(restart_index_);
159
+ do {
160
+ // Loop until end of current entry hits the start of original entry
161
+ } while (ParseNextKey() && NextEntryOffset() < original);
162
+ }
163
+
164
+ virtual void Seek(const Slice& target) {
165
+ // Binary search in restart array to find the first restart point
166
+ // with a key >= target
167
+ uint32_t left = 0;
168
+ uint32_t right = num_restarts_ - 1;
169
+ while (left < right) {
170
+ uint32_t mid = (left + right + 1) / 2;
171
+ uint32_t region_offset = GetRestartPoint(mid);
172
+ uint32_t shared, non_shared, value_length;
173
+ const char* key_ptr = DecodeEntry(data_ + region_offset,
174
+ data_ + restarts_,
175
+ &shared, &non_shared, &value_length);
176
+ if (key_ptr == NULL || (shared != 0)) {
177
+ CorruptionError();
178
+ return;
179
+ }
180
+ Slice mid_key(key_ptr, non_shared);
181
+ if (Compare(mid_key, target) < 0) {
182
+ // Key at "mid" is smaller than "target". Therefore all
183
+ // blocks before "mid" are uninteresting.
184
+ left = mid;
185
+ } else {
186
+ // Key at "mid" is >= "target". Therefore all blocks at or
187
+ // after "mid" are uninteresting.
188
+ right = mid - 1;
189
+ }
190
+ }
191
+
192
+ // Linear search (within restart block) for first key >= target
193
+ SeekToRestartPoint(left);
194
+ while (true) {
195
+ if (!ParseNextKey()) {
196
+ return;
197
+ }
198
+ if (Compare(key_, target) >= 0) {
199
+ return;
200
+ }
201
+ }
202
+ }
203
+
204
+ virtual void SeekToFirst() {
205
+ SeekToRestartPoint(0);
206
+ ParseNextKey();
207
+ }
208
+
209
+ virtual void SeekToLast() {
210
+ SeekToRestartPoint(num_restarts_ - 1);
211
+ while (ParseNextKey() && NextEntryOffset() < restarts_) {
212
+ // Keep skipping
213
+ }
214
+ }
215
+
216
+ private:
217
+ void CorruptionError() {
218
+ current_ = restarts_;
219
+ restart_index_ = num_restarts_;
220
+ status_ = Status::Corruption("bad entry in block");
221
+ key_.clear();
222
+ value_.clear();
223
+ }
224
+
225
+ bool ParseNextKey() {
226
+ current_ = NextEntryOffset();
227
+ const char* p = data_ + current_;
228
+ const char* limit = data_ + restarts_; // Restarts come right after data
229
+ if (p >= limit) {
230
+ // No more entries to return. Mark as invalid.
231
+ current_ = restarts_;
232
+ restart_index_ = num_restarts_;
233
+ return false;
234
+ }
235
+
236
+ // Decode next entry
237
+ uint32_t shared, non_shared, value_length;
238
+ p = DecodeEntry(p, limit, &shared, &non_shared, &value_length);
239
+ if (p == NULL || key_.size() < shared) {
240
+ CorruptionError();
241
+ return false;
242
+ } else {
243
+ key_.resize(shared);
244
+ key_.append(p, non_shared);
245
+ value_ = Slice(p + non_shared, value_length);
246
+ while (restart_index_ + 1 < num_restarts_ &&
247
+ GetRestartPoint(restart_index_ + 1) < current_) {
248
+ ++restart_index_;
249
+ }
250
+ return true;
251
+ }
252
+ }
253
+ };
254
+
255
+ Iterator* Block::NewIterator(const Comparator* cmp) {
256
+ if (size_ < 2*sizeof(uint32_t)) {
257
+ return NewErrorIterator(Status::Corruption("bad block contents"));
258
+ }
259
+ const uint32_t num_restarts = NumRestarts();
260
+ if (num_restarts == 0) {
261
+ return NewEmptyIterator();
262
+ } else {
263
+ return new Iter(cmp, data_, restart_offset_, num_restarts);
264
+ }
265
+ }
266
+
267
+ } // namespace leveldb
@@ -0,0 +1,44 @@
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_TABLE_BLOCK_H_
6
+ #define STORAGE_LEVELDB_TABLE_BLOCK_H_
7
+
8
+ #include <stddef.h>
9
+ #include <stdint.h>
10
+ #include "leveldb/iterator.h"
11
+
12
+ namespace leveldb {
13
+
14
+ struct BlockContents;
15
+ class Comparator;
16
+
17
+ class Block {
18
+ public:
19
+ // Initialize the block with the specified contents.
20
+ explicit Block(const BlockContents& contents);
21
+
22
+ ~Block();
23
+
24
+ size_t size() const { return size_; }
25
+ Iterator* NewIterator(const Comparator* comparator);
26
+
27
+ private:
28
+ uint32_t NumRestarts() const;
29
+
30
+ const char* data_;
31
+ size_t size_;
32
+ uint32_t restart_offset_; // Offset in data_ of restart array
33
+ bool owned_; // Block owns data_[]
34
+
35
+ // No copying allowed
36
+ Block(const Block&);
37
+ void operator=(const Block&);
38
+
39
+ class Iter;
40
+ };
41
+
42
+ } // namespace leveldb
43
+
44
+ #endif // STORAGE_LEVELDB_TABLE_BLOCK_H_
@@ -0,0 +1,109 @@
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
+ // BlockBuilder generates blocks where keys are prefix-compressed:
6
+ //
7
+ // When we store a key, we drop the prefix shared with the previous
8
+ // string. This helps reduce the space requirement significantly.
9
+ // Furthermore, once every K keys, we do not apply the prefix
10
+ // compression and store the entire key. We call this a "restart
11
+ // point". The tail end of the block stores the offsets of all of the
12
+ // restart points, and can be used to do a binary search when looking
13
+ // for a particular key. Values are stored as-is (without compression)
14
+ // immediately following the corresponding key.
15
+ //
16
+ // An entry for a particular key-value pair has the form:
17
+ // shared_bytes: varint32
18
+ // unshared_bytes: varint32
19
+ // value_length: varint32
20
+ // key_delta: char[unshared_bytes]
21
+ // value: char[value_length]
22
+ // shared_bytes == 0 for restart points.
23
+ //
24
+ // The trailer of the block has the form:
25
+ // restarts: uint32[num_restarts]
26
+ // num_restarts: uint32
27
+ // restarts[i] contains the offset within the block of the ith restart point.
28
+
29
+ #include "table/block_builder.h"
30
+
31
+ #include <algorithm>
32
+ #include <assert.h>
33
+ #include "leveldb/comparator.h"
34
+ #include "leveldb/table_builder.h"
35
+ #include "util/coding.h"
36
+
37
+ namespace leveldb {
38
+
39
+ BlockBuilder::BlockBuilder(const Options* options)
40
+ : options_(options),
41
+ restarts_(),
42
+ counter_(0),
43
+ finished_(false) {
44
+ assert(options->block_restart_interval >= 1);
45
+ restarts_.push_back(0); // First restart point is at offset 0
46
+ }
47
+
48
+ void BlockBuilder::Reset() {
49
+ buffer_.clear();
50
+ restarts_.clear();
51
+ restarts_.push_back(0); // First restart point is at offset 0
52
+ counter_ = 0;
53
+ finished_ = false;
54
+ last_key_.clear();
55
+ }
56
+
57
+ size_t BlockBuilder::CurrentSizeEstimate() const {
58
+ return (buffer_.size() + // Raw data buffer
59
+ restarts_.size() * sizeof(uint32_t) + // Restart array
60
+ sizeof(uint32_t)); // Restart array length
61
+ }
62
+
63
+ Slice BlockBuilder::Finish() {
64
+ // Append restart array
65
+ for (size_t i = 0; i < restarts_.size(); i++) {
66
+ PutFixed32(&buffer_, restarts_[i]);
67
+ }
68
+ PutFixed32(&buffer_, restarts_.size());
69
+ finished_ = true;
70
+ return Slice(buffer_);
71
+ }
72
+
73
+ void BlockBuilder::Add(const Slice& key, const Slice& value) {
74
+ Slice last_key_piece(last_key_);
75
+ assert(!finished_);
76
+ assert(counter_ <= options_->block_restart_interval);
77
+ assert(buffer_.empty() // No values yet?
78
+ || options_->comparator->Compare(key, last_key_piece) > 0);
79
+ size_t shared = 0;
80
+ if (counter_ < options_->block_restart_interval) {
81
+ // See how much sharing to do with previous string
82
+ const size_t min_length = std::min(last_key_piece.size(), key.size());
83
+ while ((shared < min_length) && (last_key_piece[shared] == key[shared])) {
84
+ shared++;
85
+ }
86
+ } else {
87
+ // Restart compression
88
+ restarts_.push_back(buffer_.size());
89
+ counter_ = 0;
90
+ }
91
+ const size_t non_shared = key.size() - shared;
92
+
93
+ // Add "<shared><non_shared><value_size>" to buffer_
94
+ PutVarint32(&buffer_, shared);
95
+ PutVarint32(&buffer_, non_shared);
96
+ PutVarint32(&buffer_, value.size());
97
+
98
+ // Add string delta to buffer_ followed by value
99
+ buffer_.append(key.data() + shared, non_shared);
100
+ buffer_.append(value.data(), value.size());
101
+
102
+ // Update state
103
+ last_key_.resize(shared);
104
+ last_key_.append(key.data() + shared, non_shared);
105
+ assert(Slice(last_key_) == key);
106
+ counter_++;
107
+ }
108
+
109
+ } // namespace leveldb
@@ -0,0 +1,57 @@
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_TABLE_BLOCK_BUILDER_H_
6
+ #define STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_
7
+
8
+ #include <vector>
9
+
10
+ #include <stdint.h>
11
+ #include "leveldb/slice.h"
12
+
13
+ namespace leveldb {
14
+
15
+ struct Options;
16
+
17
+ class BlockBuilder {
18
+ public:
19
+ explicit BlockBuilder(const Options* options);
20
+
21
+ // Reset the contents as if the BlockBuilder was just constructed.
22
+ void Reset();
23
+
24
+ // REQUIRES: Finish() has not been callled since the last call to Reset().
25
+ // REQUIRES: key is larger than any previously added key
26
+ void Add(const Slice& key, const Slice& value);
27
+
28
+ // Finish building the block and return a slice that refers to the
29
+ // block contents. The returned slice will remain valid for the
30
+ // lifetime of this builder or until Reset() is called.
31
+ Slice Finish();
32
+
33
+ // Returns an estimate of the current (uncompressed) size of the block
34
+ // we are building.
35
+ size_t CurrentSizeEstimate() const;
36
+
37
+ // Return true iff no entries have been added since the last Reset()
38
+ bool empty() const {
39
+ return buffer_.empty();
40
+ }
41
+
42
+ private:
43
+ const Options* options_;
44
+ std::string buffer_; // Destination buffer
45
+ std::vector<uint32_t> restarts_; // Restart points
46
+ int counter_; // Number of entries emitted since restart
47
+ bool finished_; // Has Finish() been called?
48
+ std::string last_key_;
49
+
50
+ // No copying allowed
51
+ BlockBuilder(const BlockBuilder&);
52
+ void operator=(const BlockBuilder&);
53
+ };
54
+
55
+ } // namespace leveldb
56
+
57
+ #endif // STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_