leveldb-ruby 0.7 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
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
data/README CHANGED
@@ -10,7 +10,7 @@ And then run this:
10
10
  require 'rubygems' # on ruby < 1.9
11
11
  require 'leveldb'
12
12
 
13
- db = LevelDB.new "/tmp/asdf"
13
+ db = LevelDB::DB.new "/tmp/asdf"
14
14
  db.put "it", "works"
15
15
  db.get "it"
16
16
 
data/leveldb/Makefile CHANGED
@@ -13,27 +13,36 @@ OPT = -O2 -DNDEBUG -fPIC # (A) Production use (optimized mode)
13
13
  # OPT = -O2 -g2 -DNDEBUG # (C) Profiling mode: opt, but w/debugging symbols
14
14
  #-----------------------------------------------
15
15
 
16
+ # detect what platform we're building on
17
+ $(shell sh ./build_detect_platform)
18
+ # this file is generated by build_detect_platform to set build flags
19
+ include build_config.mk
20
+
21
+ # If Snappy is installed, add compilation and linker flags
22
+ # (see http://code.google.com/p/snappy/)
23
+ ifeq ($(SNAPPY), 1)
24
+ SNAPPY_CFLAGS=-DSNAPPY
25
+ SNAPPY_LDFLAGS=-lsnappy
26
+ else
27
+ SNAPPY_CFLAGS=
28
+ SNAPPY_LDFLAGS=
29
+ endif
16
30
 
17
- UNAME := $(shell uname)
18
-
19
- ifeq ($(UNAME), Darwin)
20
- # To build for iOS, set PLATFORM=IOS.
21
- ifndef PLATFORM
22
- PLATFORM=OSX
23
- endif # PLATFORM
24
- PLATFORM_CFLAGS = -DLEVELDB_PLATFORM_OSX
25
- PORT_MODULE = port_osx.o
26
- else # UNAME
27
- PLATFORM_CFLAGS = -DLEVELDB_PLATFORM_POSIX -std=c++0x
28
- PORT_MODULE = port_posix.o
29
- endif # UNAME
31
+ # If Google Perf Tools are installed, add compilation and linker flags
32
+ # (see http://code.google.com/p/google-perftools/)
33
+ ifeq ($(GOOGLE_PERFTOOLS), 1)
34
+ GOOGLE_PERFTOOLS_LDFLAGS=-ltcmalloc
35
+ else
36
+ GOOGLE_PERFTOOLS_LDFLAGS=
37
+ endif
30
38
 
31
- CFLAGS = -c -I. -I./include $(PLATFORM_CFLAGS) $(OPT) -DUSE_SNAPPY=1
39
+ CFLAGS = -c -I. -I./include $(PORT_CFLAGS) $(PLATFORM_CFLAGS) $(OPT) $(SNAPPY_CFLAGS)
32
40
 
33
- LDFLAGS=-lpthread
41
+ LDFLAGS=$(PLATFORM_LDFLAGS) $(SNAPPY_LDFLAGS) $(GOOGLE_PERFTOOLS_LDFLAGS)
34
42
 
35
43
  LIBOBJECTS = \
36
44
  ./db/builder.o \
45
+ ./db/c.o \
37
46
  ./db/db_impl.o \
38
47
  ./db/db_iter.o \
39
48
  ./db/filename.o \
@@ -46,7 +55,7 @@ LIBOBJECTS = \
46
55
  ./db/version_edit.o \
47
56
  ./db/version_set.o \
48
57
  ./db/write_batch.o \
49
- ./port/$(PORT_MODULE) \
58
+ ./port/port_posix.o \
50
59
  ./table/block.o \
51
60
  ./table/block_builder.o \
52
61
  ./table/format.o \
@@ -73,6 +82,7 @@ TESTHARNESS = ./util/testharness.o $(TESTUTIL)
73
82
 
74
83
  TESTS = \
75
84
  arena_test \
85
+ c_test \
76
86
  cache_test \
77
87
  coding_test \
78
88
  corruption_test \
@@ -82,28 +92,28 @@ TESTS = \
82
92
  env_test \
83
93
  filename_test \
84
94
  log_test \
95
+ memenv_test \
85
96
  skiplist_test \
86
97
  table_test \
