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,68 @@
1
+ // Copyright (c) 2012 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
+ // A filter block is stored near the end of a Table file. It contains
6
+ // filters (e.g., bloom filters) for all data blocks in the table combined
7
+ // into a single filter block.
8
+
9
+ #ifndef STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_
10
+ #define STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_
11
+
12
+ #include <stddef.h>
13
+ #include <stdint.h>
14
+ #include <string>
15
+ #include <vector>
16
+ #include "leveldb/slice.h"
17
+ #include "util/hash.h"
18
+
19
+ namespace leveldb {
20
+
21
+ class FilterPolicy;
22
+
23
+ // A FilterBlockBuilder is used to construct all of the filters for a
24
+ // particular Table. It generates a single string which is stored as
25
+ // a special block in the Table.
26
+ //
27
+ // The sequence of calls to FilterBlockBuilder must match the regexp:
28
+ // (StartBlock AddKey*)* Finish
29
+ class FilterBlockBuilder {
30
+ public:
31
+ explicit FilterBlockBuilder(const FilterPolicy*);
32
+
33
+ void StartBlock(uint64_t block_offset);
34
+ void AddKey(const Slice& key);
35
+ Slice Finish();
36
+
37
+ private:
38
+ void GenerateFilter();
39
+
40
+ const FilterPolicy* policy_;
41
+ std::string keys_; // Flattened key contents
42
+ std::vector<size_t> start_; // Starting index in keys_ of each key
43
+ std::string result_; // Filter data computed so far
44
+ std::vector<Slice> tmp_keys_; // policy_->CreateFilter() argument
45
+ std::vector<uint32_t> filter_offsets_;
46
+
47
+ // No copying allowed
48
+ FilterBlockBuilder(const FilterBlockBuilder&);
49
+ void operator=(const FilterBlockBuilder&);
50
+ };
51
+
52
+ class FilterBlockReader {
53
+ public:
54
+ // REQUIRES: "contents" and *policy must stay live while *this is live.
55
+ FilterBlockReader(const FilterPolicy* policy, const Slice& contents);
56
+ bool KeyMayMatch(uint64_t block_offset, const Slice& key);
57
+
58
+ private:
59
+ const FilterPolicy* policy_;
60
+ const char* data_; // Pointer to filter data (at block-start)
61
+ const char* offset_; // Pointer to beginning of offset array (at block-end)
62
+ size_t num_; // Number of entries in offset array
63
+ size_t base_lg_; // Encoding parameter (see kFilterBaseLg in .cc file)
64
+ };
65
+
66
+ }
67
+
68
+ #endif // STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_
@@ -0,0 +1,128 @@
1
+ // Copyright (c) 2012 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 "table/filter_block.h"
6
+
7
+ #include "leveldb/filter_policy.h"
8
+ #include "util/coding.h"
9
+ #include "util/hash.h"
10
+ #include "util/logging.h"
11
+ #include "util/testharness.h"
12
+ #include "util/testutil.h"
13
+
14
+ namespace leveldb {
15
+
16
+ // For testing: emit an array with one hash value per key
17
+ class TestHashFilter : public FilterPolicy {
18
+ public:
19
+ virtual const char* Name() const {
20
+ return "TestHashFilter";
21
+ }
22
+
23
+ virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const {
24
+ for (int i = 0; i < n; i++) {
25
+ uint32_t h = Hash(keys[i].data(), keys[i].size(), 1);
26
+ PutFixed32(dst, h);
27
+ }
28
+ }
29
+
30
+ virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const {
31
+ uint32_t h = Hash(key.data(), key.size(), 1);
32
+ for (int i = 0; i + 4 <= filter.size(); i += 4) {
33
+ if (h == DecodeFixed32(filter.data() + i)) {
34
+ return true;
35
+ }
36
+ }
37
+ return false;
38
+ }
39
+ };
40
+
41
+ class FilterBlockTest {
42
+ public:
43
+ TestHashFilter policy_;
44
+ };
45
+
46
+ TEST(FilterBlockTest, EmptyBuilder) {
47
+ FilterBlockBuilder builder(&policy_);
48
+ Slice block = builder.Finish();
49
+ ASSERT_EQ("\\x00\\x00\\x00\\x00\\x0b", EscapeString(block));
50
+ FilterBlockReader reader(&policy_, block);
51
+ ASSERT_TRUE(reader.KeyMayMatch(0, "foo"));
52
+ ASSERT_TRUE(reader.KeyMayMatch(100000, "foo"));
53
+ }
54
+
55
+ TEST(FilterBlockTest, SingleChunk) {
56
+ FilterBlockBuilder builder(&policy_);
57
+ builder.StartBlock(100);
58
+ builder.AddKey("foo");
59
+ builder.AddKey("bar");
60
+ builder.AddKey("box");
61
+ builder.StartBlock(200);
62
+ builder.AddKey("box");
63
+ builder.StartBlock(300);
64
+ builder.AddKey("hello");
65
+ Slice block = builder.Finish();
66
+ FilterBlockReader reader(&policy_, block);
67
+ ASSERT_TRUE(reader.KeyMayMatch(100, "foo"));
68
+ ASSERT_TRUE(reader.KeyMayMatch(100, "bar"));
69
+ ASSERT_TRUE(reader.KeyMayMatch(100, "box"));
70
+ ASSERT_TRUE(reader.KeyMayMatch(100, "hello"));
71
+ ASSERT_TRUE(reader.KeyMayMatch(100, "foo"));
72
+ ASSERT_TRUE(! reader.KeyMayMatch(100, "missing"));
73
+ ASSERT_TRUE(! reader.KeyMayMatch(100, "other"));
74
+ }
75
+
76
+ TEST(FilterBlockTest, MultiChunk) {
77
+ FilterBlockBuilder builder(&policy_);
78
+
79
+ // First filter
80
+ builder.StartBlock(0);
81
+ builder.AddKey("foo");
82
+ builder.StartBlock(2000);
83
+ builder.AddKey("bar");
84
+
85
+ // Second filter
86
+ builder.StartBlock(3100);
87
+ builder.AddKey("box");
88
+
89
+ // Third filter is empty
90
+
91
+ // Last filter
92
+ builder.StartBlock(9000);
93
+ builder.AddKey("box");
94
+ builder.AddKey("hello");
95
+
96
+ Slice block = builder.Finish();
97
+ FilterBlockReader reader(&policy_, block);
98
+
99
+ // Check first filter
100
+ ASSERT_TRUE(reader.KeyMayMatch(0, "foo"));
101
+ ASSERT_TRUE(reader.KeyMayMatch(2000, "bar"));
102
+ ASSERT_TRUE(! reader.KeyMayMatch(0, "box"));
103
+ ASSERT_TRUE(! reader.KeyMayMatch(0, "hello"));
104
+
105
+ // Check second filter
106
+ ASSERT_TRUE(reader.KeyMayMatch(3100, "box"));
107
+ ASSERT_TRUE(! reader.KeyMayMatch(3100, "foo"));
108
+ ASSERT_TRUE(! reader.KeyMayMatch(3100, "bar"));
109
+ ASSERT_TRUE(! reader.KeyMayMatch(3100, "hello"));
110
+
111
+ // Check third filter (empty)
112
+ ASSERT_TRUE(! reader.KeyMayMatch(4100, "foo"));
113
+ ASSERT_TRUE(! reader.KeyMayMatch(4100, "bar"));
114
+ ASSERT_TRUE(! reader.KeyMayMatch(4100, "box"));
115
+ ASSERT_TRUE(! reader.KeyMayMatch(4100, "hello"));
116
+
117
+ // Check last filter
118
+ ASSERT_TRUE(reader.KeyMayMatch(9000, "box"));
119
+ ASSERT_TRUE(reader.KeyMayMatch(9000, "hello"));
120
+ ASSERT_TRUE(! reader.KeyMayMatch(9000, "foo"));
121
+ ASSERT_TRUE(! reader.KeyMayMatch(9000, "bar"));
122
+ }
123
+
124
+ } // namespace leveldb
125
+
126
+ int main(int argc, char** argv) {
127
+ return leveldb::test::RunAllTests();
128
+ }
@@ -0,0 +1,145 @@
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 "table/format.h"
6
+
7
+ #include "leveldb/env.h"
8
+ #include "port/port.h"
9
+ #include "table/block.h"
10
+ #include "util/coding.h"
11
+ #include "util/crc32c.h"
12
+
13
+ namespace leveldb {
14
+
15
+ void BlockHandle::EncodeTo(std::string* dst) const {
16
+ // Sanity check that all fields have been set
17
+ assert(offset_ != ~static_cast<uint64_t>(0));
18
+ assert(size_ != ~static_cast<uint64_t>(0));
19
+ PutVarint64(dst, offset_);
20
+ PutVarint64(dst, size_);
21
+ }
22
+
23
+ Status BlockHandle::DecodeFrom(Slice* input) {
24
+ if (GetVarint64(input, &offset_) &&
25
+ GetVarint64(input, &size_)) {
26
+ return Status::OK();
27
+ } else {
28
+ return Status::Corruption("bad block handle");
29
+ }
30
+ }
31
+
32
+ void Footer::EncodeTo(std::string* dst) const {
33
+ #ifndef NDEBUG
34
+ const size_t original_size = dst->size();
35
+ #endif
36
+ metaindex_handle_.EncodeTo(dst);
37
+ index_handle_.EncodeTo(dst);
38
+ dst->resize(2 * BlockHandle::kMaxEncodedLength); // Padding
39
+ PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber & 0xffffffffu));
40
+ PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber >> 32));
41
+ assert(dst->size() == original_size + kEncodedLength);
42
+ }
43
+
44
+ Status Footer::DecodeFrom(Slice* input) {
45
+ const char* magic_ptr = input->data() + kEncodedLength - 8;
46
+ const uint32_t magic_lo = DecodeFixed32(magic_ptr);
47
+ const uint32_t magic_hi = DecodeFixed32(magic_ptr + 4);
48
+ const uint64_t magic = ((static_cast<uint64_t>(magic_hi) << 32) |
49
+ (static_cast<uint64_t>(magic_lo)));
50
+ if (magic != kTableMagicNumber) {
51
+ return Status::InvalidArgument("not an sstable (bad magic number)");
52
+ }
53
+
54
+ Status result = metaindex_handle_.DecodeFrom(input);
55
+ if (result.ok()) {
56
+ result = index_handle_.DecodeFrom(input);
57
+ }
58
+ if (result.ok()) {
59
+ // We skip over any leftover data (just padding for now) in "input"
60
+ const char* end = magic_ptr + 8;
61
+ *input = Slice(end, input->data() + input->size() - end);
62
+ }
63
+ return result;
64
+ }
65
+
66
+ Status ReadBlock(RandomAccessFile* file,
67
+ const ReadOptions& options,
68
+ const BlockHandle& handle,
69
+ BlockContents* result) {
70
+ result->data = Slice();
71
+ result->cachable = false;
72
+ result->heap_allocated = false;
73
+
74
+ // Read the block contents as well as the type/crc footer.
75
+ // See table_builder.cc for the code that built this structure.
76
+ size_t n = static_cast<size_t>(handle.size());
77
+ char* buf = new char[n + kBlockTrailerSize];
78
+ Slice contents;
79
+ Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf);
80
+ if (!s.ok()) {
81
+ delete[] buf;
82
+ return s;
83
+ }
84
+ if (contents.size() != n + kBlockTrailerSize) {
85
+ delete[] buf;
86
+ return Status::Corruption("truncated block read");
87
+ }
88
+
89
+ // Check the crc of the type and the block contents
90
+ const char* data = contents.data(); // Pointer to where Read put the data
91
+ if (options.verify_checksums) {
92
+ const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1));
93
+ const uint32_t actual = crc32c::Value(data, n + 1);
94
+ if (actual != crc) {
95
+ delete[] buf;
96
+ s = Status::Corruption("block checksum mismatch");
97
+ return s;
98
+ }
99
+ }
100
+
101
+ switch (data[n]) {
102
+ case kNoCompression:
103
+ if (data != buf) {
104
+ // File implementation gave us pointer to some other data.
105
+ // Use it directly under the assumption that it will be live
106
+ // while the file is open.
107
+ delete[] buf;
108
+ result->data = Slice(data, n);
109
+ result->heap_allocated = false;
110
+ result->cachable = false; // Do not double-cache
111
+ } else {
112
+ result->data = Slice(buf, n);
113
+ result->heap_allocated = true;
114
+ result->cachable = true;
115
+ }
116
+
117
+ // Ok
118
+ break;
119
+ case kSnappyCompression: {
120
+ size_t ulength = 0;
121
+ if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
122
+ delete[] buf;
123
+ return Status::Corruption("corrupted compressed block contents");
124
+ }
125
+ char* ubuf = new char[ulength];
126
+ if (!port::Snappy_Uncompress(data, n, ubuf)) {
127
+ delete[] buf;
128
+ delete[] ubuf;
129
+ return Status::Corruption("corrupted compressed block contents");
130
+ }
131
+ delete[] buf;
132
+ result->data = Slice(ubuf, ulength);
133
+ result->heap_allocated = true;
134
+ result->cachable = true;
135
+ break;
136
+ }
137
+ default:
138
+ delete[] buf;
139
+ return Status::Corruption("bad block type");
140
+ }
141
+
142
+ return Status::OK();
143
+ }
144
+
145
+ } // namespace leveldb
@@ -0,0 +1,108 @@
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_FORMAT_H_
6
+ #define STORAGE_LEVELDB_TABLE_FORMAT_H_
7
+
8
+ #include <string>
9
+ #include <stdint.h>
10
+ #include "leveldb/slice.h"
11
+ #include "leveldb/status.h"
12
+ #include "leveldb/table_builder.h"
13
+
14
+ namespace leveldb {
15
+
16
+ class Block;
17
+ class RandomAccessFile;
18
+ struct ReadOptions;
19
+
20
+ // BlockHandle is a pointer to the extent of a file that stores a data
21
+ // block or a meta block.
22
+ class BlockHandle {
23
+ public:
24
+ BlockHandle();
25
+
26
+ // The offset of the block in the file.
27
+ uint64_t offset() const { return offset_; }
28
+ void set_offset(uint64_t offset) { offset_ = offset; }
29
+
30
+ // The size of the stored block
31
+ uint64_t size() const { return size_; }
32
+ void set_size(uint64_t size) { size_ = size; }
33
+
34
+ void EncodeTo(std::string* dst) const;
35
+ Status DecodeFrom(Slice* input);
36
+
37
+ // Maximum encoding length of a BlockHandle
38
+ enum { kMaxEncodedLength = 10 + 10 };
39
+
40
+ private:
41
+ uint64_t offset_;
42
+ uint64_t size_;
43
+ };
44
+
45
+ // Footer encapsulates the fixed information stored at the tail
46
+ // end of every table file.
47
+ class Footer {
48
+ public:
49
+ Footer() { }
50
+
51
+ // The block handle for the metaindex block of the table
52
+ const BlockHandle& metaindex_handle() const { return metaindex_handle_; }
53
+ void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; }
54
+
55
+ // The block handle for the index block of the table
56
+ const BlockHandle& index_handle() const {
57
+ return index_handle_;
58
+ }
59
+ void set_index_handle(const BlockHandle& h) {
60
+ index_handle_ = h;
61
+ }
62
+
63
+ void EncodeTo(std::string* dst) const;
64
+ Status DecodeFrom(Slice* input);
65
+
66
+ // Encoded length of a Footer. Note that the serialization of a
67
+ // Footer will always occupy exactly this many bytes. It consists
68
+ // of two block handles and a magic number.
69
+ enum {
70
+ kEncodedLength = 2*BlockHandle::kMaxEncodedLength + 8
71
+ };
72
+
73
+ private:
74
+ BlockHandle metaindex_handle_;
75
+ BlockHandle index_handle_;
76
+ };
77
+
78
+ // kTableMagicNumber was picked by running
79
+ // echo http://code.google.com/p/leveldb/ | sha1sum
80
+ // and taking the leading 64 bits.
81
+ static const uint64_t kTableMagicNumber = 0xdb4775248b80fb57ull;
82
+
83
+ // 1-byte type + 32-bit crc
84
+ static const size_t kBlockTrailerSize = 5;
85
+
86
+ struct BlockContents {
87
+ Slice data; // Actual contents of data
88
+ bool cachable; // True iff data can be cached
89
+ bool heap_allocated; // True iff caller should delete[] data.data()
90
+ };
91
+
92
+ // Read the block identified by "handle" from "file". On failure
93
+ // return non-OK. On success fill *result and return OK.
94
+ extern Status ReadBlock(RandomAccessFile* file,
95
+ const ReadOptions& options,
96
+ const BlockHandle& handle,
97
+ BlockContents* result);
98
+
99
+ // Implementation details follow. Clients should ignore,
100
+
101
+ inline BlockHandle::BlockHandle()
102
+ : offset_(~static_cast<uint64_t>(0)),
103
+ size_(~static_cast<uint64_t>(0)) {
104
+ }
105
+
106
+ } // namespace leveldb
107
+
108
+ #endif // STORAGE_LEVELDB_TABLE_FORMAT_H_
@@ -0,0 +1,67 @@
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 "leveldb/iterator.h"
6
+
7
+ namespace leveldb {
8
+
9
+ Iterator::Iterator() {
10
+ cleanup_.function = NULL;
11
+ cleanup_.next = NULL;
12
+ }
13
+
14
+ Iterator::~Iterator() {
15
+ if (cleanup_.function != NULL) {
16
+ (*cleanup_.function)(cleanup_.arg1, cleanup_.arg2);
17
+ for (Cleanup* c = cleanup_.next; c != NULL; ) {
18
+ (*c->function)(c->arg1, c->arg2);
19
+ Cleanup* next = c->next;
20
+ delete c;
21
+ c = next;
22
+ }
23
+ }
24
+ }
25
+
26
+ void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) {
27
+ assert(func != NULL);
28
+ Cleanup* c;
29
+ if (cleanup_.function == NULL) {
30
+ c = &cleanup_;
31
+ } else {
32
+ c = new Cleanup;
33
+ c->next = cleanup_.next;
34
+ cleanup_.next = c;
35
+ }
36
+ c->function = func;
37
+ c->arg1 = arg1;
38
+ c->arg2 = arg2;
39
+ }
40
+
41
+ namespace {
42
+ class EmptyIterator : public Iterator {
43
+ public:
44
+ EmptyIterator(const Status& s) : status_(s) { }
45
+ virtual bool Valid() const { return false; }
46
+ virtual void Seek(const Slice& target) { }
47
+ virtual void SeekToFirst() { }
48
+ virtual void SeekToLast() { }
49
+ virtual void Next() { assert(false); }
50
+ virtual void Prev() { assert(false); }
51
+ Slice key() const { assert(false); return Slice(); }
52
+ Slice value() const { assert(false); return Slice(); }
53
+ virtual Status status() const { return status_; }
54
+ private:
55
+ Status status_;
56
+ };
57
+ } // namespace
58
+
59
+ Iterator* NewEmptyIterator() {
60
+ return new EmptyIterator(Status::OK());
61
+ }
62
+
63
+ Iterator* NewErrorIterator(const Status& status) {
64
+ return new EmptyIterator(status);
65
+ }
66
+
67
+ } // namespace leveldb
@@ -0,0 +1,63 @@
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_ITERATOR_WRAPPER_H_
6
+ #define STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_
7
+
8
+ namespace leveldb {
9
+
10
+ // A internal wrapper class with an interface similar to Iterator that
11
+ // caches the valid() and key() results for an underlying iterator.
12
+ // This can help avoid virtual function calls and also gives better
13
+ // cache locality.
14
+ class IteratorWrapper {
15
+ public:
16
+ IteratorWrapper(): iter_(NULL), valid_(false) { }
17
+ explicit IteratorWrapper(Iterator* iter): iter_(NULL) {
18
+ Set(iter);
19
+ }
20
+ ~IteratorWrapper() { delete iter_; }
21
+ Iterator* iter() const { return iter_; }
22
+
23
+ // Takes ownership of "iter" and will delete it when destroyed, or
24
+ // when Set() is invoked again.
25
+ void Set(Iterator* iter) {
26
+ delete iter_;
27
+ iter_ = iter;
28
+ if (iter_ == NULL) {
29
+ valid_ = false;
30
+ } else {
31
+ Update();
32
+ }
33
+ }
34
+
35
+
36
+ // Iterator interface methods
37
+ bool Valid() const { return valid_; }
38
+ Slice key() const { assert(Valid()); return key_; }
39
+ Slice value() const { assert(Valid()); return iter_->value(); }
40
+ // Methods below require iter() != NULL
41
+ Status status() const { assert(iter_); return iter_->status(); }
42
+ void Next() { assert(iter_); iter_->Next(); Update(); }
43
+ void Prev() { assert(iter_); iter_->Prev(); Update(); }
44
+ void Seek(const Slice& k) { assert(iter_); iter_->Seek(k); Update(); }
45
+ void SeekToFirst() { assert(iter_); iter_->SeekToFirst(); Update(); }
46
+ void SeekToLast() { assert(iter_); iter_->SeekToLast(); Update(); }
47
+
48
+ private:
49
+ void Update() {
50
+ valid_ = iter_->Valid();
51
+ if (valid_) {
52
+ key_ = iter_->key();
53
+ }
54
+ }
55
+
56
+ Iterator* iter_;
57
+ bool valid_;
58
+ Slice key_;
59
+ };
60
+
61
+ } // namespace leveldb
62
+
63
+ #endif // STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_