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,104 @@
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
+ // Endian-neutral encoding:
6
+ // * Fixed-length numbers are encoded with least-significant byte first
7
+ // * In addition we support variable length "varint" encoding
8
+ // * Strings are encoded prefixed by their length in varint format
9
+
10
+ #ifndef STORAGE_LEVELDB_UTIL_CODING_H_
11
+ #define STORAGE_LEVELDB_UTIL_CODING_H_
12
+
13
+ #include <stdint.h>
14
+ #include <string.h>
15
+ #include <string>
16
+ #include "leveldb/slice.h"
17
+ #include "port/port.h"
18
+
19
+ namespace leveldb {
20
+
21
+ // Standard Put... routines append to a string
22
+ extern void PutFixed32(std::string* dst, uint32_t value);
23
+ extern void PutFixed64(std::string* dst, uint64_t value);
24
+ extern void PutVarint32(std::string* dst, uint32_t value);
25
+ extern void PutVarint64(std::string* dst, uint64_t value);
26
+ extern void PutLengthPrefixedSlice(std::string* dst, const Slice& value);
27
+
28
+ // Standard Get... routines parse a value from the beginning of a Slice
29
+ // and advance the slice past the parsed value.
30
+ extern bool GetVarint32(Slice* input, uint32_t* value);
31
+ extern bool GetVarint64(Slice* input, uint64_t* value);
32
+ extern bool GetLengthPrefixedSlice(Slice* input, Slice* result);
33
+
34
+ // Pointer-based variants of GetVarint... These either store a value
35
+ // in *v and return a pointer just past the parsed value, or return
36
+ // NULL on error. These routines only look at bytes in the range
37
+ // [p..limit-1]
38
+ extern const char* GetVarint32Ptr(const char* p,const char* limit, uint32_t* v);
39
+ extern const char* GetVarint64Ptr(const char* p,const char* limit, uint64_t* v);
40
+
41
+ // Returns the length of the varint32 or varint64 encoding of "v"
42
+ extern int VarintLength(uint64_t v);
43
+
44
+ // Lower-level versions of Put... that write directly into a character buffer
45
+ // REQUIRES: dst has enough space for the value being written
46
+ extern void EncodeFixed32(char* dst, uint32_t value);
47
+ extern void EncodeFixed64(char* dst, uint64_t value);
48
+
49
+ // Lower-level versions of Put... that write directly into a character buffer
50
+ // and return a pointer just past the last byte written.
51
+ // REQUIRES: dst has enough space for the value being written
52
+ extern char* EncodeVarint32(char* dst, uint32_t value);
53
+ extern char* EncodeVarint64(char* dst, uint64_t value);
54
+
55
+ // Lower-level versions of Get... that read directly from a character buffer
56
+ // without any bounds checking.
57
+
58
+ inline uint32_t DecodeFixed32(const char* ptr) {
59
+ if (port::kLittleEndian) {
60
+ // Load the raw bytes
61
+ uint32_t result;
62
+ memcpy(&result, ptr, sizeof(result)); // gcc optimizes this to a plain load
63
+ return result;
64
+ } else {
65
+ return ((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0])))
66
+ | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) << 8)
67
+ | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[2])) << 16)
68
+ | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) << 24));
69
+ }
70
+ }
71
+
72
+ inline uint64_t DecodeFixed64(const char* ptr) {
73
+ if (port::kLittleEndian) {
74
+ // Load the raw bytes
75
+ uint64_t result;
76
+ memcpy(&result, ptr, sizeof(result)); // gcc optimizes this to a plain load
77
+ return result;
78
+ } else {
79
+ uint64_t lo = DecodeFixed32(ptr);
80
+ uint64_t hi = DecodeFixed32(ptr + 4);
81
+ return (hi << 32) | lo;
82
+ }
83
+ }
84
+
85
+ // Internal routine for use by fallback path of GetVarint32Ptr
86
+ extern const char* GetVarint32PtrFallback(const char* p,
87
+ const char* limit,
88
+ uint32_t* value);
89
+ inline const char* GetVarint32Ptr(const char* p,
90
+ const char* limit,
91
+ uint32_t* value) {
92
+ if (p < limit) {
93
+ uint32_t result = *(reinterpret_cast<const unsigned char*>(p));
94
+ if ((result & 128) == 0) {
95
+ *value = result;
96
+ return p + 1;
97
+ }
98
+ }
99
+ return GetVarint32PtrFallback(p, limit, value);
100
+ }
101
+
102
+ } // namespace leveldb
103
+
104
+ #endif // STORAGE_LEVELDB_UTIL_CODING_H_
@@ -0,0 +1,196 @@
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 "util/coding.h"
6
+
7
+ #include "util/testharness.h"
8
+
9
+ namespace leveldb {
10
+
11
+ class Coding { };
12
+
13
+ TEST(Coding, Fixed32) {
14
+ std::string s;
15
+ for (uint32_t v = 0; v < 100000; v++) {
16
+ PutFixed32(&s, v);
17
+ }
18
+
19
+ const char* p = s.data();
20
+ for (uint32_t v = 0; v < 100000; v++) {
21
+ uint32_t actual = DecodeFixed32(p);
22
+ ASSERT_EQ(v, actual);
23
+ p += sizeof(uint32_t);
24
+ }
25
+ }
26
+
27
+ TEST(Coding, Fixed64) {
28
+ std::string s;
29
+ for (int power = 0; power <= 63; power++) {
30
+ uint64_t v = static_cast<uint64_t>(1) << power;
31
+ PutFixed64(&s, v - 1);
32
+ PutFixed64(&s, v + 0);
33
+ PutFixed64(&s, v + 1);
34
+ }
35
+
36
+ const char* p = s.data();
37
+ for (int power = 0; power <= 63; power++) {
38
+ uint64_t v = static_cast<uint64_t>(1) << power;
39
+ uint64_t actual;
40
+ actual = DecodeFixed64(p);
41
+ ASSERT_EQ(v-1, actual);
42
+ p += sizeof(uint64_t);
43
+
44
+ actual = DecodeFixed64(p);
45
+ ASSERT_EQ(v+0, actual);
46
+ p += sizeof(uint64_t);
47
+
48
+ actual = DecodeFixed64(p);
49
+ ASSERT_EQ(v+1, actual);
50
+ p += sizeof(uint64_t);
51
+ }
52
+ }
53
+
54
+ // Test that encoding routines generate little-endian encodings
55
+ TEST(Coding, EncodingOutput) {
56
+ std::string dst;
57
+ PutFixed32(&dst, 0x04030201);
58
+ ASSERT_EQ(4, dst.size());
59
+ ASSERT_EQ(0x01, static_cast<int>(dst[0]));
60
+ ASSERT_EQ(0x02, static_cast<int>(dst[1]));
61
+ ASSERT_EQ(0x03, static_cast<int>(dst[2]));
62
+ ASSERT_EQ(0x04, static_cast<int>(dst[3]));
63
+
64
+ dst.clear();
65
+ PutFixed64(&dst, 0x0807060504030201ull);
66
+ ASSERT_EQ(8, dst.size());
67
+ ASSERT_EQ(0x01, static_cast<int>(dst[0]));
68
+ ASSERT_EQ(0x02, static_cast<int>(dst[1]));
69
+ ASSERT_EQ(0x03, static_cast<int>(dst[2]));
70
+ ASSERT_EQ(0x04, static_cast<int>(dst[3]));
71
+ ASSERT_EQ(0x05, static_cast<int>(dst[4]));
72
+ ASSERT_EQ(0x06, static_cast<int>(dst[5]));
73
+ ASSERT_EQ(0x07, static_cast<int>(dst[6]));
74
+ ASSERT_EQ(0x08, static_cast<int>(dst[7]));
75
+ }
76
+
77
+ TEST(Coding, Varint32) {
78
+ std::string s;
79
+ for (uint32_t i = 0; i < (32 * 32); i++) {
80
+ uint32_t v = (i / 32) << (i % 32);
81
+ PutVarint32(&s, v);
82
+ }
83
+
84
+ const char* p = s.data();
85
+ const char* limit = p + s.size();
86
+ for (uint32_t i = 0; i < (32 * 32); i++) {
87
+ uint32_t expected = (i / 32) << (i % 32);
88
+ uint32_t actual;
89
+ const char* start = p;
90
+ p = GetVarint32Ptr(p, limit, &actual);
91
+ ASSERT_TRUE(p != NULL);
92
+ ASSERT_EQ(expected, actual);
93
+ ASSERT_EQ(VarintLength(actual), p - start);
94
+ }
95
+ ASSERT_EQ(p, s.data() + s.size());
96
+ }
97
+
98
+ TEST(Coding, Varint64) {
99
+ // Construct the list of values to check
100
+ std::vector<uint64_t> values;
101
+ // Some special values
102
+ values.push_back(0);
103
+ values.push_back(100);
104
+ values.push_back(~static_cast<uint64_t>(0));
105
+ values.push_back(~static_cast<uint64_t>(0) - 1);
106
+ for (uint32_t k = 0; k < 64; k++) {
107
+ // Test values near powers of two
108
+ const uint64_t power = 1ull << k;
109
+ values.push_back(power);
110
+ values.push_back(power-1);
111
+ values.push_back(power+1);
112
+ }
113
+
114
+ std::string s;
115
+ for (int i = 0; i < values.size(); i++) {
116
+ PutVarint64(&s, values[i]);
117
+ }
118
+
119
+ const char* p = s.data();
120
+ const char* limit = p + s.size();
121
+ for (int i = 0; i < values.size(); i++) {
122
+ ASSERT_TRUE(p < limit);
123
+ uint64_t actual;
124
+ const char* start = p;
125
+ p = GetVarint64Ptr(p, limit, &actual);
126
+ ASSERT_TRUE(p != NULL);
127
+ ASSERT_EQ(values[i], actual);
128
+ ASSERT_EQ(VarintLength(actual), p - start);
129
+ }
130
+ ASSERT_EQ(p, limit);
131
+
132
+ }
133
+
134
+ TEST(Coding, Varint32Overflow) {
135
+ uint32_t result;
136
+ std::string input("\x81\x82\x83\x84\x85\x11");
137
+ ASSERT_TRUE(GetVarint32Ptr(input.data(), input.data() + input.size(), &result)
138
+ == NULL);
139
+ }
140
+
141
+ TEST(Coding, Varint32Truncation) {
142
+ uint32_t large_value = (1u << 31) + 100;
143
+ std::string s;
144
+ PutVarint32(&s, large_value);
145
+ uint32_t result;
146
+ for (int len = 0; len < s.size() - 1; len++) {
147
+ ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + len, &result) == NULL);
148
+ }
149
+ ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + s.size(), &result) != NULL);
150
+ ASSERT_EQ(large_value, result);
151
+ }
152
+
153
+ TEST(Coding, Varint64Overflow) {
154
+ uint64_t result;
155
+ std::string input("\x81\x82\x83\x84\x85\x81\x82\x83\x84\x85\x11");
156
+ ASSERT_TRUE(GetVarint64Ptr(input.data(), input.data() + input.size(), &result)
157
+ == NULL);
158
+ }
159
+
160
+ TEST(Coding, Varint64Truncation) {
161
+ uint64_t large_value = (1ull << 63) + 100ull;
162
+ std::string s;
163
+ PutVarint64(&s, large_value);
164
+ uint64_t result;
165
+ for (int len = 0; len < s.size() - 1; len++) {
166
+ ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + len, &result) == NULL);
167
+ }
168
+ ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + s.size(), &result) != NULL);
169
+ ASSERT_EQ(large_value, result);
170
+ }
171
+
172
+ TEST(Coding, Strings) {
173
+ std::string s;
174
+ PutLengthPrefixedSlice(&s, Slice(""));
175
+ PutLengthPrefixedSlice(&s, Slice("foo"));
176
+ PutLengthPrefixedSlice(&s, Slice("bar"));
177
+ PutLengthPrefixedSlice(&s, Slice(std::string(200, 'x')));
178
+
179
+ Slice input(s);
180
+ Slice v;
181
+ ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));
182
+ ASSERT_EQ("", v.ToString());
183
+ ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));
184
+ ASSERT_EQ("foo", v.ToString());
185
+ ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));
186
+ ASSERT_EQ("bar", v.ToString());
187
+ ASSERT_TRUE(GetLengthPrefixedSlice(&input, &v));
188
+ ASSERT_EQ(std::string(200, 'x'), v.ToString());
189
+ ASSERT_EQ("", input.ToString());
190
+ }
191
+
192
+ } // namespace leveldb
193
+
194
+ int main(int argc, char** argv) {
195
+ return leveldb::test::RunAllTests();
196
+ }
@@ -0,0 +1,81 @@
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 <algorithm>
6
+ #include <stdint.h>
7
+ #include "leveldb/comparator.h"
8
+ #include "leveldb/slice.h"
9
+ #include "port/port.h"
10
+ #include "util/logging.h"
11
+
12
+ namespace leveldb {
13
+
14
+ Comparator::~Comparator() { }
15
+
16
+ namespace {
17
+ class BytewiseComparatorImpl : public Comparator {
18
+ public:
19
+ BytewiseComparatorImpl() { }
20
+
21
+ virtual const char* Name() const {
22
+ return "leveldb.BytewiseComparator";
23
+ }
24
+
25
+ virtual int Compare(const Slice& a, const Slice& b) const {
26
+ return a.compare(b);
27
+ }
28
+
29
+ virtual void FindShortestSeparator(
30
+ std::string* start,
31
+ const Slice& limit) const {
32
+ // Find length of common prefix
33
+ size_t min_length = std::min(start->size(), limit.size());
34
+ size_t diff_index = 0;
35
+ while ((diff_index < min_length) &&
36
+ ((*start)[diff_index] == limit[diff_index])) {
37
+ diff_index++;
38
+ }
39
+
40
+ if (diff_index >= min_length) {
41
+ // Do not shorten if one string is a prefix of the other
42
+ } else {
43
+ uint8_t diff_byte = static_cast<uint8_t>((*start)[diff_index]);
44
+ if (diff_byte < static_cast<uint8_t>(0xff) &&
45
+ diff_byte + 1 < static_cast<uint8_t>(limit[diff_index])) {
46
+ (*start)[diff_index]++;
47
+ start->resize(diff_index + 1);
48
+ assert(Compare(*start, limit) < 0);
49
+ }
50
+ }
51
+ }
52
+
53
+ virtual void FindShortSuccessor(std::string* key) const {
54
+ // Find first character that can be incremented
55
+ size_t n = key->size();
56
+ for (size_t i = 0; i < n; i++) {
57
+ const uint8_t byte = (*key)[i];
58
+ if (byte != static_cast<uint8_t>(0xff)) {
59
+ (*key)[i] = byte + 1;
60
+ key->resize(i+1);
61
+ return;
62
+ }
63
+ }
64
+ // *key is a run of 0xffs. Leave it alone.
65
+ }
66
+ };
67
+ } // namespace
68
+
69
+ static port::OnceType once = LEVELDB_ONCE_INIT;
70
+ static const Comparator* bytewise;
71
+
72
+ static void InitModule() {
73
+ bytewise = new BytewiseComparatorImpl;
74
+ }
75
+
76
+ const Comparator* BytewiseComparator() {
77
+ port::InitOnce(&once, InitModule);
78
+ return bytewise;
79
+ }
80
+
81
+ } // namespace leveldb