filiptepper-leveldb-ruby 0.14

Sign up to get free protection for your applications and to get access to all the features.
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_