leveldb-ruby 0.7 → 0.8

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 (53) hide show
  1. data/README +1 -1
  2. data/leveldb/Makefile +70 -29
  3. data/leveldb/build_detect_platform +74 -0
  4. data/leveldb/db/builder.cc +2 -4
  5. data/leveldb/db/builder.h +4 -6
  6. data/leveldb/db/c.cc +471 -0
  7. data/leveldb/db/corruption_test.cc +21 -16
  8. data/leveldb/db/db_bench.cc +400 -200
  9. data/leveldb/db/db_impl.cc +276 -131
  10. data/leveldb/db/db_impl.h +22 -10
  11. data/leveldb/db/db_iter.cc +2 -1
  12. data/leveldb/db/db_test.cc +391 -43
  13. data/leveldb/db/dbformat.cc +31 -0
  14. data/leveldb/db/dbformat.h +51 -1
  15. data/leveldb/db/filename.h +1 -1
  16. data/leveldb/db/log_format.h +1 -1
  17. data/leveldb/db/log_reader.cc +16 -11
  18. data/leveldb/db/memtable.cc +37 -0
  19. data/leveldb/db/memtable.h +6 -0
  20. data/leveldb/db/repair.cc +17 -14
  21. data/leveldb/db/skiplist_test.cc +2 -2
  22. data/leveldb/db/version_edit.cc +7 -9
  23. data/leveldb/db/version_edit.h +2 -1
  24. data/leveldb/db/version_set.cc +416 -104
  25. data/leveldb/db/version_set.h +78 -14
  26. data/leveldb/db/version_set_test.cc +179 -0
  27. data/leveldb/db/write_batch_internal.h +2 -0
  28. data/leveldb/include/leveldb/c.h +246 -0
  29. data/leveldb/include/leveldb/db.h +14 -2
  30. data/leveldb/include/leveldb/env.h +31 -10
  31. data/leveldb/include/leveldb/options.h +7 -18
  32. data/leveldb/include/leveldb/slice.h +2 -2
  33. data/leveldb/include/leveldb/status.h +1 -1
  34. data/leveldb/port/atomic_pointer.h +144 -0
  35. data/leveldb/port/port.h +0 -2
  36. data/leveldb/port/port_android.h +7 -1
  37. data/leveldb/port/port_example.h +11 -1
  38. data/leveldb/port/port_posix.h +56 -38
  39. data/leveldb/table/format.cc +12 -8
  40. data/leveldb/table/table_test.cc +16 -7
  41. data/leveldb/util/cache.cc +173 -100
  42. data/leveldb/util/cache_test.cc +28 -11
  43. data/leveldb/util/coding.h +4 -4
  44. data/leveldb/util/comparator.cc +1 -0
  45. data/leveldb/util/env.cc +10 -5
  46. data/leveldb/util/env_posix.cc +48 -87
  47. data/leveldb/util/histogram.cc +11 -0
  48. data/leveldb/util/histogram.h +1 -0
  49. data/leveldb/util/posix_logger.h +98 -0
  50. data/leveldb/util/testharness.cc +12 -0
  51. data/leveldb/util/testharness.h +10 -1
  52. data/lib/leveldb.rb +11 -3
  53. metadata +41 -22
@@ -33,6 +33,7 @@ struct Range {
33
33
  Slice start; // Included in the range
34
34
  Slice limit; // Not included in the range
35
35
 
36
+ Range() { }
36
37
  Range(const Slice& s, const Slice& l) : start(s), limit(l) { }
37
38
  };
38
39
 
