filiptepper-leveldb-ruby 0.14

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 (123) hide show
  1. data/LICENSE +24 -0
  2. data/README +72 -0
  3. data/ext/leveldb/extconf.rb +14 -0
  4. data/ext/leveldb/leveldb.cc +530 -0
  5. data/ext/leveldb/platform.rb +83 -0
  6. data/leveldb/Makefile +191 -0
  7. data/leveldb/build_detect_platform +160 -0
  8. data/leveldb/db/builder.cc +88 -0
  9. data/leveldb/db/builder.h +34 -0
  10. data/leveldb/db/c.cc +581 -0
  11. data/leveldb/db/corruption_test.cc +359 -0
  12. data/leveldb/db/db_bench.cc +970 -0
  13. data/leveldb/db/db_impl.cc +1448 -0
  14. data/leveldb/db/db_impl.h +194 -0
  15. data/leveldb/db/db_iter.cc +299 -0
  16. data/leveldb/db/db_iter.h +26 -0
  17. data/leveldb/db/db_test.cc +1901 -0
  18. data/leveldb/db/dbformat.cc +140 -0
  19. data/leveldb/db/dbformat.h +227 -0
  20. data/leveldb/db/dbformat_test.cc +112 -0
  21. data/leveldb/db/filename.cc +139 -0
  22. data/leveldb/db/filename.h +80 -0
  23. data/leveldb/db/filename_test.cc +122 -0
  24. data/leveldb/db/log_format.h +35 -0
  25. data/leveldb/db/log_reader.cc +259 -0
  26. data/leveldb/db/log_reader.h +108 -0
  27. data/leveldb/db/log_test.cc +500 -0
  28. data/leveldb/db/log_writer.cc +103 -0
  29. data/leveldb/db/log_writer.h +48 -0
  30. data/leveldb/db/memtable.cc +145 -0
  31. data/leveldb/db/memtable.h +91 -0
  32. data/leveldb/db/repair.cc +389 -0
  33. data/leveldb/db/skiplist.h +379 -0
  34. data/leveldb/db/skiplist_test.cc +378 -0
  35. data/leveldb/db/snapshot.h +66 -0
  36. data/leveldb/db/table_cache.cc +121 -0
  37. data/leveldb/db/table_cache.h +61 -0
  38. data/leveldb/db/version_edit.cc +266 -0
  39. data/leveldb/db/version_edit.h +107 -0
  40. data/leveldb/db/version_edit_test.cc +46 -0
  41. data/leveldb/db/version_set.cc +1402 -0
  42. data/leveldb/db/version_set.h +370 -0
  43. data/leveldb/db/version_set_test.cc +179 -0
  44. data/leveldb/db/write_batch.cc +147 -0
  45. data/leveldb/db/write_batch_internal.h +49 -0
  46. data/leveldb/db/write_batch_test.cc +120 -0
  47. data/leveldb/helpers/memenv/memenv.cc +374 -0
  48. data/leveldb/helpers/memenv/memenv.h +20 -0
  49. data/leveldb/helpers/memenv/memenv_test.cc +232 -0
  50. data/leveldb/include/leveldb/c.h +275 -0
  51. data/leveldb/include/leveldb/cache.h +99 -0
  52. data/leveldb/include/leveldb/comparator.h +63 -0
  53. data/leveldb/include/leveldb/db.h +161 -0
  54. data/leveldb/include/leveldb/env.h +323 -0
  55. data/leveldb/include/leveldb/filter_policy.h +70 -0
  56. data/leveldb/include/leveldb/iterator.h +100 -0
  57. data/leveldb/include/leveldb/options.h +195 -0
  58. data/leveldb/include/leveldb/slice.h +109 -0
  59. data/leveldb/include/leveldb/status.h +106 -0
  60. data/leveldb/include/leveldb/table.h +85 -0
  61. data/leveldb/include/leveldb/table_builder.h +92 -0
  62. data/leveldb/include/leveldb/write_batch.h +64 -0
  63. data/leveldb/port/atomic_pointer.h +144 -0
  64. data/leveldb/port/port.h +21 -0
  65. data/leveldb/port/port_android.cc +64 -0
  66. data/leveldb/port/port_android.h +159 -0
  67. data/leveldb/port/port_example.h +125 -0
  68. data/leveldb/port/port_posix.cc +50 -0
  69. data/leveldb/port/port_posix.h +129 -0
  70. data/leveldb/port/win/stdint.h +24 -0
  71. data/leveldb/table/block.cc +267 -0
  72. data/leveldb/table/block.h +44 -0
  73. data/leveldb/table/block_builder.cc +109 -0
  74. data/leveldb/table/block_builder.h +57 -0
  75. data/leveldb/table/filter_block.cc +111 -0
  76. data/leveldb/table/filter_block.h +68 -0
  77. data/leveldb/table/filter_block_test.cc +128 -0
  78. data/leveldb/table/format.cc +145 -0
  79. data/leveldb/table/format.h +108 -0
  80. data/leveldb/table/iterator.cc +67 -0
  81. data/leveldb/table/iterator_wrapper.h +63 -0
  82. data/leveldb/table/merger.cc +197 -0
  83. data/leveldb/table/merger.h +26 -0
  84. data/leveldb/table/table.cc +276 -0
  85. data/leveldb/table/table_builder.cc +270 -0
  86. data/leveldb/table/table_test.cc +838 -0
  87. data/leveldb/table/two_level_iterator.cc +182 -0
  88. data/leveldb/table/two_level_iterator.h +34 -0
  89. data/leveldb/util/arena.cc +68 -0
  90. data/leveldb/util/arena.h +68 -0
  91. data/leveldb/util/arena_test.cc +68 -0
  92. data/leveldb/util/bloom.cc +95 -0
  93. data/leveldb/util/bloom_test.cc +159 -0
  94. data/leveldb/util/cache.cc +328 -0
  95. data/leveldb/util/cache_test.cc +186 -0
  96. data/leveldb/util/coding.cc +194 -0
  97. data/leveldb/util/coding.h +104 -0
  98. data/leveldb/util/coding_test.cc +173 -0
  99. data/leveldb/util/comparator.cc +76 -0
  100. data/leveldb/util/crc32c.cc +332 -0
  101. data/leveldb/util/crc32c.h +45 -0
  102. data/leveldb/util/crc32c_test.cc +72 -0
  103. data/leveldb/util/env.cc +96 -0
  104. data/leveldb/util/env_posix.cc +609 -0
  105. data/leveldb/util/env_test.cc +104 -0
  106. data/leveldb/util/filter_policy.cc +11 -0
  107. data/leveldb/util/hash.cc +45 -0
  108. data/leveldb/util/hash.h +19 -0
  109. data/leveldb/util/histogram.cc +139 -0
  110. data/leveldb/util/histogram.h +42 -0
  111. data/leveldb/util/logging.cc +81 -0
  112. data/leveldb/util/logging.h +47 -0
  113. data/leveldb/util/mutexlock.h +39 -0
  114. data/leveldb/util/options.cc +29 -0
  115. data/leveldb/util/posix_logger.h +98 -0
  116. data/leveldb/util/random.h +59 -0
  117. data/leveldb/util/status.cc +75 -0
  118. data/leveldb/util/testharness.cc +77 -0
  119. data/leveldb/util/testharness.h +138 -0
  120. data/leveldb/util/testutil.cc +51 -0
  121. data/leveldb/util/testutil.h +53 -0
  122. data/lib/leveldb.rb +76 -0
  123. metadata +175 -0