87
98
  version_edit_test \
99
+ version_set_test \
88
100
  write_batch_test
89
101
 
90
102
  PROGRAMS = db_bench $(TESTS)
103
+ BENCHMARKS = db_bench_sqlite3 db_bench_tree_db
91
104
 
92
105
  LIBRARY = libleveldb.a
106
+ MEMENVLIBRARY = libmemenv.a
93
107
 
94
- ifeq ($(PLATFORM), IOS)
95
- # Only XCode can build executable applications for iOS.
96
108
  all: $(LIBRARY)
97
- else
98
- all: $(PROGRAMS) $(LIBRARY)
99
- endif
100
109
 
101
- check: $(TESTS)
110
+ check: $(PROGRAMS) $(TESTS)
102
111
  for t in $(TESTS); do echo "***** Running $$t"; ./$$t || exit 1; done
103
112
 
104
113
  clean:
105
- -rm -f $(PROGRAMS) $(LIBRARY) */*.o ios-x86/*/*.o ios-arm/*/*.o
106
- -rmdir -p ios-x86/* ios-arm/*
114
+ -rm -f $(PROGRAMS) $(BENCHMARKS) $(LIBRARY) $(MEMENVLIBRARY) */*.o */*/*.o ios-x86/*/*.o ios-arm/*/*.o
115
+ -rm -rf ios-x86/* ios-arm/*
116
+ -rm build_config.mk
107
117
 
108
118
  $(LIBRARY): $(LIBOBJECTS)
109
119
  rm -f $@
@@ -112,9 +122,18 @@ $(LIBRARY): $(LIBOBJECTS)
112
122
  db_bench: db/db_bench.o $(LIBOBJECTS) $(TESTUTIL)
113
123
  $(CC) $(LDFLAGS) db/db_bench.o $(LIBOBJECTS) $(TESTUTIL) -o $@
114
124
 
125
+ db_bench_sqlite3: doc/bench/db_bench_sqlite3.o $(LIBOBJECTS) $(TESTUTIL)
126
+ $(CC) $(LDFLAGS) -lsqlite3 doc/bench/db_bench_sqlite3.o $(LIBOBJECTS) $(TESTUTIL) -o $@
127
+
128
+ db_bench_tree_db: doc/bench/db_bench_tree_db.o $(LIBOBJECTS) $(TESTUTIL)
129
+ $(CC) $(LDFLAGS) -lkyotocabinet doc/bench/db_bench_tree_db.o $(LIBOBJECTS) $(TESTUTIL) -o $@
130
+
115
131
  arena_test: util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS)
116
132
  $(CC) $(LDFLAGS) util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
117
133
 
134
+ c_test: db/c_test.o $(LIBOBJECTS) $(TESTHARNESS)
135
+ $(CC) $(LDFLAGS) db/c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
136
+
118
137
  cache_test: util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS)
119
138
  $(CC) $(LDFLAGS) util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
120
139
 
@@ -151,22 +170,44 @@ skiplist_test: db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS)
151
170
  version_edit_test: db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS)
152
171
  $(CC) $(LDFLAGS) db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
153
172
 
173
+ version_set_test: db/version_set_test.o $(LIBOBJECTS) $(TESTHARNESS)
174
+ $(CC) $(LDFLAGS) db/version_set_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
175
+
154
176
  write_batch_test: db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS)
155
177
  $(CC) $(LDFLAGS) db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
156
178
 
179
+ $(MEMENVLIBRARY) : helpers/memenv/memenv.o
180
+ rm -f $@
181
+ $(AR) -rs $@ helpers/memenv/memenv.o
182
+
183
+ memenv_test : helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS)
184
+ $(CC) $(LDFLAGS) helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS) -o $@
185
+
157
186
  ifeq ($(PLATFORM), IOS)
158
187
  # For iOS, create universal object files to be used on both the simulator and
159
188
  # a device.
189
+ SIMULATORROOT=/Developer/Platforms/iPhoneSimulator.platform/Developer
190
+ DEVICEROOT=/Developer/Platforms/iPhoneOS.platform/Developer
191
+ IOSVERSION=$(shell defaults read /Developer/Platforms/iPhoneOS.platform/version CFBundleShortVersionString)
192
+
160
193
  .cc.o:
161
194
  mkdir -p ios-x86/$(dir $@)
162
- $(CC) $(CFLAGS) -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -arch i686 $< -o ios-x86/$@
195
+ $(SIMULATORROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 $< -o ios-x86/$@
196
+ mkdir -p ios-arm/$(dir $@)
197
+ $(DEVICEROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 $< -o ios-arm/$@
198
+ lipo ios-x86/$@ ios-arm/$@ -create -output $@
199
+
200
+ .c.o:
201
+ mkdir -p ios-x86/$(dir $@)
202
+ $(SIMULATORROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 $< -o ios-x86/$@
163
203
  mkdir -p ios-arm/$(dir $@)
164
- $(CC) $(CFLAGS) -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -arch armv6 -arch armv7 $< -o ios-arm/$@
204
+ $(DEVICEROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 $< -o ios-arm/$@
165
205
  lipo ios-x86/$@ ios-arm/$@ -create -output $@
206
+
166
207
  else
167
208
  .cc.o:
168
209
  $(CC) $(CFLAGS) $< -o $@
169
- endif
170
210
 
171
- # TODO(gabor): dependencies for .o files
172
- # TODO(gabor): Build library
211
+ .c.o:
212
+ $(CC) $(CFLAGS) $< -o $@
213
+ endif
@@ -0,0 +1,74 @@
1
+ #!/bin/sh
2
+
3
+ # Detects OS we're compiling on and generates build_config.mk,
4
+ # which in turn gets read while processing Makefile.
5
+
6
+ # build_config.mk will set the following variables:
7
+ # - PORT_CFLAGS will either set:
8
+ # -DLEVELDB_PLATFORM_POSIX if cstatomic is present
9
+ # -DLEVELDB_PLATFORM_NOATOMIC if it is not
10
+ # - PLATFORM_CFLAGS with compiler flags for the platform
11
+ # - PLATFORM_LDFLAGS with linker flags for the platform
12
+
13
+ # Delete existing build_config.mk
14
+ rm -f build_config.mk
15
+
16
+ # Detect OS
17
+ case `uname -s` in
18
+ Darwin)
19
+ PLATFORM=OS_MACOSX
20
+ echo "PLATFORM_CFLAGS=-DOS_MACOSX" >> build_config.mk
21
+ echo "PLATFORM_LDFLAGS=" >> build_config.mk
22
+ ;;
23
+ Linux)
24
+ PLATFORM=OS_LINUX
25
+ echo "PLATFORM_CFLAGS=-pthread -DOS_LINUX" >> build_config.mk
26
+ echo "PLATFORM_LDFLAGS=-lpthread" >> build_config.mk
27
+ ;;
28
+ SunOS)
29
+ PLATFORM=OS_SOLARIS
30
+ echo "PLATFORM_CFLAGS=-D_REENTRANT -DOS_SOLARIS" >> build_config.mk
31
+ echo "PLATFORM_LDFLAGS=-lpthread -lrt" >> build_config.mk
32
+ ;;
33
+ FreeBSD)
34
+ PLATFORM=OS_FREEBSD
35
+ echo "PLATFORM_CFLAGS=-D_REENTRANT -DOS_FREEBSD" >> build_config.mk
36
+ echo "PLATFORM_LDFLAGS=-lpthread" >> build_config.mk
37
+ ;;
38
+ *)
39
+ echo "Unknown platform!"
40
+ exit 1
41
+ esac
42
+
43
+ echo "PLATFORM=$PLATFORM" >> build_config.mk
44
+
45
+ # On GCC, use libc's memcmp, not GCC's memcmp
46
+ PORT_CFLAGS="-fno-builtin-memcmp"
47
+
48
+ # Detect C++0x -- this determines whether we'll use port_noatomic.h
49
+ # or port_posix.h by:
50
+ # 1. Rrying to compile with -std=c++0x and including <cstdatomic>.
51
+ # 2. If g++ returns error code, we know to use port_posix.h
52
+ g++ $CFLAGS -std=c++0x -x c++ - -o /dev/null 2>/dev/null <<EOF
53
+ #include <cstdatomic>
54
+ int main() {}
55
+ EOF
56
+ if [ "$?" = 0 ]; then
57
+ PORT_CFLAGS="$PORT_CFLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_CSTDATOMIC_PRESENT -std=c++0x"
58
+ else
59
+ PORT_CFLAGS="$PORT_CFLAGS -DLEVELDB_PLATFORM_POSIX"
60
+ fi
61
+
62
+ # Test whether Snappy library is installed
63
+ # http://code.google.com/p/snappy/
64
+ g++ $CFLAGS -x c++ - -o /dev/null 2>/dev/null <<EOF
65
+ #include <snappy.h>
66
+ int main() {}
67
+ EOF
68
+ if [ "$?" = 0 ]; then
69
+ echo "SNAPPY=1" >> build_config.mk
70
+ else
71
+ echo "SNAPPY=0" >> build_config.mk
72
+ fi
73
+
74
+ echo "PORT_CFLAGS=$PORT_CFLAGS" >> build_config.mk
@@ -19,8 +19,7 @@ Status BuildTable(const std::string& dbname,
19
19
  const Options& options,
20
20
  TableCache* table_cache,
21
21
  Iterator* iter,
22
- FileMetaData* meta,
23
- VersionEdit* edit) {
22
+ FileMetaData* meta) {
24
23
  Status s;
25
24
  meta->file_size = 0;
26
25
  iter->SeekToFirst();
@@ -79,8 +78,7 @@ Status BuildTable(const std::string& dbname,
79
78
  }
80
79
 
81
80
  if (s.ok() && meta->file_size > 0) {
82
- edit->AddFile(0, meta->number, meta->file_size,
83
- meta->smallest, meta->largest);
81
+ // Keep it
84
82
  } else {
85
83
  env->DeleteFile(fname);
86
84
  }
data/leveldb/db/builder.h CHANGED
@@ -19,17 +19,15 @@ class VersionEdit;
19
19
 
20
20
  // Build a Table file from the contents of *iter. The generated file
21
21
  // will be named according to meta->number. On success, the rest of
22
- // *meta will be filled with metadata about the generated table, and
23
- // the file information will be added to *edit. If no data is present
24
- // in *iter, meta->file_size will be set to zero, and no Table file
25
- // will be produced.
22
+ // *meta will be filled with metadata about the generated table.
23
+ // If no data is present in *iter, meta->file_size will be set to
24
+ // zero, and no Table file will be produced.
26
25
  extern Status BuildTable(const std::string& dbname,
27
26
  Env* env,
28
27
  const Options& options,
29
28
  TableCache* table_cache,
30
29
  Iterator* iter,
31
- FileMetaData* meta,
32
- VersionEdit* edit);
30
+ FileMetaData* meta);
33
31
 
34
32
  }
35
33
 
data/leveldb/db/c.cc ADDED
@@ -0,0 +1,471 @@
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 "leveldb/c.h"
6
+
7
+ #include <stdlib.h>
8
+ #include <unistd.h>
9
+ #include "leveldb/cache.h"
10
+ #include "leveldb/comparator.h"
11
+ #include "leveldb/db.h"
12
+ #include "leveldb/env.h"
13
+ #include "leveldb/iterator.h"
14
+ #include "leveldb/options.h"
15
+ #include "leveldb/status.h"
16
+ #include "leveldb/write_batch.h"
17
+
18
+ using leveldb::Cache;
19
+ using leveldb::Comparator;
20
+ using leveldb::CompressionType;
21
+ using leveldb::DB;
22
+ using leveldb::Env;
23
+ using leveldb::FileLock;
24
+ using leveldb::Iterator;
25
+ using leveldb::Logger;
26
+ using leveldb::NewLRUCache;
27
+ using leveldb::Options;
28
+ using leveldb::RandomAccessFile;
29
+ using leveldb::Range;
30
+ using leveldb::ReadOptions;
31
+ using leveldb::SequentialFile;
32
+ using leveldb::Slice;
33
+ using leveldb::Snapshot;
34
+ using leveldb::Status;
35
+ using leveldb::WritableFile;
36
+ using leveldb::WriteBatch;
37
+ using leveldb::WriteOptions;
38
+
39
+ extern "C" {
40
+
41
+ struct leveldb_t { DB* rep; };
42
+ struct leveldb_iterator_t { Iterator* rep; };
43
+ struct leveldb_writebatch_t { WriteBatch rep; };
44
+ struct leveldb_snapshot_t { const Snapshot* rep; };
45
+ struct leveldb_readoptions_t { ReadOptions rep; };
46
+ struct leveldb_writeoptions_t { WriteOptions rep; };
47
+ struct leveldb_options_t { Options rep; };
48
+ struct leveldb_cache_t { Cache* rep; };
49
+ struct leveldb_seqfile_t { SequentialFile* rep; };
50
+ struct leveldb_randomfile_t { RandomAccessFile* rep; };
51
+ struct leveldb_writablefile_t { WritableFile* rep; };
52
+ struct leveldb_logger_t { Logger* rep; };
53
+ struct leveldb_filelock_t { FileLock* rep; };
54
+
55
+ struct leveldb_comparator_t : public Comparator {
56
+ void* state_;
57
+ void (*destructor_)(void*);
58
+ int (*compare_)(
59
+ void*,
60
+ const char* a, size_t alen,
61
+ const char* b, size_t blen);
62
+ const char* (*name_)(void*);
63
+
64
+ virtual ~leveldb_comparator_t() {
65
+ (*destructor_)(state_);
66
+ }
67
+
68
+ virtual int Compare(const Slice& a, const Slice& b) const {
69
+ return (*compare_)(state_, a.data(), a.size(), b.data(), b.size());
70
+ }
71
+
72
+ virtual const char* Name() const {
73
+ return (*name_)(state_);
74
+ }
75
+
76
+ // No-ops since the C binding does not support key shortening methods.
77
+ virtual void FindShortestSeparator(std::string*, const Slice&) const { }
78
+ virtual void FindShortSuccessor(std::string* key) const { }
79
+ };
80
+
81
+ struct leveldb_env_t {
82
+ Env* rep;
83
+ bool is_default;
84
+ };
85
+
86
+ static bool SaveError(char** errptr, const Status& s) {
87
+ assert(errptr != NULL);
88
+ if (s.ok()) {
89
+ return false;
90
+ } else if (*errptr == NULL) {
91
+ *errptr = strdup(s.ToString().c_str());
92
+ } else {
93
+ // TODO(sanjay): Merge with existing error?
94
+ free(*errptr);
95
+ *errptr = strdup(s.ToString().c_str());
96
+ }
97
+ return true;
98
+ }
99
+
100
+ static char* CopyString(const std::string& str) {
101
+ char* result = reinterpret_cast<char*>(malloc(sizeof(char) * str.size()));
102
+ memcpy(result, str.data(), sizeof(char) * str.size());
103
+ return result;
104
+ }
105
+
106
+ leveldb_t* leveldb_open(
107
+ const leveldb_options_t* options,
108
+ const char* name,
109
+ char** errptr) {
110
+ DB* db;
111
+ if (SaveError(errptr, DB::Open(options->rep, std::string(name), &db))) {
112
+ return NULL;
113
+ }
114
+ leveldb_t* result = new leveldb_t;
115
+ result->rep = db;
116
+ return result;
117
+ }
118
+
119
+ void leveldb_close(leveldb_t* db) {
120
+ delete db->rep;
121
+ delete db;
122
+ }
123
+
124
+ void leveldb_put(
125
+ leveldb_t* db,
126
+ const leveldb_writeoptions_t* options,
127
+ const char* key, size_t keylen,
128
+ const char* val, size_t vallen,
129
+ char** errptr) {
130
+ SaveError(errptr,
131
+ db->rep->Put(options->rep, Slice(key, keylen), Slice(val, vallen)));
132
+ }
133
+
134
+ void leveldb_delete(
135
+ leveldb_t* db,
136
+ const leveldb_writeoptions_t* options,
137
+ const char* key, size_t keylen,
138
+ char** errptr) {
139
+ SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen)));
140
+ }
141
+
142
+
143
+ void leveldb_write(
144
+ leveldb_t* db,
145
+ const leveldb_writeoptions_t* options,
146
+ leveldb_writebatch_t* batch,
147
+ char** errptr) {
148
+ SaveError(errptr, db->rep->Write(options->rep, &batch->rep));
149
+ }
150
+
151
+ char* leveldb_get(
152
+ leveldb_t* db,
153
+ const leveldb_readoptions_t* options,
154
+ const char* key, size_t keylen,
155
+ size_t* vallen,
156
+ char** errptr) {
157
+ char* result = NULL;
158
+ std::string tmp;
159
+ Status s = db->rep->Get(options->rep, Slice(key, keylen), &tmp);
160
+ if (s.ok()) {
161
+ *vallen = tmp.size();
162
+ result = CopyString(tmp);
163
+ } else {
164
+ *vallen = 0;
165
+ if (!s.IsNotFound()) {
166
+ SaveError(errptr, s);
167
+ }
168
+ }
169
+ return result;
170
+ }
171
+
172
+ leveldb_iterator_t* leveldb_create_iterator(
173
+ leveldb_t* db,
174
+ const leveldb_readoptions_t* options) {
175
+ leveldb_iterator_t* result = new leveldb_iterator_t;
176
+ result->rep = db->rep->NewIterator(options->rep);
177
+ return result;
178
+ }
179
+
180
+ const leveldb_snapshot_t* leveldb_create_snapshot(
181
+ leveldb_t* db) {
182
+ leveldb_snapshot_t* result = new leveldb_snapshot_t;
183
+ result->rep = db->rep->GetSnapshot();
184
+ return result;
185
+ }
186
+
187
+ void leveldb_release_snapshot(
188
+ leveldb_t* db,
189
+ const leveldb_snapshot_t* snapshot) {
190
+ db->rep->ReleaseSnapshot(snapshot->rep);
191
+ delete snapshot;
192
+ }
193
+
194
+ char* leveldb_property_value(
195
+ leveldb_t* db,
196
+ const char* propname) {
197
+ std::string tmp;
198
+ if (db->rep->GetProperty(Slice(propname), &tmp)) {
199
+ // We use strdup() since we expect human readable output.
200
+ return strdup(tmp.c_str());
201
+ } else {
202
+ return NULL;
203
+ }
204
+ }
205
+
206
+ void leveldb_approximate_sizes(
207
+ leveldb_t* db,
208
+ int num_ranges,
209
+ const char* const* range_start_key, const size_t* range_start_key_len,
210
+ const char* const* range_limit_key, const size_t* range_limit_key_len,
211
+ uint64_t* sizes) {
212
+ Range* ranges = new Range[num_ranges];
213
+ for (int i = 0; i < num_ranges; i++) {
214
+ ranges[i].start = Slice(range_start_key[i], range_start_key_len[i]);
215
+ ranges[i].limit = Slice(range_limit_key[i], range_limit_key_len[i]);
216
+ }
217
+ db->rep->GetApproximateSizes(ranges, num_ranges, sizes);
218
+ delete[] ranges;
219
+ }
220
+
221
+ void leveldb_destroy_db(
222
+ const leveldb_options_t* options,
223
+ const char* name,
224
+ char** errptr) {
225
+ SaveError(errptr, DestroyDB(name, options->rep));
226
+ }
227
+
228
+ void leveldb_repair_db(
229
+ const leveldb_options_t* options,
230
+ const char* name,
231
+ char** errptr) {
232
+ SaveError(errptr, RepairDB(name, options->rep));
233
+ }
234
+
235
+ void leveldb_iter_destroy(leveldb_iterator_t* iter) {
236
+ delete iter->rep;
237
+ delete iter;
238
+ }
239
+
240
+ unsigned char leveldb_iter_valid(const leveldb_iterator_t* iter) {
241
+ return iter->rep->Valid();
242
+ }
243
+
244
+ void leveldb_iter_seek_to_first(leveldb_iterator_t* iter) {
245
+ iter->rep->SeekToFirst();
246
+ }
247
+
248
+ void leveldb_iter_seek_to_last(leveldb_iterator_t* iter) {
249
+ iter->rep->SeekToLast();
250
+ }
251
+
252
+ void leveldb_iter_seek(leveldb_iterator_t* iter, const char* k, size_t klen) {
253
+ iter->rep->Seek(Slice(k, klen));
254
+ }
255
+
256
+ void leveldb_iter_next(leveldb_iterator_t* iter) {
257
+ iter->rep->Next();
258
+ }
259
+
260
+ void leveldb_iter_prev(leveldb_iterator_t* iter) {
261
+ iter->rep->Prev();
262
+ }
263
+
264
+ const char* leveldb_iter_key(const leveldb_iterator_t* iter, size_t* klen) {
265
+ Slice s = iter->rep->key();
266
+ *klen = s.size();
267
+ return s.data();
268
+ }
269
+
270
+ const char* leveldb_iter_value(const leveldb_iterator_t* iter, size_t* vlen) {
271
+ Slice s = iter->rep->value();
272
+ *vlen = s.size();
273
+ return s.data();
274
+ }
275
+
276
+ void leveldb_iter_get_error(const leveldb_iterator_t* iter, char** errptr) {
277
+ SaveError(errptr, iter->rep->status());
278
+ }
279
+
280
+ leveldb_writebatch_t* leveldb_writebatch_create() {
281
+ return new leveldb_writebatch_t;
282
+ }
283
+
284
+ void leveldb_writebatch_destroy(leveldb_writebatch_t* b) {
285
+ delete b;
286
+ }
287
+
288
+ void leveldb_writebatch_clear(leveldb_writebatch_t* b) {
289
+ b->rep.Clear();
290
+ }
291
+
292
+ void leveldb_writebatch_put(
293
+ leveldb_writebatch_t* b,
294
+ const char* key, size_t klen,
295
+ const char* val, size_t vlen) {
296
+ b->rep.Put(Slice(key, klen), Slice(val, vlen));
297
+ }
298
+
299
+ void leveldb_writebatch_delete(
300
+ leveldb_writebatch_t* b,
301
+ const char* key, size_t klen) {
302
+ b->rep.Delete(Slice(key, klen));
303
+ }
304
+
305
+ void leveldb_writebatch_iterate(
306
+ leveldb_writebatch_t* b,
307
+ void* state,
308
+ void (*put)(void*, const char* k, size_t klen, const char* v, size_t vlen),
309
+ void (*deleted)(void*, const char* k, size_t klen)) {
310
+ class H : public WriteBatch::Handler {
311
+ public:
312
+ void* state_;
313
+ void (*put_)(void*, const char* k, size_t klen, const char* v, size_t vlen);
314
+ void (*deleted_)(void*, const char* k, size_t klen);
315
+ virtual void Put(const Slice& key, const Slice& value) {
316
+ (*put_)(state_, key.data(), key.size(), value.data(), value.size());
317
+ }
318
+ virtual void Delete(const Slice& key) {
319
+ (*deleted_)(state_, key.data(), key.size());
320
+ }
321
+ };
322
+ H handler;
323
+ handler.state_ = state;
324
+ handler.put_ = put;
325
+ handler.deleted_ = deleted;
326
+ b->rep.Iterate(&handler);
327
+ }
328
+
329
+ leveldb_options_t* leveldb_options_create() {
330
+ return new leveldb_options_t;
331
+ }
332
+
333
+ void leveldb_options_destroy(leveldb_options_t* options) {
334
+ delete options;
335
+ }
336
+
337
+ void leveldb_options_set_comparator(
338
+ leveldb_options_t* opt,
339
+ leveldb_comparator_t* cmp) {
340
+ opt->rep.comparator = cmp;
341
+ }
342
+
343
+ void leveldb_options_set_create_if_missing(
344
+ leveldb_options_t* opt, unsigned char v) {
345
+ opt->rep.create_if_missing = v;
346
+ }
347
+
348
+ void leveldb_options_set_error_if_exists(
349
+ leveldb_options_t* opt, unsigned char v) {
350
+ opt->rep.error_if_exists = v;
351
+ }
352
+
353
+ void leveldb_options_set_paranoid_checks(
354
+ leveldb_options_t* opt, unsigned char v) {
355
+ opt->rep.paranoid_checks = v;
356
+ }
357
+
358
+ void leveldb_options_set_env(leveldb_options_t* opt, leveldb_env_t* env) {
359
+ opt->rep.env = (env ? env->rep : NULL);
360
+ }
361
+
362
+ void leveldb_options_set_info_log(leveldb_options_t* opt, leveldb_logger_t* l) {
363
+ opt->rep.info_log = (l ? l->rep : NULL);
364
+ }
365
+
366
+ void leveldb_options_set_write_buffer_size(leveldb_options_t* opt, size_t s) {
367
+ opt->rep.write_buffer_size = s;
368
+ }
369
+
370
+ void leveldb_options_set_max_open_files(leveldb_options_t* opt, int n) {
371
+ opt->rep.max_open_files = n;
372
+ }
373
+
374
+ void leveldb_options_set_cache(leveldb_options_t* opt, leveldb_cache_t* c) {
375
+ opt->rep.block_cache = c->rep;
376
+ }
377
+
378
+ void leveldb_options_set_block_size(leveldb_options_t* opt, size_t s) {
379
+ opt->rep.block_size = s;
380
+ }
381
+
382
+ void leveldb_options_set_block_restart_interval(leveldb_options_t* opt, int n) {
383
+ opt->rep.block_restart_interval = n;
384
+ }
385
+
386
+ void leveldb_options_set_compression(leveldb_options_t* opt, int t) {
387
+ opt->rep.compression = static_cast<CompressionType>(t);
388
+ }
389
+
390
+ leveldb_comparator_t* leveldb_comparator_create(
391
+ void* state,
392
+ void (*destructor)(void*),
393
+ int (*compare)(
394
+ void*,
395
+ const char* a, size_t alen,
396
+ const char* b, size_t blen),
397
+ const char* (*name)(void*)) {
398
+ leveldb_comparator_t* result = new leveldb_comparator_t;
399
+ result->state_ = state;
400
+ result->destructor_ = destructor;
401
+ result->compare_ = compare;
402
+ result->name_ = name;
403
+ return result;
404
+ }
405
+
406
+ void leveldb_comparator_destroy(leveldb_comparator_t* cmp) {
407
+ delete cmp;
408
+ }
409
+
410
+ leveldb_readoptions_t* leveldb_readoptions_create() {
411
+ return new leveldb_readoptions_t;
412
+ }
413
+
414
+ void leveldb_readoptions_destroy(leveldb_readoptions_t* opt) {
415
+ delete opt;
416
+ }
417
+
418
+ void leveldb_readoptions_set_verify_checksums(
419
+ leveldb_readoptions_t* opt,
420
+ unsigned char v) {
421
+ opt->rep.verify_checksums = v;
422
+ }
423
+
424
+ void leveldb_readoptions_set_fill_cache(
425
+ leveldb_readoptions_t* opt, unsigned char v) {
426
+ opt->rep.fill_cache = v;
427
+ }
428
+
429
+ void leveldb_readoptions_set_snapshot(
430
+ leveldb_readoptions_t* opt,
431
+ const leveldb_snapshot_t* snap) {
432
+ opt->rep.snapshot = (snap ? snap->rep : NULL);
433
+ }
434
+
435
+ leveldb_writeoptions_t* leveldb_writeoptions_create() {
436
+ return new leveldb_writeoptions_t;
437
+ }
438
+
439
+ void leveldb_writeoptions_destroy(leveldb_writeoptions_t* opt) {
440
+ delete opt;
441
+ }
442
+
443
+ void leveldb_writeoptions_set_sync(
444
+ leveldb_writeoptions_t* opt, unsigned char v) {
445
+ opt->rep.sync = v;
446
+ }
447
+
448
+ leveldb_cache_t* leveldb_cache_create_lru(size_t capacity) {
449
+ leveldb_cache_t* c = new leveldb_cache_t;
450
+ c->rep = NewLRUCache(capacity);
451
+ return c;
452
+ }
453
+
454
+ void leveldb_cache_destroy(leveldb_cache_t* cache) {
455
+ delete cache->rep;
456
+ delete cache;
457
+ }
458
+
459
+ leveldb_env_t* leveldb_create_default_env() {
460
+ leveldb_env_t* result = new leveldb_env_t;
461
+ result->rep = Env::Default();
462
+ result->is_default = true;
463
+ return result;
464
+ }
465
+
466
+ void leveldb_env_destroy(leveldb_env_t* env) {
467
+ if (!env->is_default) delete env->rep;
468
+ delete env;
469
+ }
470
+
471
+ } // end extern "C"