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,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_