@@ -0,0 +1,106 @@
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
+ // A Status encapsulates the result of an operation. It may indicate success,
6
+ // or it may indicate an error with an associated error message.
7
+ //
8
+ // Multiple threads can invoke const methods on a Status without
9
+ // external synchronization, but if any of the threads may call a
10
+ // non-const method, all threads accessing the same Status must use
11
+ // external synchronization.
12
+
13
+ #ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_
14
+ #define STORAGE_LEVELDB_INCLUDE_STATUS_H_
15
+
16
+ #include <string>
17
+ #include "leveldb/slice.h"
18
+
19
+ namespace leveldb {
20
+
21
+ class Status {
22
+ public:
23
+ // Create a success status.
24
+ Status() : state_(NULL) { }
25
+ ~Status() { delete[] state_; }
26
+
27
+ // Copy the specified status.
28
+ Status(const Status& s);
29
+ void operator=(const Status& s);
30
+
31
+ // Return a success status.
32
+ static Status OK() { return Status(); }
33
+
34
+ // Return error status of an appropriate type.
35
+ static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) {
36
+ return Status(kNotFound, msg, msg2);
37
+ }
38
+ static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) {
39
+ return Status(kCorruption, msg, msg2);
40
+ }
41
+ static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) {
42
+ return Status(kNotSupported, msg, msg2);
43
+ }
44
+ static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) {
45
+ return Status(kInvalidArgument, msg, msg2);
46
+ }
47
+ static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) {
48
+ return Status(kIOError, msg, msg2);
49
+ }
50
+
51
+ // Returns true iff the status indicates success.
52
+ bool ok() const { return (state_ == NULL); }
53
+
54
+ // Returns true iff the status indicates a NotFound error.
55
+ bool IsNotFound() const { return code() == kNotFound; }
56
+
57
+ // Returns true iff the status indicates a Corruption error.
58
+ bool IsCorruption() const { return code() == kCorruption; }
59
+
60
+ // Returns true iff the status indicates an IOError.
61
+ bool IsIOError() const { return code() == kIOError; }
62
+
63
+ // Return a string representation of this status suitable for printing.
64
+ // Returns the string "OK" for success.
65
+ std::string ToString() const;
66
+
67
+ private:
68
+ // OK status has a NULL state_. Otherwise, state_ is a new[] array
69
+ // of the following form:
70
+ // state_[0..3] == length of message
71
+ // state_[4] == code
72
+ // state_[5..] == message
73
+ const char* state_;
74
+
75
+ enum Code {
76
+ kOk = 0,
77
+ kNotFound = 1,
78
+ kCorruption = 2,
79
+ kNotSupported = 3,
80
+ kInvalidArgument = 4,
81
+ kIOError = 5
82
+ };
83
+
84
+ Code code() const {
85
+ return (state_ == NULL) ? kOk : static_cast<Code>(state_[4]);
86
+ }
87
+
88
+ Status(Code code, const Slice& msg, const Slice& msg2);
89
+ static const char* CopyState(const char* s);
90
+ };
91
+
92
+ inline Status::Status(const Status& s) {
93
+ state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
94
+ }
95
+ inline void Status::operator=(const Status& s) {
96
+ // The following condition catches both aliasing (when this == &s),
97
+ // and the common case where both s and *this are ok.
98
+ if (state_ != s.state_) {
99
+ delete[] state_;
100
+ state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_);
101
+ }
102
+ }
103
+
104
+ } // namespace leveldb
105
+
106
+ #endif // STORAGE_LEVELDB_INCLUDE_STATUS_H_
@@ -0,0 +1,85 @@
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_INCLUDE_TABLE_H_
6
+ #define STORAGE_LEVELDB_INCLUDE_TABLE_H_
7
+
8
+ #include <stdint.h>
9
+ #include "leveldb/iterator.h"
10
+
11
+ namespace leveldb {
12
+
13
+ class Block;
14
+ class BlockHandle;
15
+ class Footer;
16
+ struct Options;
17
+ class RandomAccessFile;
18
+ struct ReadOptions;
19
+ class TableCache;
20
+
21
+ // A Table is a sorted map from strings to strings. Tables are
22
+ // immutable and persistent. A Table may be safely accessed from
23
+ // multiple threads without external synchronization.
24
+ class Table {
25
+ public:
26
+ // Attempt to open the table that is stored in bytes [0..file_size)
27
+ // of "file", and read the metadata entries necessary to allow
28
+ // retrieving data from the table.
29
+ //
30
+ // If successful, returns ok and sets "*table" to the newly opened
31
+ // table. The client should delete "*table" when no longer needed.
32
+ // If there was an error while initializing the table, sets "*table"
33
+ // to NULL and returns a non-ok status. Does not take ownership of
34
+ // "*source", but the client must ensure that "source" remains live
35
+ // for the duration of the returned table's lifetime.
36
+ //
37
+ // *file must remain live while this Table is in use.
38
+ static Status Open(const Options& options,
39
+ RandomAccessFile* file,
40
+ uint64_t file_size,
41
+ Table** table);
42
+
43
+ ~Table();
44
+
45
+ // Returns a new iterator over the table contents.
46
+ // The result of NewIterator() is initially invalid (caller must
47
+ // call one of the Seek methods on the iterator before using it).
48
+ Iterator* NewIterator(const ReadOptions&) const;
49
+
50
+ // Given a key, return an approximate byte offset in the file where
51
+ // the data for that key begins (or would begin if the key were
52
+ // present in the file). The returned value is in terms of file
53
+ // bytes, and so includes effects like compression of the underlying data.
54
+ // E.g., the approximate offset of the last key in the table will
55
+ // be close to the file length.
56
+ uint64_t ApproximateOffsetOf(const Slice& key) const;
57
+
58
+ private:
59
+ struct Rep;
60
+ Rep* rep_;
61
+
62
+ explicit Table(Rep* rep) { rep_ = rep; }
63
+ static Iterator* BlockReader(void*, const ReadOptions&, const Slice&);
64
+
65
+ // Calls (*handle_result)(arg, ...) with the entry found after a call
66
+ // to Seek(key). May not make such a call if filter policy says
67
+ // that key is not present.
68
+ friend class TableCache;
69
+ Status InternalGet(
70
+ const ReadOptions&, const Slice& key,
71
+ void* arg,
72
+ void (*handle_result)(void* arg, const Slice& k, const Slice& v));
73
+
74
+
75
+ void ReadMeta(const Footer& footer);
76
+ void ReadFilter(const Slice& filter_handle_value);
77
+
78
+ // No copying allowed
79
+ Table(const Table&);
80
+ void operator=(const Table&);
81
+ };
82
+
83
+ } // namespace leveldb
84
+
85
+ #endif // STORAGE_LEVELDB_INCLUDE_TABLE_H_
@@ -0,0 +1,92 @@
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
+ // TableBuilder provides the interface used to build a Table
6
+ // (an immutable and sorted map from keys to values).
7
+ //
8
+ // Multiple threads can invoke const methods on a TableBuilder without
9
+ // external synchronization, but if any of the threads may call a
10
+ // non-const method, all threads accessing the same TableBuilder must use
11
+ // external synchronization.
12
+
13
+ #ifndef STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_
14
+ #define STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_
15
+
16
+ #include <stdint.h>
17
+ #include "leveldb/options.h"
18
+ #include "leveldb/status.h"
19
+
20
+ namespace leveldb {
21
+
22
+ class BlockBuilder;
23
+ class BlockHandle;
24
+ class WritableFile;
25
+
26
+ class TableBuilder {
27
+ public:
28
+ // Create a builder that will store the contents of the table it is
29
+ // building in *file. Does not close the file. It is up to the
30
+ // caller to close the file after calling Finish().
31
+ TableBuilder(const Options& options, WritableFile* file);
32
+
33
+ // REQUIRES: Either Finish() or Abandon() has been called.
34
+ ~TableBuilder();
35
+
36
+ // Change the options used by this builder. Note: only some of the
37
+ // option fields can be changed after construction. If a field is
38
+ // not allowed to change dynamically and its value in the structure
39
+ // passed to the constructor is different from its value in the
40
+ // structure passed to this method, this method will return an error
41
+ // without changing any fields.
42
+ Status ChangeOptions(const Options& options);
43
+
44
+ // Add key,value to the table being constructed.
45
+ // REQUIRES: key is after any previously added key according to comparator.
46
+ // REQUIRES: Finish(), Abandon() have not been called
47
+ void Add(const Slice& key, const Slice& value);
48
+
49
+ // Advanced operation: flush any buffered key/value pairs to file.
50
+ // Can be used to ensure that two adjacent entries never live in
51
+ // the same data block. Most clients should not need to use this method.
52
+ // REQUIRES: Finish(), Abandon() have not been called
53
+ void Flush();
54
+
55
+ // Return non-ok iff some error has been detected.
56
+ Status status() const;
57
+
58
+ // Finish building the table. Stops using the file passed to the
59
+ // constructor after this function returns.
60
+ // REQUIRES: Finish(), Abandon() have not been called
61
+ Status Finish();
62
+
63
+ // Indicate that the contents of this builder should be abandoned. Stops
64
+ // using the file passed to the constructor after this function returns.
65
+ // If the caller is not going to call Finish(), it must call Abandon()
66
+ // before destroying this builder.
67
+ // REQUIRES: Finish(), Abandon() have not been called
68
+ void Abandon();
69
+
70
+ // Number of calls to Add() so far.
71
+ uint64_t NumEntries() const;
72
+
73
+ // Size of the file generated so far. If invoked after a successful
74
+ // Finish() call, returns the size of the final generated file.
75
+ uint64_t FileSize() const;
76
+
77
+ private:
78
+ bool ok() const { return status().ok(); }
79
+ void WriteBlock(BlockBuilder* block, BlockHandle* handle);
80
+ void WriteRawBlock(const Slice& data, CompressionType, BlockHandle* handle);
81
+
82
+ struct Rep;
83
+ Rep* rep_;
84
+
85
+ // No copying allowed
86
+ TableBuilder(const TableBuilder&);
87
+ void operator=(const TableBuilder&);
88
+ };
89
+
90
+ } // namespace leveldb
91
+
92
+ #endif // STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_
@@ -0,0 +1,64 @@
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
+ // WriteBatch holds a collection of updates to apply atomically to a DB.
6
+ //
7
+ // The updates are applied in the order in which they are added
8
+ // to the WriteBatch. For example, the value of "key" will be "v3"
9
+ // after the following batch is written:
10
+ //
11
+ // batch.Put("key", "v1");
12
+ // batch.Delete("key");
13
+ // batch.Put("key", "v2");
14
+ // batch.Put("key", "v3");
15
+ //
16
+ // Multiple threads can invoke const methods on a WriteBatch without
17
+ // external synchronization, but if any of the threads may call a
18
+ // non-const method, all threads accessing the same WriteBatch must use
19
+ // external synchronization.
20
+
21
+ #ifndef STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_
22
+ #define STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_
23
+
24
+ #include <string>
25
+ #include "leveldb/status.h"
26
+
27
+ namespace leveldb {
28
+
29
+ class Slice;
30
+
31
+ class WriteBatch {
32
+ public:
33
+ WriteBatch();
34
+ ~WriteBatch();
35
+
36
+ // Store the mapping "key->value" in the database.
37
+ void Put(const Slice& key, const Slice& value);
38
+
39
+ // If the database contains a mapping for "key", erase it. Else do nothing.
40
+ void Delete(const Slice& key);
41
+
42
+ // Clear all updates buffered in this batch.
43
+ void Clear();
44
+
45
+ // Support for iterating over the contents of a batch.
46
+ class Handler {
47
+ public:
48
+ virtual ~Handler();
49
+ virtual void Put(const Slice& key, const Slice& value) = 0;
50
+ virtual void Delete(const Slice& key) = 0;
51
+ };
52
+ Status Iterate(Handler* handler) const;
53
+
54
+ private:
55
+ friend class WriteBatchInternal;
56
+
57
+ std::string rep_; // See comment in write_batch.cc for the format of rep_
58
+
59
+ // Intentionally copyable
60
+ };
61
+
62
+ } // namespace leveldb
63
+
64
+ #endif // STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_
@@ -0,0 +1,144 @@
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
+ #endif
40
+
41
+ namespace leveldb {
42
+ namespace port {
43
+
44
+ // Define MemoryBarrier() if available
45
+ // Windows on x86
46
+ #if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY)
47
+ // windows.h already provides a MemoryBarrier(void) macro
48
+ // http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx
49
+ #define LEVELDB_HAVE_MEMORY_BARRIER
50
+
51
+ // Gcc on x86
52
+ #elif defined(ARCH_CPU_X86_FAMILY) && defined(__GNUC__)
53
+ inline void MemoryBarrier() {
54
+ // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on
55
+ // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering.
56
+ __asm__ __volatile__("" : : : "memory");
57
+ }
58
+ #define LEVELDB_HAVE_MEMORY_BARRIER
59
+
60
+ // Sun Studio
61
+ #elif defined(ARCH_CPU_X86_FAMILY) && defined(__SUNPRO_CC)
62
+ inline void MemoryBarrier() {
63
+ // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on
64
+ // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering.
65
+ asm volatile("" : : : "memory");
66
+ }
67
+ #define LEVELDB_HAVE_MEMORY_BARRIER
68
+
69
+ // Mac OS
70
+ #elif defined(OS_MACOSX)
71
+ inline void MemoryBarrier() {
72
+ OSMemoryBarrier();
73
+ }
74
+ #define LEVELDB_HAVE_MEMORY_BARRIER
75
+
76
+ // ARM
77
+ #elif defined(ARCH_CPU_ARM_FAMILY)
78
+ typedef void (*LinuxKernelMemoryBarrierFunc)(void);
79
+ LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
80
+ (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
81
+ inline void MemoryBarrier() {
82
+ pLinuxKernelMemoryBarrier();
83
+ }
84
+ #define LEVELDB_HAVE_MEMORY_BARRIER
85
+
86
+ #endif
87
+
88
+ // AtomicPointer built using platform-specific MemoryBarrier()
89
+ #if defined(LEVELDB_HAVE_MEMORY_BARRIER)
90
+ class AtomicPointer {
91
+ private:
92
+ void* rep_;
93
+ public:
94
+ AtomicPointer() { }
95
+ explicit AtomicPointer(void* p) : rep_(p) {}
96
+ inline void* NoBarrier_Load() const { return rep_; }
97
+ inline void NoBarrier_Store(void* v) { rep_ = v; }
98
+ inline void* Acquire_Load() const {
99
+ void* result = rep_;
100
+ MemoryBarrier();
101
+ return result;
102
+ }
103
+ inline void Release_Store(void* v) {
104
+ MemoryBarrier();
105
+ rep_ = v;
106
+ }
107
+ };
108
+
109
+ // AtomicPointer based on <cstdatomic>
110
+ #elif defined(LEVELDB_CSTDATOMIC_PRESENT)
111
+ class AtomicPointer {
112
+ private:
113
+ std::atomic<void*> rep_;
114
+ public:
115
+ AtomicPointer() { }
116
+ explicit AtomicPointer(void* v) : rep_(v) { }
117
+ inline void* Acquire_Load() const {
118
+ return rep_.load(std::memory_order_acquire);
119
+ }
120
+ inline void Release_Store(void* v) {
121
+ rep_.store(v, std::memory_order_release);
122
+ }
123
+ inline void* NoBarrier_Load() const {
124
+ return rep_.load(std::memory_order_relaxed);
125
+ }
126
+ inline void NoBarrier_Store(void* v) {
127
+ rep_.store(v, std::memory_order_relaxed);
128
+ }
129
+ };
130
+
131
+ // We have neither MemoryBarrier(), nor <cstdatomic>
132
+ #else
133
+ #error Please implement AtomicPointer for this platform.
134
+
135
+ #endif
136
+
137
+ #undef LEVELDB_HAVE_MEMORY_BARRIER
138
+ #undef ARCH_CPU_X86_FAMILY
139
+ #undef ARCH_CPU_ARM_FAMILY
140
+
141
+ } // namespace port
142
+ } // namespace leveldb
143
+
144
+ #endif // PORT_ATOMIC_POINTER_H_