leveldb-ruby 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 (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,169 @@
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/cache.h"
6
+
7
+ #include <vector>
8
+ #include "util/coding.h"
9
+ #include "util/testharness.h"
10
+
11
+ namespace leveldb {
12
+
13
+ // Conversions between numeric keys/values and the types expected by Cache.
14
+ static std::string EncodeKey(int k) {
15
+ std::string result;
16
+ PutFixed32(&result, k);
17
+ return result;
18
+ }
19
+ static int DecodeKey(const Slice& k) {
20
+ assert(k.size() == 4);
21
+ return DecodeFixed32(k.data());
22
+ }
23
+ static void* EncodeValue(uintptr_t v) { return reinterpret_cast<void*>(v); }
24
+ static int DecodeValue(void* v) { return reinterpret_cast<uintptr_t>(v); }
25
+
26
+ class CacheTest {
27
+ public:
28
+ static CacheTest* current_;
29
+
30
+ static void Deleter(const Slice& key, void* v) {
31
+ current_->deleted_keys_.push_back(DecodeKey(key));
32
+ current_->deleted_values_.push_back(DecodeValue(v));
33
+ }
34
+
35
+ static const int kCacheSize = 100;
36
+ std::vector<int> deleted_keys_;
37
+ std::vector<int> deleted_values_;
38
+ Cache* cache_;
39
+
40
+ CacheTest() : cache_(NewLRUCache(kCacheSize)) {
41
+ current_ = this;
42
+ }
43
+
44
+ ~CacheTest() {
45
+ delete cache_;
46
+ }
47
+
48
+ int Lookup(int key) {
49
+ Cache::Handle* handle = cache_->Lookup(EncodeKey(key));
50
+ const int r = (handle == NULL) ? -1 : DecodeValue(cache_->Value(handle));
51
+ if (handle != NULL) {
52
+ cache_->Release(handle);
53
+ }
54
+ return r;
55
+ }
56
+
57
+ void Insert(int key, int value, int charge = 1) {
58
+ cache_->Release(cache_->Insert(EncodeKey(key), EncodeValue(value), charge,
59
+ &CacheTest::Deleter));
60
+ }
61
+
62
+ void Erase(int key) {
63
+ cache_->Erase(EncodeKey(key));
64
+ }
65
+ };
66
+ CacheTest* CacheTest::current_;
67
+
68
+ TEST(CacheTest, HitAndMiss) {
69
+ ASSERT_EQ(-1, Lookup(100));
70
+
71
+ Insert(100, 101);
72
+ ASSERT_EQ(101, Lookup(100));
73
+ ASSERT_EQ(-1, Lookup(200));
74
+ ASSERT_EQ(-1, Lookup(300));
75
+
76
+ Insert(200, 201);
77
+ ASSERT_EQ(101, Lookup(100));
78
+ ASSERT_EQ(201, Lookup(200));
79
+ ASSERT_EQ(-1, Lookup(300));
80
+
81
+ Insert(100, 102);
82
+ ASSERT_EQ(102, Lookup(100));
83
+ ASSERT_EQ(201, Lookup(200));
84
+ ASSERT_EQ(-1, Lookup(300));
85
+
86
+ ASSERT_EQ(1, deleted_keys_.size());
87
+ ASSERT_EQ(100, deleted_keys_[0]);
88
+ ASSERT_EQ(101, deleted_values_[0]);
89
+ }
90
+
91
+ TEST(CacheTest, Erase) {
92
+ Erase(200);
93
+ ASSERT_EQ(0, deleted_keys_.size());
94
+
95
+ Insert(100, 101);
96
+ Insert(200, 201);
97
+ Erase(100);
98
+ ASSERT_EQ(-1, Lookup(100));
99
+ ASSERT_EQ(201, Lookup(200));
100
+ ASSERT_EQ(1, deleted_keys_.size());
101
+ ASSERT_EQ(100, deleted_keys_[0]);
102
+ ASSERT_EQ(101, deleted_values_[0]);
103
+
104
+ Erase(100);
105
+ ASSERT_EQ(-1, Lookup(100));
106
+ ASSERT_EQ(201, Lookup(200));
107
+ ASSERT_EQ(1, deleted_keys_.size());
108
+ }
109
+
110
+ TEST(CacheTest, EntriesArePinned) {
111
+ Insert(100, 101);
112
+ Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));
113
+ ASSERT_EQ(101, DecodeValue(cache_->Value(h1)));
114
+
115
+ Insert(100, 102);
116
+ Cache::Handle* h2 = cache_->Lookup(EncodeKey(100));
117
+ ASSERT_EQ(102, DecodeValue(cache_->Value(h2)));
118
+ ASSERT_EQ(0, deleted_keys_.size());
119
+
120
+ cache_->Release(h1);
121
+ ASSERT_EQ(1, deleted_keys_.size());
122
+ ASSERT_EQ(100, deleted_keys_[0]);
123
+ ASSERT_EQ(101, deleted_values_[0]);
124
+
125
+ Erase(100);
126
+ ASSERT_EQ(-1, Lookup(100));
127
+ ASSERT_EQ(1, deleted_keys_.size());
128
+
129
+ cache_->Release(h2);
130
+ ASSERT_EQ(2, deleted_keys_.size());
131
+ ASSERT_EQ(100, deleted_keys_[1]);
132
+ ASSERT_EQ(102, deleted_values_[1]);
133
+ }
134
+
135
+ TEST(CacheTest, EvictionPolicy) {
136
+ Insert(100, 101);
137
+ Insert(200, 201);
138
+
139
+ // Frequently used entry must be kept around
140
+ for (int i = 0; i < kCacheSize; i++) {
141
+ Insert(1000+i, 2000+i);
142
+ ASSERT_EQ(2000+i, Lookup(1000+i));
143
+ ASSERT_EQ(101, Lookup(100));
144
+ }
145
+ ASSERT_EQ(101, Lookup(100));
146
+ ASSERT_EQ(2, deleted_keys_.size());
147
+ ASSERT_EQ(200, deleted_keys_[0]);
148
+ ASSERT_EQ(201, deleted_values_[0]);
149
+ }
150
+
151
+ TEST(CacheTest, HeavyEntry) {
152
+ Insert(100, 101);
153
+ Insert(200, 201, kCacheSize);
154
+ ASSERT_EQ(1, deleted_keys_.size());
155
+ ASSERT_EQ(100, deleted_keys_[0]);
156
+ ASSERT_EQ(101, deleted_values_[0]);
157
+ }
158
+
159
+ TEST(CacheTest, NewId) {
160
+ uint64_t a = cache_->NewId();
161
+ uint64_t b = cache_->NewId();
162
+ ASSERT_NE(a, b);
163
+ }
164
+
165
+ }
166
+
167
+ int main(int argc, char** argv) {
168
+ return leveldb::test::RunAllTests();
169
+ }
@@ -0,0 +1,194 @@
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
+ namespace leveldb {
8
+
9
+ void EncodeFixed32(char* buf, uint32_t value) {
10
+ #if __BYTE_ORDER == __LITTLE_ENDIAN
11
+ memcpy(buf, &value, sizeof(value));
12
+ #else
13
+ buf[0] = value & 0xff;
14
+ buf[1] = (value >> 8) & 0xff;
15
+ buf[2] = (value >> 16) & 0xff;
16
+ buf[3] = (value >> 24) & 0xff;
17
+ #endif
18
+ }
19
+
20
+ void EncodeFixed64(char* buf, uint64_t value) {
21
+ #if __BYTE_ORDER == __LITTLE_ENDIAN
22
+ memcpy(buf, &value, sizeof(value));
23
+ #else
24
+ buf[0] = value & 0xff;
25
+ buf[1] = (value >> 8) & 0xff;
26
+ buf[2] = (value >> 16) & 0xff;
27
+ buf[3] = (value >> 24) & 0xff;
28
+ buf[4] = (value >> 32) & 0xff;
29
+ buf[5] = (value >> 40) & 0xff;
30
+ buf[6] = (value >> 48) & 0xff;
31
+ buf[7] = (value >> 56) & 0xff;
32
+ #endif
33
+ }
34
+
35
+ void PutFixed32(std::string* dst, uint32_t value) {
36
+ char buf[sizeof(value)];
37
+ EncodeFixed32(buf, value);
38
+ dst->append(buf, sizeof(buf));
39
+ }
40
+
41
+ void PutFixed64(std::string* dst, uint64_t value) {
42
+ char buf[sizeof(value)];
43
+ EncodeFixed64(buf, value);
44
+ dst->append(buf, sizeof(buf));
45
+ }
46
+
47
+ char* EncodeVarint32(char* dst, uint32_t v) {
48
+ // Operate on characters as unsigneds
49
+ unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
50
+ static const int B = 128;
51
+ if (v < (1<<7)) {
52
+ *(ptr++) = v;
53
+ } else if (v < (1<<14)) {
54
+ *(ptr++) = v | B;
55
+ *(ptr++) = v>>7;
56
+ } else if (v < (1<<21)) {
57
+ *(ptr++) = v | B;
58
+ *(ptr++) = (v>>7) | B;
59
+ *(ptr++) = v>>14;
60
+ } else if (v < (1<<28)) {
61
+ *(ptr++) = v | B;
62
+ *(ptr++) = (v>>7) | B;
63
+ *(ptr++) = (v>>14) | B;
64
+ *(ptr++) = v>>21;
65
+ } else {
66
+ *(ptr++) = v | B;
67
+ *(ptr++) = (v>>7) | B;
68
+ *(ptr++) = (v>>14) | B;
69
+ *(ptr++) = (v>>21) | B;
70
+ *(ptr++) = v>>28;
71
+ }
72
+ return reinterpret_cast<char*>(ptr);
73
+ }
74
+
75
+ void PutVarint32(std::string* dst, uint32_t v) {
76
+ char buf[5];
77
+ char* ptr = EncodeVarint32(buf, v);
78
+ dst->append(buf, ptr - buf);
79
+ }
80
+
81
+ char* EncodeVarint64(char* dst, uint64_t v) {
82
+ static const int B = 128;
83
+ unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
84
+ while (v >= B) {
85
+ *(ptr++) = (v & (B-1)) | B;
86
+ v >>= 7;
87
+ }
88
+ *(ptr++) = static_cast<unsigned char>(v);
89
+ return reinterpret_cast<char*>(ptr);
90
+ }
91
+
92
+ void PutVarint64(std::string* dst, uint64_t v) {
93
+ char buf[10];
94
+ char* ptr = EncodeVarint64(buf, v);
95
+ dst->append(buf, ptr - buf);
96
+ }
97
+
98
+ void PutLengthPrefixedSlice(std::string* dst, const Slice& value) {
99
+ PutVarint32(dst, value.size());
100
+ dst->append(value.data(), value.size());
101
+ }
102
+
103
+ int VarintLength(uint64_t v) {
104
+ int len = 1;
105
+ while (v >= 128) {
106
+ v >>= 7;
107
+ len++;
108
+ }
109
+ return len;
110
+ }
111
+
112
+ const char* GetVarint32PtrFallback(const char* p,
113
+ const char* limit,
114
+ uint32_t* value) {
115
+ uint32_t result = 0;
116
+ for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7) {
117
+ uint32_t byte = *(reinterpret_cast<const unsigned char*>(p));
118
+ p++;
119
+ if (byte & 128) {
120
+ // More bytes are present
121
+ result |= ((byte & 127) << shift);
122
+ } else {
123
+ result |= (byte << shift);
124
+ *value = result;
125
+ return reinterpret_cast<const char*>(p);
126
+ }
127
+ }
128
+ return NULL;
129
+ }
130
+
131
+ bool GetVarint32(Slice* input, uint32_t* value) {
132
+ const char* p = input->data();
133
+ const char* limit = p + input->size();
134
+ const char* q = GetVarint32Ptr(p, limit, value);
135
+ if (q == NULL) {
136
+ return false;
137
+ } else {
138
+ *input = Slice(q, limit - q);
139
+ return true;
140
+ }
141
+ }
142
+
143
+ const char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* value) {
144
+ uint64_t result = 0;
145
+ for (uint32_t shift = 0; shift <= 63 && p < limit; shift += 7) {
146
+ uint64_t byte = *(reinterpret_cast<const unsigned char*>(p));
147
+ p++;
148
+ if (byte & 128) {
149
+ // More bytes are present
150
+ result |= ((byte & 127) << shift);
151
+ } else {
152
+ result |= (byte << shift);
153
+ *value = result;
154
+ return reinterpret_cast<const char*>(p);
155
+ }
156
+ }
157
+ return NULL;
158
+ }
159
+
160
+ bool GetVarint64(Slice* input, uint64_t* value) {
161
+ const char* p = input->data();
162
+ const char* limit = p + input->size();
163
+ const char* q = GetVarint64Ptr(p, limit, value);
164
+ if (q == NULL) {
165
+ return false;
166
+ } else {
167
+ *input = Slice(q, limit - q);
168
+ return true;
169
+ }
170
+ }
171
+
172
+ const char* GetLengthPrefixedSlice(const char* p, const char* limit,
173
+ Slice* result) {
174
+ uint32_t len;
175
+ p = GetVarint32Ptr(p, limit, &len);
176
+ if (p == NULL) return NULL;
177
+ if (p + len > limit) return NULL;
178
+ *result = Slice(p, len);
179
+ return p + len;
180
+ }
181
+
182
+ bool GetLengthPrefixedSlice(Slice* input, Slice* result) {
183
+ uint32_t len;
184
+ if (GetVarint32(input, &len) &&
185
+ input->size() >= len) {
186
+ *result = Slice(input->data(), len);
187
+ input->remove_prefix(len);
188
+ return true;
189
+ } else {
190
+ return false;
191
+ }
192
+ }
193
+
194
+ }
@@ -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>(ptr[0]))
66
+ | (static_cast<uint32_t>(ptr[1]) << 8)
67
+ | (static_cast<uint32_t>(ptr[2]) << 16)
68
+ | (static_cast<uint32_t>(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
+ }
103
+
104
+ #endif // STORAGE_LEVELDB_UTIL_CODING_H_