leveldb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,92 @@
1
+ // Copyright (c) 2013 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
+ // Test for issue 178: a manual compaction causes deleted data to reappear.
6
+ #include <iostream>
7
+ #include <sstream>
8
+ #include <cstdlib>
9
+
10
+ #include "leveldb/db.h"
11
+ #include "leveldb/write_batch.h"
12
+ #include "util/testharness.h"
13
+
14
+ namespace {
15
+
16
+ const int kNumKeys = 1100000;
17
+
18
+ std::string Key1(int i) {
19
+ char buf[100];
20
+ snprintf(buf, sizeof(buf), "my_key_%d", i);
21
+ return buf;
22
+ }
23
+
24
+ std::string Key2(int i) {
25
+ return Key1(i) + "_xxx";
26
+ }
27
+
28
+ class Issue178 { };
29
+
30
+ TEST(Issue178, Test) {
31
+ // Get rid of any state from an old run.
32
+ std::string dbpath = leveldb::test::TmpDir() + "/leveldb_cbug_test";
33
+ DestroyDB(dbpath, leveldb::Options());
34
+
35
+ // Open database. Disable compression since it affects the creation
36
+ // of layers and the code below is trying to test against a very
37
+ // specific scenario.
38
+ leveldb::DB* db;
39
+ leveldb::Options db_options;
40
+ db_options.create_if_missing = true;
41
+ db_options.compression = leveldb::kNoCompression;
42
+ ASSERT_OK(leveldb::DB::Open(db_options, dbpath, &db));
43
+
44
+ // create first key range
45
+ leveldb::WriteBatch batch;
46
+ for (size_t i = 0; i < kNumKeys; i++) {
47
+ batch.Put(Key1(i), "value for range 1 key");
48
+ }
49
+ ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
50
+
51
+ // create second key range
52
+ batch.Clear();
53
+ for (size_t i = 0; i < kNumKeys; i++) {
54
+ batch.Put(Key2(i), "value for range 2 key");
55
+ }
56
+ ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
57
+
58
+ // delete second key range
59
+ batch.Clear();
60
+ for (size_t i = 0; i < kNumKeys; i++) {
61
+ batch.Delete(Key2(i));
62
+ }
63
+ ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
64
+
65
+ // compact database
66
+ std::string start_key = Key1(0);
67
+ std::string end_key = Key1(kNumKeys - 1);
68
+ leveldb::Slice least(start_key.data(), start_key.size());
69
+ leveldb::Slice greatest(end_key.data(), end_key.size());
70
+
71
+ // commenting out the line below causes the example to work correctly
72
+ db->CompactRange(&least, &greatest);
73
+
74
+ // count the keys
75
+ leveldb::Iterator* iter = db->NewIterator(leveldb::ReadOptions());
76
+ size_t num_keys = 0;
77
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
78
+ num_keys++;
79
+ }
80
+ delete iter;
81
+ ASSERT_EQ(kNumKeys, num_keys) << "Bad number of keys";
82
+
83
+ // close database
84
+ delete db;
85
+ DestroyDB(dbpath, leveldb::Options());
86
+ }
87
+
88
+ } // anonymous namespace
89
+
90
+ int main(int argc, char** argv) {
91
+ return leveldb::test::RunAllTests();
92
+ }
@@ -0,0 +1,224 @@
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
+ // AtomicPointer provides storage for a lock-free pointer.
6
+ // Platform-dependent implementation of AtomicPointer:
7
+ // - If the platform provides a cheap barrier, we use it with raw pointers
8
+ // - If cstdatomic is present (on newer versions of gcc, it is), we use
9
+ // a cstdatomic-based AtomicPointer. However we prefer the memory
10
+ // barrier based version, because at least on a gcc 4.4 32-bit build
11
+ // on linux, we have encountered a buggy <cstdatomic>
12
+ // implementation. Also, some <cstdatomic> implementations are much
13
+ // slower than a memory-barrier based implementation (~16ns for
14
+ // <cstdatomic> based acquire-load vs. ~1ns for a barrier based
15
+ // acquire-load).
16
+ // This code is based on atomicops-internals-* in Google's perftools:
17
+ // http://code.google.com/p/google-perftools/source/browse/#svn%2Ftrunk%2Fsrc%2Fbase
18
+
19
+ #ifndef PORT_ATOMIC_POINTER_H_
20
+ #define PORT_ATOMIC_POINTER_H_
21
+
22
+ #include <stdint.h>
23
+ #ifdef LEVELDB_CSTDATOMIC_PRESENT
24
+ #include <cstdatomic>
25
+ #endif
26
+ #ifdef OS_WIN
27
+ #include <windows.h>
28
+ #endif
29
+ #ifdef OS_MACOSX
30
+ #include <libkern/OSAtomic.h>
31
+ #endif
32
+
33
+ #if defined(_M_X64) || defined(__x86_64__)
34
+ #define ARCH_CPU_X86_FAMILY 1
35
+ #elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
36
+ #define ARCH_CPU_X86_FAMILY 1
37
+ #elif defined(__ARMEL__)
38
+ #define ARCH_CPU_ARM_FAMILY 1
39
+ #elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__)
40
+ #define ARCH_CPU_PPC_FAMILY 1
41
+ #endif
42
+
43
+ namespace leveldb {
44
+ namespace port {
45
+
46
+ // Define MemoryBarrier() if available
47
+ // Windows on x86
48
+ #if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY)
49
+ // windows.h already provides a MemoryBarrier(void) macro
50
+ // http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx
51
+ #define LEVELDB_HAVE_MEMORY_BARRIER
52
+
53
+ // Gcc on x86
54
+ #elif defined(ARCH_CPU_X86_FAMILY) && defined(__GNUC__)
55
+ inline void MemoryBarrier() {
56
+ // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on
57
+ // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering.
58
+ __asm__ __volatile__("" : : : "memory");
59
+ }
60
+ #define LEVELDB_HAVE_MEMORY_BARRIER
61
+
62
+ // Sun Studio
63
+ #elif defined(ARCH_CPU_X86_FAMILY) && defined(__SUNPRO_CC)
64
+ inline void MemoryBarrier() {
65
+ // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on
66
+ // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering.
67
+ asm volatile("" : : : "memory");
68
+ }
69
+ #define LEVELDB_HAVE_MEMORY_BARRIER
70
+
71
+ // Mac OS
72
+ #elif defined(OS_MACOSX)
73
+ inline void MemoryBarrier() {
74
+ OSMemoryBarrier();
75
+ }
76
+ #define LEVELDB_HAVE_MEMORY_BARRIER
77
+
78
+ // ARM Linux
79
+ #elif defined(ARCH_CPU_ARM_FAMILY) && defined(__linux__)
80
+ typedef void (*LinuxKernelMemoryBarrierFunc)(void);
81
+ // The Linux ARM kernel provides a highly optimized device-specific memory
82
+ // barrier function at a fixed memory address that is mapped in every
83
+ // user-level process.
84
+ //
85
+ // This beats using CPU-specific instructions which are, on single-core
86
+ // devices, un-necessary and very costly (e.g. ARMv7-A "dmb" takes more
87
+ // than 180ns on a Cortex-A8 like the one on a Nexus One). Benchmarking
88
+ // shows that the extra function call cost is completely negligible on
89
+ // multi-core devices.
90
+ //
91
+ inline void MemoryBarrier() {
92
+ (*(LinuxKernelMemoryBarrierFunc)0xffff0fa0)();
93
+ }
94
+ #define LEVELDB_HAVE_MEMORY_BARRIER
95
+
96
+ // PPC
97
+ #elif defined(ARCH_CPU_PPC_FAMILY) && defined(__GNUC__)
98
+ inline void MemoryBarrier() {
99
+ // TODO for some powerpc expert: is there a cheaper suitable variant?
100
+ // Perhaps by having separate barriers for acquire and release ops.
101
+ asm volatile("sync" : : : "memory");
102
+ }
103
+ #define LEVELDB_HAVE_MEMORY_BARRIER
104
+
105
+ #endif
106
+
107
+ // AtomicPointer built using platform-specific MemoryBarrier()
108
+ #if defined(LEVELDB_HAVE_MEMORY_BARRIER)
109
+ class AtomicPointer {
110
+ private:
111
+ void* rep_;
112
+ public:
113
+ AtomicPointer() { }
114
+ explicit AtomicPointer(void* p) : rep_(p) {}
115
+ inline void* NoBarrier_Load() const { return rep_; }
116
+ inline void NoBarrier_Store(void* v) { rep_ = v; }
117
+ inline void* Acquire_Load() const {
118
+ void* result = rep_;
119
+ MemoryBarrier();
120
+ return result;
121
+ }
122
+ inline void Release_Store(void* v) {
123
+ MemoryBarrier();
124
+ rep_ = v;
125
+ }
126
+ };
127
+
128
+ // AtomicPointer based on <cstdatomic>
129
+ #elif defined(LEVELDB_CSTDATOMIC_PRESENT)
130
+ class AtomicPointer {
131
+ private:
132
+ std::atomic<void*> rep_;
133
+ public:
134
+ AtomicPointer() { }
135
+ explicit AtomicPointer(void* v) : rep_(v) { }
136
+ inline void* Acquire_Load() const {
137
+ return rep_.load(std::memory_order_acquire);
138
+ }
139
+ inline void Release_Store(void* v) {
140
+ rep_.store(v, std::memory_order_release);
141
+ }
142
+ inline void* NoBarrier_Load() const {
143
+ return rep_.load(std::memory_order_relaxed);
144
+ }
145
+ inline void NoBarrier_Store(void* v) {
146
+ rep_.store(v, std::memory_order_relaxed);
147
+ }
148
+ };
149
+
150
+ // Atomic pointer based on sparc memory barriers
151
+ #elif defined(__sparcv9) && defined(__GNUC__)
152
+ class AtomicPointer {
153
+ private:
154
+ void* rep_;
155
+ public:
156
+ AtomicPointer() { }
157
+ explicit AtomicPointer(void* v) : rep_(v) { }
158
+ inline void* Acquire_Load() const {
159
+ void* val;
160
+ __asm__ __volatile__ (
161
+ "ldx [%[rep_]], %[val] \n\t"
162
+ "membar #LoadLoad|#LoadStore \n\t"
163
+ : [val] "=r" (val)
164
+ : [rep_] "r" (&rep_)
165
+ : "memory");
166
+ return val;
167
+ }
168
+ inline void Release_Store(void* v) {
169
+ __asm__ __volatile__ (
170
+ "membar #LoadStore|#StoreStore \n\t"
171
+ "stx %[v], [%[rep_]] \n\t"
172
+ :
173
+ : [rep_] "r" (&rep_), [v] "r" (v)
174
+ : "memory");
175
+ }
176
+ inline void* NoBarrier_Load() const { return rep_; }
177
+ inline void NoBarrier_Store(void* v) { rep_ = v; }
178
+ };
179
+
180
+ // Atomic pointer based on ia64 acq/rel
181
+ #elif defined(__ia64) && defined(__GNUC__)
182
+ class AtomicPointer {
183
+ private:
184
+ void* rep_;
185
+ public:
186
+ AtomicPointer() { }
187
+ explicit AtomicPointer(void* v) : rep_(v) { }
188
+ inline void* Acquire_Load() const {
189
+ void* val ;
190
+ __asm__ __volatile__ (
191
+ "ld8.acq %[val] = [%[rep_]] \n\t"
192
+ : [val] "=r" (val)
193
+ : [rep_] "r" (&rep_)
194
+ : "memory"
195
+ );
196
+ return val;
197
+ }
198
+ inline void Release_Store(void* v) {
199
+ __asm__ __volatile__ (
200
+ "st8.rel [%[rep_]] = %[v] \n\t"
201
+ :
202
+ : [rep_] "r" (&rep_), [v] "r" (v)
203
+ : "memory"
204
+ );
205
+ }
206
+ inline void* NoBarrier_Load() const { return rep_; }
207
+ inline void NoBarrier_Store(void* v) { rep_ = v; }
208
+ };
209
+
210
+ // We have neither MemoryBarrier(), nor <cstdatomic>
211
+ #else
212
+ #error Please implement AtomicPointer for this platform.
213
+
214
+ #endif
215
+
216
+ #undef LEVELDB_HAVE_MEMORY_BARRIER
217
+ #undef ARCH_CPU_X86_FAMILY
218
+ #undef ARCH_CPU_ARM_FAMILY
219
+ #undef ARCH_CPU_PPC_FAMILY
220
+
221
+ } // namespace port
222
+ } // namespace leveldb
223
+
224
+ #endif // PORT_ATOMIC_POINTER_H_
@@ -0,0 +1,19 @@
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_PORT_PORT_H_
6
+ #define STORAGE_LEVELDB_PORT_PORT_H_
7
+
8
+ #include <string.h>
9
+
10
+ // Include the appropriate platform specific file below. If you are
11
+ // porting to a new platform, see "port_example.h" for documentation
12
+ // of what the new port_<platform>.h file must provide.
13
+ #if defined(LEVELDB_PLATFORM_POSIX)
14
+ # include "port/port_posix.h"
15
+ #elif defined(LEVELDB_PLATFORM_CHROMIUM)
16
+ # include "port/port_chromium.h"
17
+ #endif
18
+
19
+ #endif // STORAGE_LEVELDB_PORT_PORT_H_
@@ -0,0 +1,135 @@
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
+ // This file contains the specification, but not the implementations,
6
+ // of the types/operations/etc. that should be defined by a platform
7
+ // specific port_<platform>.h file. Use this file as a reference for
8
+ // how to port this package to a new platform.
9
+
10
+ #ifndef STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
11
+ #define STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
12
+
13
+ namespace leveldb {
14
+ namespace port {
15
+
16
+ // TODO(jorlow): Many of these belong more in the environment class rather than
17
+ // here. We should try moving them and see if it affects perf.
18
+
19
+ // The following boolean constant must be true on a little-endian machine
20
+ // and false otherwise.
21
+ static const bool kLittleEndian = true /* or some other expression */;
22
+
23
+ // ------------------ Threading -------------------
24
+
25
+ // A Mutex represents an exclusive lock.
26
+ class Mutex {
27
+ public:
28
+ Mutex();
29
+ ~Mutex();
30
+
31
+ // Lock the mutex. Waits until other lockers have exited.
32
+ // Will deadlock if the mutex is already locked by this thread.
33
+ void Lock();
34
+
35
+ // Unlock the mutex.
36
+ // REQUIRES: This mutex was locked by this thread.
37
+ void Unlock();
38
+
39
+ // Optionally crash if this thread does not hold this mutex.
40
+ // The implementation must be fast, especially if NDEBUG is
41
+ // defined. The implementation is allowed to skip all checks.
42
+ void AssertHeld();
43
+ };
44
+
45
+ class CondVar {
46
+ public:
47
+ explicit CondVar(Mutex* mu);
48
+ ~CondVar();
49
+
50
+ // Atomically release *mu and block on this condition variable until
51
+ // either a call to SignalAll(), or a call to Signal() that picks
52
+ // this thread to wakeup.
53
+ // REQUIRES: this thread holds *mu
54
+ void Wait();
55
+
56
+ // If there are some threads waiting, wake up at least one of them.
57
+ void Signal();
58
+
59
+ // Wake up all waiting threads.
60
+ void SignallAll();
61
+ };
62
+
63
+ // Thread-safe initialization.
64
+ // Used as follows:
65
+ // static port::OnceType init_control = LEVELDB_ONCE_INIT;
66
+ // static void Initializer() { ... do something ...; }
67
+ // ...
68
+ // port::InitOnce(&init_control, &Initializer);
69
+ typedef intptr_t OnceType;
70
+ #define LEVELDB_ONCE_INIT 0
71
+ extern void InitOnce(port::OnceType*, void (*initializer)());
72
+
73
+ // A type that holds a pointer that can be read or written atomically
74
+ // (i.e., without word-tearing.)
75
+ class AtomicPointer {
76
+ private:
77
+ intptr_t rep_;
78
+ public:
79
+ // Initialize to arbitrary value
80
+ AtomicPointer();
81
+
82
+ // Initialize to hold v
83
+ explicit AtomicPointer(void* v) : rep_(v) { }
84
+
85
+ // Read and return the stored pointer with the guarantee that no
86
+ // later memory access (read or write) by this thread can be
87
+ // reordered ahead of this read.
88
+ void* Acquire_Load() const;
89
+
90
+ // Set v as the stored pointer with the guarantee that no earlier
91
+ // memory access (read or write) by this thread can be reordered
92
+ // after this store.
93
+ void Release_Store(void* v);
94
+
95
+ // Read the stored pointer with no ordering guarantees.
96
+ void* NoBarrier_Load() const;
97
+
98
+ // Set va as the stored pointer with no ordering guarantees.
99
+ void NoBarrier_Store(void* v);
100
+ };
101
+
102
+ // ------------------ Compression -------------------
103
+
104
+ // Store the snappy compression of "input[0,input_length-1]" in *output.
105
+ // Returns false if snappy is not supported by this port.
106
+ extern bool Snappy_Compress(const char* input, size_t input_length,
107
+ std::string* output);
108
+
109
+ // If input[0,input_length-1] looks like a valid snappy compressed
110
+ // buffer, store the size of the uncompressed data in *result and
111
+ // return true. Else return false.
112
+ extern bool Snappy_GetUncompressedLength(const char* input, size_t length,
113
+ size_t* result);
114
+
115
+ // Attempt to snappy uncompress input[0,input_length-1] into *output.
116
+ // Returns true if successful, false if the input is invalid lightweight
117
+ // compressed data.
118
+ //
119
+ // REQUIRES: at least the first "n" bytes of output[] must be writable
120
+ // where "n" is the result of a successful call to
121
+ // Snappy_GetUncompressedLength.
122
+ extern bool Snappy_Uncompress(const char* input_data, size_t input_length,
123
+ char* output);
124
+
125
+ // ------------------ Miscellaneous -------------------
126
+
127
+ // If heap profiling is not supported, returns false.
128
+ // Else repeatedly calls (*func)(arg, data, n) and then returns true.
129
+ // The concatenation of all "data[0,n-1]" fragments is the heap profile.
130
+ extern bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg);
131
+
132
+ } // namespace port
133
+ } // namespace leveldb
134
+
135
+ #endif // STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
@@ -0,0 +1,54 @@
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 "port/port_posix.h"
6
+
7
+ #include <cstdlib>
8
+ #include <stdio.h>
9
+ #include <string.h>
10
+ #include "util/logging.h"
11
+
12
+ namespace leveldb {
13
+ namespace port {
14
+
15
+ static void PthreadCall(const char* label, int result) {
16
+ if (result != 0) {
17
+ fprintf(stderr, "pthread %s: %s\n", label, strerror(result));
18
+ abort();
19
+ }
20
+ }
21
+
22
+ Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); }
23
+
24
+ Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); }
25
+
26
+ void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); }
27
+
28
+ void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); }
29
+
30
+ CondVar::CondVar(Mutex* mu)
31
+ : mu_(mu) {
32
+ PthreadCall("init cv", pthread_cond_init(&cv_, NULL));
33
+ }
34
+
35
+ CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); }
36
+
37
+ void CondVar::Wait() {
38
+ PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_));
39
+ }
40
+
41
+ void CondVar::Signal() {
42
+ PthreadCall("signal", pthread_cond_signal(&cv_));
43
+ }
44
+
45
+ void CondVar::SignalAll() {
46
+ PthreadCall("broadcast", pthread_cond_broadcast(&cv_));
47
+ }
48
+
49
+ void InitOnce(OnceType* once, void (*initializer)()) {
50
+ PthreadCall("once", pthread_once(once, initializer));
51
+ }
52
+
53
+ } // namespace port
54
+ } // namespace leveldb
@@ -0,0 +1,157 @@
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
+ // See port_example.h for documentation for the following types/functions.
6
+
7
+ #ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_
8
+ #define STORAGE_LEVELDB_PORT_PORT_POSIX_H_
9
+
10
+ #undef PLATFORM_IS_LITTLE_ENDIAN
11
+ #if defined(OS_MACOSX)
12
+ #include <machine/endian.h>
13
+ #if defined(__DARWIN_LITTLE_ENDIAN) && defined(__DARWIN_BYTE_ORDER)
14
+ #define PLATFORM_IS_LITTLE_ENDIAN \
15
+ (__DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN)
16
+ #endif
17
+ #elif defined(OS_SOLARIS)
18
+ #include <sys/isa_defs.h>
19
+ #ifdef _LITTLE_ENDIAN
20
+ #define PLATFORM_IS_LITTLE_ENDIAN true
21
+ #else
22
+ #define PLATFORM_IS_LITTLE_ENDIAN false
23
+ #endif
24
+ #elif defined(OS_FREEBSD)
25
+ #include <sys/types.h>
26
+ #include <sys/endian.h>
27
+ #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)
28
+ #elif defined(OS_OPENBSD) || defined(OS_NETBSD) ||\
29
+ defined(OS_DRAGONFLYBSD)
30
+ #include <sys/types.h>
31
+ #include <sys/endian.h>
32
+ #elif defined(OS_HPUX)
33
+ #define PLATFORM_IS_LITTLE_ENDIAN false
34
+ #elif defined(OS_ANDROID)
35
+ // Due to a bug in the NDK x86 <sys/endian.h> definition,
36
+ // _BYTE_ORDER must be used instead of __BYTE_ORDER on Android.
37
+ // See http://code.google.com/p/android/issues/detail?id=39824
38
+ #include <endian.h>
39
+ #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)
40
+ #else
41
+ #include <endian.h>
42
+ #endif
43
+
44
+ #include <pthread.h>
45
+ #ifdef SNAPPY
46
+ #include <snappy.h>
47
+ #endif
48
+ #include <stdint.h>
49
+ #include <string>
50
+ #include "port/atomic_pointer.h"
51
+
52
+ #ifndef PLATFORM_IS_LITTLE_ENDIAN
53
+ #define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
54
+ #endif
55
+
56
+ #if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\
57
+ defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\
58
+ defined(OS_ANDROID) || defined(OS_HPUX)
59
+ // Use fread/fwrite/fflush on platforms without _unlocked variants
60
+ #define fread_unlocked fread
61
+ #define fwrite_unlocked fwrite
62
+ #define fflush_unlocked fflush
63
+ #endif
64
+
65
+ #if defined(OS_MACOSX) || defined(OS_FREEBSD) ||\
66
+ defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD)
67
+ // Use fsync() on platforms without fdatasync()
68
+ #define fdatasync fsync
69
+ #endif
70
+
71
+ #if defined(OS_ANDROID) && __ANDROID_API__ < 9
72
+ // fdatasync() was only introduced in API level 9 on Android. Use fsync()
73
+ // when targetting older platforms.
74
+ #define fdatasync fsync
75
+ #endif
76
+
77
+ namespace leveldb {
78
+ namespace port {
79
+
80
+ static const bool kLittleEndian = PLATFORM_IS_LITTLE_ENDIAN;
81
+ #undef PLATFORM_IS_LITTLE_ENDIAN
82
+
83
+ class CondVar;
84
+
85
+ class Mutex {
86
+ public:
87
+ Mutex();
88
+ ~Mutex();
89
+
90
+ void Lock();
91
+ void Unlock();
92
+ void AssertHeld() { }
93
+
94
+ private:
95
+ friend class CondVar;
96
+ pthread_mutex_t mu_;
97
+
98
+ // No copying
99
+ Mutex(const Mutex&);
100
+ void operator=(const Mutex&);
101
+ };
102
+
103
+ class CondVar {
104
+ public:
105
+ explicit CondVar(Mutex* mu);
106
+ ~CondVar();
107
+ void Wait();
108
+ void Signal();
109
+ void SignalAll();
110
+ private:
111
+ pthread_cond_t cv_;
112
+ Mutex* mu_;
113
+ };
114
+
115
+ typedef pthread_once_t OnceType;
116
+ #define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT
117
+ extern void InitOnce(OnceType* once, void (*initializer)());
118
+
119
+ inline bool Snappy_Compress(const char* input, size_t length,
120
+ ::std::string* output) {
121
+ #ifdef SNAPPY
122
+ output->resize(snappy::MaxCompressedLength(length));
123
+ size_t outlen;
124
+ snappy::RawCompress(input, length, &(*output)[0], &outlen);
125
+ output->resize(outlen);
126
+ return true;
127
+ #endif
128
+
129
+ return false;
130
+ }
131
+
132
+ inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
133
+ size_t* result) {
134
+ #ifdef SNAPPY
135
+ return snappy::GetUncompressedLength(input, length, result);
136
+ #else
137
+ return false;
138
+ #endif
139
+ }
140
+
141
+ inline bool Snappy_Uncompress(const char* input, size_t length,
142
+ char* output) {
143
+ #ifdef SNAPPY
144
+ return snappy::RawUncompress(input, length, output);
145
+ #else
146
+ return false;
147
+ #endif
148
+ }
149
+
150
+ inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
151
+ return false;
152
+ }
153
+
154
+ } // namespace port
155
+ } // namespace leveldb
156
+
157
+ #endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_