@@ -111,6 +112,8 @@ class DB {
111
112
  // where <N> is an ASCII representation of a level number (e.g. "0").
112
113
  // "leveldb.stats" - returns a multi-line string that describes statistics
113
114
  // about the internal operation of the DB.
115
+ // "leveldb.sstables" - returns a multi-line string that describes all
116
+ // of the sstables that make up the db contents.
114
117
  virtual bool GetProperty(const Slice& property, std::string* value) = 0;
115
118
 
116
119
  // For each i in [0,n-1], store in "sizes[i]", the approximate
@@ -124,8 +127,17 @@ class DB {
124
127
  virtual void GetApproximateSizes(const Range* range, int n,
125
128
  uint64_t* sizes) = 0;
126
129
 
127
- // Possible extensions:
128
- // (1) Add a method to compact a range of keys
130
+ // Compact the underlying storage for the key range [*begin,*end].
131
+ // In particular, deleted and overwritten versions are discarded,
132
+ // and the data is rearranged to reduce the cost of operations
133
+ // needed to access the data. This operation should typically only
134
+ // be invoked by users who understand the underlying implementation.
135
+ //
136
+ // begin==NULL is treated as a key before all keys in the database.
137
+ // end==NULL is treated as a key after all keys in the database.
138
+ // Therefore the following call will compact the entire database:
139
+ // db->CompactRange(NULL, NULL);
140
+ virtual void CompactRange(const Slice* begin, const Slice* end) = 0;
129
141
 
130
142
  private:
131
143
  // No copying allowed
@@ -22,6 +22,7 @@
22
22
  namespace leveldb {
23
23
 
24
24
  class FileLock;
25
+ class Logger;
25
26
  class RandomAccessFile;
26
27
  class SequentialFile;
27
28
  class Slice;
@@ -134,8 +135,8 @@ class Env {
134
135
  // same directory.
135
136
  virtual Status GetTestDirectory(std::string* path) = 0;
136
137
 
137
- // Write an entry to the log file with the specified format.
138
- virtual void Logv(WritableFile* log, const char* format, va_list ap) = 0;
138
+ // Create and return a log file for storing informational messages.
139
+ virtual Status NewLogger(const std::string& fname, Logger** result) = 0;
139
140
 
140
141
  // Returns the number of micro-seconds since some fixed point in time. Only
141
142
  // useful for computing deltas of time.
@@ -159,6 +160,8 @@ class SequentialFile {
159
160
  // Read up to "n" bytes from the file. "scratch[0..n-1]" may be
160
161
  // written by this routine. Sets "*result" to the data that was
161
162
  // read (including if fewer than "n" bytes were successfully read).
163
+ // May set "*result" to point at data in "scratch[0..n-1]", so
164
+ // "scratch[0..n-1]" must be live when "*result" is used.
162
165
  // If an error was encountered, returns a non-OK status.
163
166
  //
164
167
  // REQUIRES: External synchronization
@@ -183,8 +186,10 @@ class RandomAccessFile {
183
186
  // Read up to "n" bytes from the file starting at "offset".
184
187
  // "scratch[0..n-1]" may be written by this routine. Sets "*result"
185
188
  // to the data that was read (including if fewer than "n" bytes were
186
- // successfully read). If an error was encountered, returns a
187
- // non-OK status.
189
+ // successfully read). May set "*result" to point at data in
190
+ // "scratch[0..n-1]", so "scratch[0..n-1]" must be live when
191
+ // "*result" is used. If an error was encountered, returns a non-OK
192
+ // status.
188
193
  //
189
194
  // Safe for concurrent use by multiple threads.
190
195
  virtual Status Read(uint64_t offset, size_t n, Slice* result,
@@ -210,6 +215,22 @@ class WritableFile {
210
215
  void operator=(const WritableFile&);
211
216
  };
212
217
 
218
+ // An interface for writing log messages.
219
+ class Logger {
220
+ public:
221
+ Logger() { }
222
+ virtual ~Logger();
223
+
224
+ // Write an entry to the log file with the specified format.
225
+ virtual void Logv(const char* format, va_list ap) = 0;
226
+
227
+ private:
228
+ // No copying allowed
229
+ Logger(const Logger&);
230
+ void operator=(const Logger&);
231
+ };
232
+
233
+
213
234
  // Identifies a locked file.
214
235
  class FileLock {
215
236
  public:
@@ -222,9 +243,9 @@ class FileLock {
222
243
  };
223
244
 
224
245
  // Log the specified data to *info_log if info_log is non-NULL.
225
- extern void Log(Env* env, WritableFile* info_log, const char* format, ...)
246
+ extern void Log(Logger* info_log, const char* format, ...)
226
247
  # if defined(__GNUC__) || defined(__clang__)
227
- __attribute__((__format__ (__printf__, 3, 4)))
248
+ __attribute__((__format__ (__printf__, 2, 3)))
228
249
  # endif
229
250
  ;
230
251
 
@@ -241,8 +262,8 @@ extern Status ReadFileToString(Env* env, const std::string& fname,
241
262
  // functionality of another Env.
242
263
  class EnvWrapper : public Env {
243
264
  public:
244
- // Initialize an EnvWrapper that delegates all calls to *target
245
- explicit EnvWrapper(Env* target) : target_(target) { }
265
+ // Initialize an EnvWrapper that delegates all calls to *t
266
+ explicit EnvWrapper(Env* t) : target_(t) { }
246
267
  virtual ~EnvWrapper();
247
268
 
248
269
  // Return the target to which this Env forwards all calls
@@ -284,8 +305,8 @@ class EnvWrapper : public Env {
284
305
  virtual Status GetTestDirectory(std::string* path) {
285
306
  return target_->GetTestDirectory(path);
286
307
  }
287
- virtual void Logv(WritableFile* log, const char* format, va_list ap) {
288
- return target_->Logv(log, format, ap);
308
+ virtual Status NewLogger(const std::string& fname, Logger** result) {
309
+ return target_->NewLogger(fname, result);
289
310
  }
290
311
  uint64_t NowMicros() {
291
312
  return target_->NowMicros();
@@ -12,8 +12,8 @@ namespace leveldb {
12
12
  class Cache;
13
13
  class Comparator;
14
14
  class Env;
15
+ class Logger;
15
16
  class Snapshot;
16
- class WritableFile;
17
17
 
18
18
  // DB contents are stored in a set of blocks, each of which holds a
19
19
  // sequence of key,value pairs. Each block may be compressed before
@@ -23,7 +23,7 @@ enum CompressionType {
23
23
  // NOTE: do not change the values of existing entries, as these are
24
24
  // part of the persistent format on disk.
25
25
  kNoCompression = 0x0,
26
- kSnappyCompression = 0x1,
26
+ kSnappyCompression = 0x1
27
27
  };
28
28
 
29
29
  // Options to control the behavior of a database (passed to DB::Open)
@@ -61,10 +61,10 @@ struct Options {
61
61
  Env* env;
62
62
 
63
63
  // Any internal progress/error information generated by the db will
64
- // be to written to info_log if it is non-NULL, or to a file stored
64
+ // be written to info_log if it is non-NULL, or to a file stored
65
65
  // in the same directory as the DB contents if info_log is NULL.
66
66
  // Default: NULL
67
- WritableFile* info_log;
67
+ Logger* info_log;
68
68
 
69
69
  // -------------------
70
70
  // Parameters that affect performance
@@ -75,6 +75,8 @@ struct Options {
75
75
  // Larger values increase performance, especially during bulk loads.
76
76
  // Up to two write buffers may be held in memory at the same time,
77
77
  // so you may wish to adjust this parameter to control memory usage.
78
+ // Also, a larger write buffer will result in a longer recovery time
79
+ // the next time the database is opened.
78
80
  //
79
81
  // Default: 4MB
80
82
  size_t write_buffer_size;
@@ -175,21 +177,8 @@ struct WriteOptions {
175
177
  // Default: false
176
178
  bool sync;
177
179
 
178
- // If "post_write_snapshot" is non-NULL, and the write succeeds,
179
- // *post_write_snapshot will be modified to point to a snapshot of
180
- // the DB state immediately after this write. The caller must call
181
- // DB::ReleaseSnapshot(*post_write_snapshotsnapshot) when the
182
- // snapshot is no longer needed.
183
- //
184
- // If "post_write_snapshot" is non-NULL, and the write fails,
185
- // *post_write_snapshot will be set to NULL.
186
- //
187
- // Default: NULL
188
- const Snapshot** post_write_snapshot;
189
-
190
180
  WriteOptions()
191
- : sync(false),
192
- post_write_snapshot(NULL) {
181
+ : sync(false) {
193
182
  }
194
183
  };
195
184
 
@@ -27,8 +27,8 @@ class Slice {
27
27
  // Create an empty slice.
28
28
  Slice() : data_(""), size_(0) { }
29
29
 
30
- // Create a slice that refers to data[0,n-1].
31
- Slice(const char* data, size_t n) : data_(data), size_(n) { }
30
+ // Create a slice that refers to d[0,n-1].
31
+ Slice(const char* d, size_t n) : data_(d), size_(n) { }
32
32
 
33
33
  // Create a slice that refers to the contents of "s"
34
34
  Slice(const std::string& s) : data_(s.data()), size_(s.size()) { }
@@ -72,7 +72,7 @@ class Status {
72
72
  kCorruption = 2,
73
73
  kNotSupported = 3,
74
74
  kInvalidArgument = 4,
75
- kIOError = 5,
75
+ kIOError = 5
76
76
  };
77
77
 
78
78
  Code code() const {
@@ -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 leveldb::port
142
+ } // namespace leveldb
143
+
144
+ #endif // PORT_ATOMIC_POINTER_H_
data/leveldb/port/port.h CHANGED
@@ -16,8 +16,6 @@
16
16
  # include "port/port_chromium.h"
17
17
  #elif defined(LEVELDB_PLATFORM_ANDROID)
18
18
  # include "port/port_android.h"
19
- #elif defined(LEVELDB_PLATFORM_OSX)
20
- # include "port/port_osx.h"
21
19
  #endif
22
20
 
23
21
  #endif // STORAGE_LEVELDB_PORT_PORT_H_
@@ -125,11 +125,17 @@ inline bool Snappy_Compress(
125
125
  return false;
126
126
  }
127
127
 
128
+ // TODO(gabor): Implement uncompress
129
+ inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
130
+ size_t* result) {
131
+ return false;
132
+ }
133
+
128
134
  // TODO(gabor): Implement uncompress
129
135
  inline bool Snappy_Uncompress(
130
136
  const char* input_data,
131
137
  size_t input_length,
132
- std::string* output) {
138
+ char* output) {
133
139
  return false;
134
140
  }
135
141
 
@@ -96,11 +96,21 @@ class AtomicPointer {
96
96
  extern bool Snappy_Compress(const char* input, size_t input_length,
97
97
  std::string* output);
98
98
 
99
+ // If input[0,input_length-1] looks like a valid snappy compressed
100
+ // buffer, store the size of the uncompressed data in *result and
101
+ // return true. Else return false.
102
+ extern bool Snappy_GetUncompressedLength(const char* input, size_t length,
103
+ size_t* result);
104
+
99
105
  // Attempt to snappy uncompress input[0,input_length-1] into *output.
100
106
  // Returns true if successful, false if the input is invalid lightweight
101
107
  // compressed data.
108
+ //
109
+ // REQUIRES: at least the first "n" bytes of output[] must be writable
110
+ // where "n" is the result of a successful call to
111
+ // Snappy_GetUncompressedLength.
102
112
  extern bool Snappy_Uncompress(const char* input_data, size_t input_length,
103
- std::string* output);
113
+ char* output);
104
114
 
105
115
  // ------------------ Miscellaneous -------------------
106
116
 
@@ -7,26 +7,46 @@
7
7
  #ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_
8
8
  #define STORAGE_LEVELDB_PORT_PORT_POSIX_H_
9
9
 
10
- #define GCC_VERSION (__GNUC__ * 10000 \
11
- + __GNUC_MINOR__ * 100 \
12
- + __GNUC_PATCHLEVEL__)
13
- #include <endian.h>
10
+ #if defined(OS_MACOSX) || defined(OS_FREEBSD)
11
+ #include <machine/endian.h>
12
+ #elif defined(OS_SOLARIS)
13
+ #include <sys/isa_defs.h>
14
+ #ifdef _LITTLE_ENDIAN
15
+ #define LITTLE_ENDIAN
16
+ #else
17
+ #define BIG_ENDIAN
18
+ #endif
19
+ #else
20
+ #include <endian.h>
21
+ #endif
14
22
  #include <pthread.h>
23
+ #ifdef SNAPPY
24
+ #include <snappy.h>
25
+ #endif
15
26
  #include <stdint.h>
16
27
  #include <string>
28
+ #include "port/atomic_pointer.h"
17
29
 
18
- #if GCC_VERSION > 40500 // check for GCC > 4.5
19
- #include <atomic>
30
+ #ifdef LITTLE_ENDIAN
31
+ #define IS_LITTLE_ENDIAN true
20
32
  #else
21
- #include <cstdatomic>
22
- #endif // if GCC_VERSION > 40500
33
+ #define IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
34
+ #endif
35
+
36
+ #if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD)
37
+ #define fread_unlocked fread
38
+ #define fwrite_unlocked fwrite
39
+ #define fflush_unlocked fflush
40
+ #endif
23
41
 
24
- #include <cstring>
42
+ #if defined(OS_MACOSX) || defined(OS_FREEBSD)
43
+ #define fdatasync fsync
44
+ #endif
25
45
 
26
46
  namespace leveldb {
27
47
  namespace port {
28
48
 
29
- static const bool kLittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN);
49
+ static const bool kLittleEndian = IS_LITTLE_ENDIAN;
30
50
 
31
51
  class CondVar;
32
52
 
@@ -60,44 +80,42 @@ class CondVar {
60
80
  Mutex* mu_;
61
81
  };
62
82
 
63
- // Storage for a lock-free pointer
64
- class AtomicPointer {
65
- private:
66
- std::atomic<void*> rep_;
67
- public:
68
- AtomicPointer() { }
69
- explicit AtomicPointer(void* v) : rep_(v) { }
70
- inline void* Acquire_Load() const {
71
- return rep_.load(std::memory_order_acquire);
72
- }
73
- inline void Release_Store(void* v) {
74
- rep_.store(v, std::memory_order_release);
75
- }
76
- inline void* NoBarrier_Load() const {
77
- return rep_.load(std::memory_order_relaxed);
78
- }
79
- inline void NoBarrier_Store(void* v) {
80
- rep_.store(v, std::memory_order_relaxed);
81
- }
82
- };
83
+ inline bool Snappy_Compress(const char* input, size_t length,
84
+ ::std::string* output) {
85
+ #ifdef SNAPPY
86
+ output->resize(snappy::MaxCompressedLength(length));
87
+ size_t outlen;
88
+ snappy::RawCompress(input, length, &(*output)[0], &outlen);
89
+ output->resize(outlen);
90
+ return true;
91
+ #endif
92
+
93
+ return false;
94
+ }
83
95
 
84
- // TODO(gabor): Implement actual compress
85
- inline bool Snappy_Compress(const char* input, size_t input_length,
86
- std::string* output) {
96
+ inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
97
+ size_t* result) {
98
+ #ifdef SNAPPY
99
+ return snappy::GetUncompressedLength(input, length, result);
100
+ #else
87
101
  return false;
102
+ #endif
88
103
  }
89
104
 
90
- // TODO(gabor): Implement actual uncompress
91
- inline bool Snappy_Uncompress(const char* input_data, size_t input_length,
92
- std::string* output) {
105
+ inline bool Snappy_Uncompress(const char* input, size_t length,
106
+ char* output) {
107
+ #ifdef SNAPPY
108
+ return snappy::RawUncompress(input, length, output);
109
+ #else
93
110
  return false;
111
+ #endif
94
112
  }
95
113
 
96
114
  inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
97
115
  return false;
98
116
  }
99
117
 
100
- }
101
- }
118
+ } // namespace port
119
+ } // namespace leveldb
102
120
 
103
121
  #endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_