leveldb-ruby 0.10 → 0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/leveldb/extconf.rb +2 -6
- data/ext/leveldb/leveldb.cc +377 -33
- data/ext/leveldb/platform.rb +83 -0
- data/leveldb/Makefile +29 -28
- data/leveldb/build_detect_platform +23 -4
- data/leveldb/db/builder.cc +1 -1
- data/leveldb/db/builder.h +1 -1
- data/leveldb/db/corruption_test.cc +1 -1
- data/leveldb/db/db_bench.cc +2 -2
- data/leveldb/db/db_impl.cc +8 -16
- data/leveldb/db/db_impl.h +1 -1
- data/leveldb/db/db_iter.cc +1 -1
- data/leveldb/db/db_iter.h +1 -1
- data/leveldb/db/db_test.cc +180 -9
- data/leveldb/db/dbformat.cc +9 -7
- data/leveldb/db/dbformat.h +2 -2
- data/leveldb/db/dbformat_test.cc +1 -1
- data/leveldb/db/filename.cc +6 -2
- data/leveldb/db/filename.h +1 -1
- data/leveldb/db/filename_test.cc +1 -1
- data/leveldb/db/log_format.h +2 -2
- data/leveldb/db/log_reader.cc +2 -2
- data/leveldb/db/log_reader.h +2 -2
- data/leveldb/db/log_test.cc +2 -2
- data/leveldb/db/log_writer.cc +2 -2
- data/leveldb/db/log_writer.h +2 -2
- data/leveldb/db/memtable.cc +1 -1
- data/leveldb/db/memtable.h +1 -1
- data/leveldb/db/repair.cc +2 -2
- data/leveldb/db/skiplist.h +1 -1
- data/leveldb/db/skiplist_test.cc +1 -1
- data/leveldb/db/snapshot.h +1 -1
- data/leveldb/db/table_cache.cc +1 -1
- data/leveldb/db/table_cache.h +1 -1
- data/leveldb/db/version_edit.cc +1 -1
- data/leveldb/db/version_edit.h +1 -1
- data/leveldb/db/version_edit_test.cc +1 -1
- data/leveldb/db/version_set.cc +39 -14
- data/leveldb/db/version_set.h +1 -1
- data/leveldb/db/version_set_test.cc +1 -1
- data/leveldb/db/write_batch.cc +2 -2
- data/leveldb/db/write_batch_internal.h +1 -1
- data/leveldb/db/write_batch_test.cc +1 -1
- data/leveldb/helpers/memenv/memenv.cc +374 -0
- data/leveldb/helpers/memenv/memenv.h +20 -0
- data/leveldb/helpers/memenv/memenv_test.cc +232 -0
- data/leveldb/include/leveldb/cache.h +1 -1
- data/leveldb/include/leveldb/comparator.h +1 -1
- data/leveldb/include/leveldb/db.h +1 -1
- data/leveldb/include/leveldb/env.h +1 -1
- data/leveldb/include/leveldb/iterator.h +1 -1
- data/leveldb/include/leveldb/options.h +1 -1
- data/leveldb/include/leveldb/slice.h +1 -1
- data/leveldb/include/leveldb/status.h +1 -1
- data/leveldb/include/leveldb/table.h +1 -1
- data/leveldb/include/leveldb/table_builder.h +1 -1
- data/leveldb/include/leveldb/write_batch.h +1 -1
- data/leveldb/port/atomic_pointer.h +2 -2
- data/leveldb/port/port_android.cc +2 -2
- data/leveldb/port/port_android.h +2 -2
- data/leveldb/port/port_example.h +2 -2
- data/leveldb/port/port_posix.cc +2 -2
- data/leveldb/port/port_posix.h +11 -3
- data/leveldb/table/block.cc +1 -1
- data/leveldb/table/block.h +1 -1
- data/leveldb/table/block_builder.cc +1 -1
- data/leveldb/table/block_builder.h +1 -1
- data/leveldb/table/format.cc +1 -1
- data/leveldb/table/format.h +1 -1
- data/leveldb/table/iterator.cc +2 -2
- data/leveldb/table/merger.cc +2 -2
- data/leveldb/table/merger.h +1 -1
- data/leveldb/table/table.cc +1 -1
- data/leveldb/table/table_builder.cc +1 -1
- data/leveldb/table/table_test.cc +3 -3
- data/leveldb/table/two_level_iterator.cc +2 -2
- data/leveldb/table/two_level_iterator.h +1 -1
- data/leveldb/util/arena.cc +1 -1
- data/leveldb/util/arena.h +1 -1
- data/leveldb/util/arena_test.cc +1 -1
- data/leveldb/util/cache.cc +1 -1
- data/leveldb/util/cache_test.cc +1 -1
- data/leveldb/util/coding.cc +1 -1
- data/leveldb/util/coding.h +1 -1
- data/leveldb/util/coding_test.cc +1 -1
- data/leveldb/util/comparator.cc +7 -4
- data/leveldb/util/crc32c.cc +2 -2
- data/leveldb/util/crc32c.h +2 -2
- data/leveldb/util/crc32c_test.cc +2 -2
- data/leveldb/util/env.cc +17 -3
- data/leveldb/util/env_posix.cc +2 -2
- data/leveldb/util/env_test.cc +13 -11
- data/leveldb/util/hash.cc +1 -1
- data/leveldb/util/histogram.cc +1 -1
- data/leveldb/util/histogram.h +1 -1
- data/leveldb/util/logging.cc +1 -1
- data/leveldb/util/logging.h +1 -1
- data/leveldb/util/mutexlock.h +1 -1
- data/leveldb/util/options.cc +1 -1
- data/leveldb/util/posix_logger.h +1 -1
- data/leveldb/util/random.h +1 -1
- data/leveldb/util/status.cc +1 -1
- data/leveldb/util/testharness.cc +2 -2
- data/leveldb/util/testharness.h +2 -2
- data/leveldb/util/testutil.cc +2 -2
- data/leveldb/util/testutil.h +2 -2
- data/lib/leveldb.rb +34 -2
- metadata +7 -13
- data/leveldb/port/port_chromium.cc +0 -80
- data/leveldb/port/port_chromium.h +0 -97
- data/leveldb/port/port_osx.cc +0 -50
- data/leveldb/port/port_osx.h +0 -125
- data/leveldb/port/sha1_portable.cc +0 -298
- data/leveldb/port/sha1_portable.h +0 -25
- data/leveldb/port/sha1_test.cc +0 -39
- data/leveldb/util/env_chromium.cc +0 -612
@@ -0,0 +1,83 @@
|
|
1
|
+
## here lies some platform-specific C++ compile and link environment
|
2
|
+
## variable hacking.
|
3
|
+
##
|
4
|
+
## this code is entirely stolen from eventmachine's extconf.rb. many
|
5
|
+
## thanks to @tmm1 for the pointer.
|
6
|
+
|
7
|
+
def check_libs libs=[], fatal=false
|
8
|
+
libs.all? { |lib| have_library(lib) || (abort("could not find library: #{lib}") if fatal) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def check_heads heads=[], fatal=false
|
12
|
+
heads.all? { |head| have_header(head) || (abort("could not find header: #{head}") if fatal)}
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_define name; $defs.push "-D#{name}" end
|
16
|
+
|
17
|
+
def set_platform_specific_variables!
|
18
|
+
puts "setting build environment for #{RUBY_PLATFORM}..."
|
19
|
+
case RUBY_PLATFORM
|
20
|
+
when /mswin32/, /mingw32/, /bccwin32/
|
21
|
+
check_heads(%w[windows.h winsock.h], true)
|
22
|
+
check_libs(%w[kernel32 rpcrt4 gdi32], true)
|
23
|
+
|
24
|
+
if GNU_CHAIN
|
25
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++"
|
26
|
+
else
|
27
|
+
$defs.push "-EHs"
|
28
|
+
$defs.push "-GR"
|
29
|
+
end
|
30
|
+
|
31
|
+
when /solaris/
|
32
|
+
add_define 'OS_SOLARIS8'
|
33
|
+
check_libs(%w[nsl socket], true)
|
34
|
+
|
35
|
+
if CONFIG['CC'] == 'cc' and `cc -flags 2>&1` =~ /Sun/ # detect SUNWspro compiler
|
36
|
+
# SUN CHAIN
|
37
|
+
add_define 'CC_SUNWspro'
|
38
|
+
$preload = ["\nCXX = CC"] # hack a CXX= line into the makefile
|
39
|
+
$CFLAGS = CONFIG['CFLAGS'] = "-KPIC"
|
40
|
+
CONFIG['CCDLFLAGS'] = "-KPIC"
|
41
|
+
CONFIG['LDSHARED'] = "$(CXX) -G -KPIC -lCstd"
|
42
|
+
else
|
43
|
+
# GNU CHAIN
|
44
|
+
# on Unix we need a g++ link, not gcc.
|
45
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
46
|
+
end
|
47
|
+
|
48
|
+
when /openbsd/
|
49
|
+
# OpenBSD branch contributed by Guillaume Sellier.
|
50
|
+
|
51
|
+
# on Unix we need a g++ link, not gcc. On OpenBSD, linking against libstdc++ have to be explicitly done for shared libs
|
52
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++ -fPIC"
|
53
|
+
CONFIG['LDSHAREDXX'] = "$(CXX) -shared -lstdc++ -fPIC"
|
54
|
+
|
55
|
+
when /darwin/
|
56
|
+
# on Unix we need a g++ link, not gcc.
|
57
|
+
# Ff line contributed by Daniel Harple.
|
58
|
+
CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
|
59
|
+
|
60
|
+
when /linux/
|
61
|
+
add_define 'HAVE_EPOLL' if have_func('epoll_create', 'sys/epoll.h')
|
62
|
+
|
63
|
+
# on Unix we need a g++ link, not gcc.
|
64
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
65
|
+
|
66
|
+
when /aix/
|
67
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G -Wl,-brtl"
|
68
|
+
|
69
|
+
when /cygwin/
|
70
|
+
# For rubies built with Cygwin, CXX may be set to CC, which is just
|
71
|
+
# a wrapper for gcc.
|
72
|
+
# This will compile, but it will not link to the C++ std library.
|
73
|
+
# Explicitly set CXX to use g++.
|
74
|
+
CONFIG['CXX'] = "g++"
|
75
|
+
# on Unix we need a g++ link, not gcc.
|
76
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
77
|
+
|
78
|
+
else
|
79
|
+
# on Unix we need a g++ link, not gcc.
|
80
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
data/leveldb/Makefile
CHANGED
@@ -2,15 +2,16 @@
|
|
2
2
|
# Use of this source code is governed by a BSD-style license that can be
|
3
3
|
# found in the LICENSE file. See the AUTHORS file for names of contributors.
|
4
4
|
|
5
|
-
|
5
|
+
CXX ?= g++
|
6
|
+
CC ?= gcc
|
6
7
|
|
7
8
|
#-----------------------------------------------
|
8
9
|
# Uncomment exactly one of the lines labelled (A), (B), and (C) below
|
9
10
|
# to switch between compilation modes.
|
10
11
|
|
11
|
-
OPT
|
12
|
-
# OPT
|
13
|
-
# OPT
|
12
|
+
OPT ?= -O2 -DNDEBUG -fPIC # (A) Production use (optimized mode)
|
13
|
+
# OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols
|
14
|
+
# OPT ?= -O2 -g2 -DNDEBUG # (C) Profiling mode: opt, but w/debugging symbols
|
14
15
|
#-----------------------------------------------
|
15
16
|
|
16
17
|
# detect what platform we're building on
|
@@ -38,7 +39,7 @@ endif
|
|
38
39
|
|
39
40
|
CFLAGS = -c -I. -I./include $(PORT_CFLAGS) $(PLATFORM_CFLAGS) $(OPT) $(SNAPPY_CFLAGS)
|
40
41
|
|
41
|
-
LDFLAGS
|
42
|
+
LDFLAGS += $(PLATFORM_LDFLAGS) $(SNAPPY_LDFLAGS) $(GOOGLE_PERFTOOLS_LDFLAGS)
|
42
43
|
|
43
44
|
LIBOBJECTS = \
|
44
45
|
./db/builder.o \
|
@@ -120,68 +121,68 @@ $(LIBRARY): $(LIBOBJECTS)
|
|
120
121
|
$(AR) -rs $@ $(LIBOBJECTS)
|
121
122
|
|
122
123
|
db_bench: db/db_bench.o $(LIBOBJECTS) $(TESTUTIL)
|
123
|
-
$(
|
124
|
+
$(CXX) $(LDFLAGS) db/db_bench.o $(LIBOBJECTS) $(TESTUTIL) -o $@
|
124
125
|
|
125
126
|
db_bench_sqlite3: doc/bench/db_bench_sqlite3.o $(LIBOBJECTS) $(TESTUTIL)
|
126
|
-
$(
|
127
|
+
$(CXX) $(LDFLAGS) -lsqlite3 doc/bench/db_bench_sqlite3.o $(LIBOBJECTS) $(TESTUTIL) -o $@
|
127
128
|
|
128
129
|
db_bench_tree_db: doc/bench/db_bench_tree_db.o $(LIBOBJECTS) $(TESTUTIL)
|
129
|
-
$(
|
130
|
+
$(CXX) $(LDFLAGS) -lkyotocabinet doc/bench/db_bench_tree_db.o $(LIBOBJECTS) $(TESTUTIL) -o $@
|
130
131
|
|
131
132
|
arena_test: util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
132
|
-
$(
|
133
|
+
$(CXX) $(LDFLAGS) util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
133
134
|
|
134
135
|
c_test: db/c_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
135
|
-
$(
|
136
|
+
$(CXX) $(LDFLAGS) db/c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
136
137
|
|
137
138
|
cache_test: util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
138
|
-
$(
|
139
|
+
$(CXX) $(LDFLAGS) util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
139
140
|
|
140
141
|
coding_test: util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
141
|
-
$(
|
142
|
+
$(CXX) $(LDFLAGS) util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
142
143
|
|
143
144
|
corruption_test: db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
144
|
-
$(
|
145
|
+
$(CXX) $(LDFLAGS) db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
145
146
|
|
146
147
|
crc32c_test: util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
147
|
-
$(
|
148
|
+
$(CXX) $(LDFLAGS) util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
148
149
|
|
149
150
|
db_test: db/db_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
150
|
-
$(
|
151
|
+
$(CXX) $(LDFLAGS) db/db_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
151
152
|
|
152
153
|
dbformat_test: db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
153
|
-
$(
|
154
|
+
$(CXX) $(LDFLAGS) db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
154
155
|
|
155
156
|
env_test: util/env_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
156
|
-
$(
|
157
|
+
$(CXX) $(LDFLAGS) util/env_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
157
158
|
|
158
159
|
filename_test: db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
159
|
-
$(
|
160
|
+
$(CXX) $(LDFLAGS) db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
160
161
|
|
161
162
|
log_test: db/log_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
162
|
-
$(
|
163
|
+
$(CXX) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
163
164
|
|
164
165
|
table_test: table/table_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
165
|
-
$(
|
166
|
+
$(CXX) $(LDFLAGS) table/table_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
166
167
|
|
167
168
|
skiplist_test: db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
168
|
-
$(
|
169
|
+
$(CXX) $(LDFLAGS) db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
169
170
|
|
170
171
|
version_edit_test: db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
171
|
-
$(
|
172
|
+
$(CXX) $(LDFLAGS) db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
172
173
|
|
173
174
|
version_set_test: db/version_set_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
174
|
-
$(
|
175
|
+
$(CXX) $(LDFLAGS) db/version_set_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
175
176
|
|
176
177
|
write_batch_test: db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
177
|
-
$(
|
178
|
+
$(CXX) $(LDFLAGS) db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
|
178
179
|
|
179
180
|
$(MEMENVLIBRARY) : helpers/memenv/memenv.o
|
180
181
|
rm -f $@
|
181
182
|
$(AR) -rs $@ helpers/memenv/memenv.o
|
182
183
|
|
183
184
|
memenv_test : helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS)
|
184
|
-
$(
|
185
|
+
$(CXX) $(LDFLAGS) helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS) -o $@
|
185
186
|
|
186
187
|
ifeq ($(PLATFORM), IOS)
|
187
188
|
# For iOS, create universal object files to be used on both the simulator and
|
@@ -192,9 +193,9 @@ IOSVERSION=$(shell defaults read /Developer/Platforms/iPhoneOS.platform/version
|
|
192
193
|
|
193
194
|
.cc.o:
|
194
195
|
mkdir -p ios-x86/$(dir $@)
|
195
|
-
$(SIMULATORROOT)/usr/bin/$(
|
196
|
+
$(SIMULATORROOT)/usr/bin/$(CXX) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 $< -o ios-x86/$@
|
196
197
|
mkdir -p ios-arm/$(dir $@)
|
197
|
-
$(DEVICEROOT)/usr/bin/$(
|
198
|
+
$(DEVICEROOT)/usr/bin/$(CXX) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 $< -o ios-arm/$@
|
198
199
|
lipo ios-x86/$@ ios-arm/$@ -create -output $@
|
199
200
|
|
200
201
|
.c.o:
|
@@ -206,7 +207,7 @@ IOSVERSION=$(shell defaults read /Developer/Platforms/iPhoneOS.platform/version
|
|
206
207
|
|
207
208
|
else
|
208
209
|
.cc.o:
|
209
|
-
$(
|
210
|
+
$(CXX) $(CFLAGS) $< -o $@
|
210
211
|
|
211
212
|
.c.o:
|
212
213
|
$(CC) $(CFLAGS) $< -o $@
|
@@ -13,6 +13,10 @@
|
|
13
13
|
# Delete existing build_config.mk
|
14
14
|
rm -f build_config.mk
|
15
15
|
|
16
|
+
if test -z "$CXX"; then
|
17
|
+
CXX=g++
|
18
|
+
fi
|
19
|
+
|
16
20
|
# Detect OS
|
17
21
|
case `uname -s` in
|
18
22
|
Darwin)
|
@@ -23,7 +27,7 @@ case `uname -s` in
|
|
23
27
|
Linux)
|
24
28
|
PLATFORM=OS_LINUX
|
25
29
|
echo "PLATFORM_CFLAGS=-pthread -DOS_LINUX" >> build_config.mk
|
26
|
-
echo "PLATFORM_LDFLAGS=-
|
30
|
+
echo "PLATFORM_LDFLAGS=-pthread" >> build_config.mk
|
27
31
|
;;
|
28
32
|
SunOS)
|
29
33
|
PLATFORM=OS_SOLARIS
|
@@ -35,6 +39,21 @@ case `uname -s` in
|
|
35
39
|
echo "PLATFORM_CFLAGS=-D_REENTRANT -DOS_FREEBSD" >> build_config.mk
|
36
40
|
echo "PLATFORM_LDFLAGS=-lpthread" >> build_config.mk
|
37
41
|
;;
|
42
|
+
NetBSD)
|
43
|
+
PLATFORM=OS_NETBSD
|
44
|
+
echo "PLATFORM_CFLAGS=-D_REENTRANT -DOS_NETBSD" >> build_config.mk
|
45
|
+
echo "PLATFORM_LDFLAGS=-lpthread -lgcc_s" >> build_config.mk
|
46
|
+
;;
|
47
|
+
OpenBSD)
|
48
|
+
PLATFORM=OS_OPENBSD
|
49
|
+
echo "PLATFORM_CFLAGS=-D_REENTRANT -DOS_OPENBSD" >> build_config.mk
|
50
|
+
echo "PLATFORM_LDFLAGS=-pthread" >> build_config.mk
|
51
|
+
;;
|
52
|
+
DragonFly)
|
53
|
+
PLATFORM=OS_DRAGONFLYBSD
|
54
|
+
echo "PLATFORM_CFLAGS=-D_REENTRANT -DOS_DRAGONFLYBSD" >> build_config.mk
|
55
|
+
echo "PLATFORM_LDFLAGS=-lpthread" >> build_config.mk
|
56
|
+
;;
|
38
57
|
*)
|
39
58
|
echo "Unknown platform!"
|
40
59
|
exit 1
|
@@ -48,8 +67,8 @@ PORT_CFLAGS="-fno-builtin-memcmp"
|
|
48
67
|
# Detect C++0x -- this determines whether we'll use port_noatomic.h
|
49
68
|
# or port_posix.h by:
|
50
69
|
# 1. Rrying to compile with -std=c++0x and including <cstdatomic>.
|
51
|
-
# 2. If
|
52
|
-
|
70
|
+
# 2. If $CXX returns error code, we know to use port_posix.h
|
71
|
+
$CXX $CFLAGS -std=c++0x -x c++ - -o /dev/null 2>/dev/null <<EOF
|
53
72
|
#include <cstdatomic>
|
54
73
|
int main() {}
|
55
74
|
EOF
|
@@ -61,7 +80,7 @@ fi
|
|
61
80
|
|
62
81
|
# Test whether Snappy library is installed
|
63
82
|
# http://code.google.com/p/snappy/
|
64
|
-
|
83
|
+
$CXX $CFLAGS -x c++ - -o /dev/null 2>/dev/null <<EOF
|
65
84
|
#include <snappy.h>
|
66
85
|
int main() {}
|
67
86
|
EOF
|
data/leveldb/db/builder.cc
CHANGED
data/leveldb/db/builder.h
CHANGED
data/leveldb/db/db_bench.cc
CHANGED
@@ -288,7 +288,7 @@ struct ThreadState {
|
|
288
288
|
}
|
289
289
|
};
|
290
290
|
|
291
|
-
}
|
291
|
+
} // namespace
|
292
292
|
|
293
293
|
class Benchmark {
|
294
294
|
private:
|
@@ -829,7 +829,7 @@ class Benchmark {
|
|
829
829
|
}
|
830
830
|
};
|
831
831
|
|
832
|
-
}
|
832
|
+
} // namespace leveldb
|
833
833
|
|
834
834
|
int main(int argc, char** argv) {
|
835
835
|
FLAGS_write_buffer_size = leveldb::Options().write_buffer_size;
|
data/leveldb/db/db_impl.cc
CHANGED
@@ -655,6 +655,8 @@ void DBImpl::BackgroundCompaction() {
|
|
655
655
|
CompactionState* compact = new CompactionState(c);
|
656
656
|
status = DoCompactionWork(compact);
|
657
657
|
CleanupCompaction(compact);
|
658
|
+
c->ReleaseInputs();
|
659
|
+
DeleteObsoleteFiles();
|
658
660
|
}
|
659
661
|
delete c;
|
660
662
|
|
@@ -672,6 +674,9 @@ void DBImpl::BackgroundCompaction() {
|
|
672
674
|
|
673
675
|
if (is_manual) {
|
674
676
|
ManualCompaction* m = manual_compaction_;
|
677
|
+
if (!status.ok()) {
|
678
|
+
m->done = true;
|
679
|
+
}
|
675
680
|
if (!m->done) {
|
676
681
|
// We only compacted part of the requested range. Update *m
|
677
682
|
// to the range that is left to be compacted.
|
@@ -793,21 +798,8 @@ Status DBImpl::InstallCompactionResults(CompactionState* compact) {
|
|
793
798
|
compact->compaction->edit()->AddFile(
|
794
799
|
level + 1,
|
795
800
|
out.number, out.file_size, out.smallest, out.largest);
|
796
|
-
pending_outputs_.erase(out.number);
|
797
801
|
}
|
798
|
-
compact->
|
799
|
-
|
800
|
-
Status s = versions_->LogAndApply(compact->compaction->edit(), &mutex_);
|
801
|
-
if (s.ok()) {
|
802
|
-
compact->compaction->ReleaseInputs();
|
803
|
-
DeleteObsoleteFiles();
|
804
|
-
} else {
|
805
|
-
// Discard any files we may have created during this failed compaction
|
806
|
-
for (size_t i = 0; i < compact->outputs.size(); i++) {
|
807
|
-
env_->DeleteFile(TableFileName(dbname_, compact->outputs[i].number));
|
808
|
-
}
|
809
|
-
}
|
810
|
-
return s;
|
802
|
+
return versions_->LogAndApply(compact->compaction->edit(), &mutex_);
|
811
803
|
}
|
812
804
|
|
813
805
|
Status DBImpl::DoCompactionWork(CompactionState* compact) {
|
@@ -985,7 +977,7 @@ static void CleanupIteratorState(void* arg1, void* arg2) {
|
|
985
977
|
state->mu->Unlock();
|
986
978
|
delete state;
|
987
979
|
}
|
988
|
-
}
|
980
|
+
} // namespace
|
989
981
|
|
990
982
|
Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
|
991
983
|
SequenceNumber* latest_snapshot) {
|
@@ -1378,4 +1370,4 @@ Status DestroyDB(const std::string& dbname, const Options& options) {
|
|
1378
1370
|
return result;
|
1379
1371
|
}
|
1380
1372
|
|
1381
|
-
}
|
1373
|
+
} // namespace leveldb
|
data/leveldb/db/db_impl.h
CHANGED
data/leveldb/db/db_iter.cc
CHANGED
data/leveldb/db/db_iter.h
CHANGED
data/leveldb/db/db_test.cc
CHANGED
@@ -28,8 +28,12 @@ class SpecialEnv : public EnvWrapper {
|
|
28
28
|
// sstable Sync() calls are blocked while this pointer is non-NULL.
|
29
29
|
port::AtomicPointer delay_sstable_sync_;
|
30
30
|
|
31
|
+
// Simulate no-space errors while this pointer is non-NULL.
|
32
|
+
port::AtomicPointer no_space_;
|
33
|
+
|
31
34
|
explicit SpecialEnv(Env* base) : EnvWrapper(base) {
|
32
35
|
delay_sstable_sync_.Release_Store(NULL);
|
36
|
+
no_space_.Release_Store(NULL);
|
33
37
|
}
|
34
38
|
|
35
39
|
Status NewWritableFile(const std::string& f, WritableFile** r) {
|
@@ -44,7 +48,14 @@ class SpecialEnv : public EnvWrapper {
|
|
44
48
|
base_(base) {
|
45
49
|
}
|
46
50
|
~SSTableFile() { delete base_; }
|
47
|
-
Status Append(const Slice& data) {
|
51
|
+
Status Append(const Slice& data) {
|
52
|
+
if (env_->no_space_.Acquire_Load() != NULL) {
|
53
|
+
// Drop writes on the floor
|
54
|
+
return Status::OK();
|
55
|
+
} else {
|
56
|
+
return base_->Append(data);
|
57
|
+
}
|
58
|
+
}
|
48
59
|
Status Close() { return base_->Close(); }
|
49
60
|
Status Flush() { return base_->Flush(); }
|
50
61
|
Status Sync() {
|
@@ -136,6 +147,33 @@ class DBTest {
|
|
136
147
|
return result;
|
137
148
|
}
|
138
149
|
|
150
|
+
// Return a string that contains all key,value pairs in order,
|
151
|
+
// formatted like "(k1->v1)(k2->v2)".
|
152
|
+
std::string Contents() {
|
153
|
+
std::vector<std::string> forward;
|
154
|
+
std::string result;
|
155
|
+
Iterator* iter = db_->NewIterator(ReadOptions());
|
156
|
+
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
157
|
+
std::string s = IterStatus(iter);
|
158
|
+
result.push_back('(');
|
159
|
+
result.append(s);
|
160
|
+
result.push_back(')');
|
161
|
+
forward.push_back(s);
|
162
|
+
}
|
163
|
+
|
164
|
+
// Check reverse iteration results are the reverse of forward results
|
165
|
+
int matched = 0;
|
166
|
+
for (iter->SeekToLast(); iter->Valid(); iter->Prev()) {
|
167
|
+
ASSERT_LT(matched, forward.size());
|
168
|
+
ASSERT_EQ(IterStatus(iter), forward[forward.size() - matched - 1]);
|
169
|
+
matched++;
|
170
|
+
}
|
171
|
+
ASSERT_EQ(matched, forward.size());
|
172
|
+
|
173
|
+
delete iter;
|
174
|
+
return result;
|
175
|
+
}
|
176
|
+
|
139
177
|
std::string AllEntriesFor(const Slice& user_key) {
|
140
178
|
Iterator* iter = dbfull()->TEST_NewInternalIterator();
|
141
179
|
InternalKey target(user_key, kMaxSequenceNumber, kTypeValue);
|
@@ -212,6 +250,12 @@ class DBTest {
|
|
212
250
|
return result;
|
213
251
|
}
|
214
252
|
|
253
|
+
int CountFiles() {
|
254
|
+
std::vector<std::string> files;
|
255
|
+
env_->GetChildren(dbname_, &files);
|
256
|
+
return static_cast<int>(files.size());
|
257
|
+
}
|
258
|
+
|
215
259
|
uint64_t Size(const Slice& start, const Slice& limit) {
|
216
260
|
Range r(start, limit);
|
217
261
|
uint64_t size;
|
@@ -1048,6 +1092,49 @@ TEST(DBTest, OverlapInLevel0) {
|
|
1048
1092
|
ASSERT_EQ("NOT_FOUND", Get("600"));
|
1049
1093
|
}
|
1050
1094
|
|
1095
|
+
TEST(DBTest, L0_CompactionBug_Issue44_a) {
|
1096
|
+
Reopen();
|
1097
|
+
ASSERT_OK(Put("b", "v"));
|
1098
|
+
Reopen();
|
1099
|
+
ASSERT_OK(Delete("b"));
|
1100
|
+
ASSERT_OK(Delete("a"));
|
1101
|
+
Reopen();
|
1102
|
+
ASSERT_OK(Delete("a"));
|
1103
|
+
Reopen();
|
1104
|
+
ASSERT_OK(Put("a", "v"));
|
1105
|
+
Reopen();
|
1106
|
+
Reopen();
|
1107
|
+
ASSERT_EQ("(a->v)", Contents());
|
1108
|
+
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
1109
|
+
ASSERT_EQ("(a->v)", Contents());
|
1110
|
+
}
|
1111
|
+
|
1112
|
+
TEST(DBTest, L0_CompactionBug_Issue44_b) {
|
1113
|
+
Reopen();
|
1114
|
+
Put("","");
|
1115
|
+
Reopen();
|
1116
|
+
Delete("e");
|
1117
|
+
Put("","");
|
1118
|
+
Reopen();
|
1119
|
+
Put("c", "cv");
|
1120
|
+
Reopen();
|
1121
|
+
Put("","");
|
1122
|
+
Reopen();
|
1123
|
+
Put("","");
|
1124
|
+
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
1125
|
+
Reopen();
|
1126
|
+
Put("d","dv");
|
1127
|
+
Reopen();
|
1128
|
+
Put("","");
|
1129
|
+
Reopen();
|
1130
|
+
Delete("d");
|
1131
|
+
Delete("b");
|
1132
|
+
Reopen();
|
1133
|
+
ASSERT_EQ("(->)(c->cv)", Contents());
|
1134
|
+
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
1135
|
+
ASSERT_EQ("(->)(c->cv)", Contents());
|
1136
|
+
}
|
1137
|
+
|
1051
1138
|
TEST(DBTest, ComparatorCheck) {
|
1052
1139
|
class NewComparator : public Comparator {
|
1053
1140
|
public:
|
@@ -1071,6 +1158,58 @@ TEST(DBTest, ComparatorCheck) {
|
|
1071
1158
|
<< s.ToString();
|
1072
1159
|
}
|
1073
1160
|
|
1161
|
+
TEST(DBTest, CustomComparator) {
|
1162
|
+
class NumberComparator : public Comparator {
|
1163
|
+
public:
|
1164
|
+
virtual const char* Name() const { return "test.NumberComparator"; }
|
1165
|
+
virtual int Compare(const Slice& a, const Slice& b) const {
|
1166
|
+
return ToNumber(a) - ToNumber(b);
|
1167
|
+
}
|
1168
|
+
virtual void FindShortestSeparator(std::string* s, const Slice& l) const {
|
1169
|
+
ToNumber(*s); // Check format
|
1170
|
+
ToNumber(l); // Check format
|
1171
|
+
}
|
1172
|
+
virtual void FindShortSuccessor(std::string* key) const {
|
1173
|
+
ToNumber(*key); // Check format
|
1174
|
+
}
|
1175
|
+
private:
|
1176
|
+
static int ToNumber(const Slice& x) {
|
1177
|
+
// Check that there are no extra characters.
|
1178
|
+
ASSERT_TRUE(x.size() >= 2 && x[0] == '[' && x[x.size()-1] == ']')
|
1179
|
+
<< EscapeString(x);
|
1180
|
+
int val;
|
1181
|
+
char ignored;
|
1182
|
+
ASSERT_TRUE(sscanf(x.ToString().c_str(), "[%i]%c", &val, &ignored) == 1)
|
1183
|
+
<< EscapeString(x);
|
1184
|
+
return val;
|
1185
|
+
}
|
1186
|
+
};
|
1187
|
+
NumberComparator cmp;
|
1188
|
+
Options new_options;
|
1189
|
+
new_options.create_if_missing = true;
|
1190
|
+
new_options.comparator = &cmp;
|
1191
|
+
new_options.write_buffer_size = 1000; // Compact more often
|
1192
|
+
DestroyAndReopen(&new_options);
|
1193
|
+
ASSERT_OK(Put("[10]", "ten"));
|
1194
|
+
ASSERT_OK(Put("[0x14]", "twenty"));
|
1195
|
+
for (int i = 0; i < 2; i++) {
|
1196
|
+
ASSERT_EQ("ten", Get("[10]"));
|
1197
|
+
ASSERT_EQ("ten", Get("[0xa]"));
|
1198
|
+
ASSERT_EQ("twenty", Get("[20]"));
|
1199
|
+
ASSERT_EQ("twenty", Get("[0x14]"));
|
1200
|
+
Compact("[0]", "[9999]");
|
1201
|
+
}
|
1202
|
+
|
1203
|
+
for (int run = 0; run < 2; run++) {
|
1204
|
+
for (int i = 0; i < 1000; i++) {
|
1205
|
+
char buf[100];
|
1206
|
+
snprintf(buf, sizeof(buf), "[%d]", i*10);
|
1207
|
+
ASSERT_OK(Put(buf, buf));
|
1208
|
+
}
|
1209
|
+
Compact("[0]", "[1000000]");
|
1210
|
+
}
|
1211
|
+
}
|
1212
|
+
|
1074
1213
|
TEST(DBTest, ManualCompaction) {
|
1075
1214
|
ASSERT_EQ(config::kMaxMemCompactLevel, 2)
|
1076
1215
|
<< "Need to update this test to match kMaxMemCompactLevel";
|
@@ -1144,6 +1283,37 @@ TEST(DBTest, DBOpen_Options) {
|
|
1144
1283
|
db = NULL;
|
1145
1284
|
}
|
1146
1285
|
|
1286
|
+
// Check that number of files does not grow when we are out of space
|
1287
|
+
TEST(DBTest, NoSpace) {
|
1288
|
+
Options options;
|
1289
|
+
options.env = env_;
|
1290
|
+
Reopen(&options);
|
1291
|
+
|
1292
|
+
ASSERT_OK(Put("foo", "v1"));
|
1293
|
+
ASSERT_EQ("v1", Get("foo"));
|
1294
|
+
Compact("a", "z");
|
1295
|
+
const int num_files = CountFiles();
|
1296
|
+
env_->no_space_.Release_Store(env_); // Force out-of-space errors
|
1297
|
+
for (int i = 0; i < 10; i++) {
|
1298
|
+
for (int level = 0; level < config::kNumLevels-1; level++) {
|
1299
|
+
dbfull()->TEST_CompactRange(level, NULL, NULL);
|
1300
|
+
}
|
1301
|
+
}
|
1302
|
+
env_->no_space_.Release_Store(NULL);
|
1303
|
+
ASSERT_LT(CountFiles(), num_files + 5);
|
1304
|
+
}
|
1305
|
+
|
1306
|
+
TEST(DBTest, FilesDeletedAfterCompaction) {
|
1307
|
+
ASSERT_OK(Put("foo", "v2"));
|
1308
|
+
Compact("a", "z");
|
1309
|
+
const int num_files = CountFiles();
|
1310
|
+
for (int i = 0; i < 10; i++) {
|
1311
|
+
ASSERT_OK(Put("foo", "v2"));
|
1312
|
+
Compact("a", "z");
|
1313
|
+
}
|
1314
|
+
ASSERT_EQ(CountFiles(), num_files);
|
1315
|
+
}
|
1316
|
+
|
1147
1317
|
// Multi-threaded test:
|
1148
1318
|
namespace {
|
1149
1319
|
|
@@ -1165,14 +1335,15 @@ struct MTThread {
|
|
1165
1335
|
|
1166
1336
|
static void MTThreadBody(void* arg) {
|
1167
1337
|
MTThread* t = reinterpret_cast<MTThread*>(arg);
|
1338
|
+
int id = t->id;
|
1168
1339
|
DB* db = t->state->test->db_;
|
1169
1340
|
uintptr_t counter = 0;
|
1170
|
-
fprintf(stderr, "... starting thread %d\n",
|
1171
|
-
Random rnd(1000 +
|
1341
|
+
fprintf(stderr, "... starting thread %d\n", id);
|
1342
|
+
Random rnd(1000 + id);
|
1172
1343
|
std::string value;
|
1173
1344
|
char valbuf[1500];
|
1174
1345
|
while (t->state->stop.Acquire_Load() == NULL) {
|
1175
|
-
t->state->counter[
|
1346
|
+
t->state->counter[id].Release_Store(reinterpret_cast<void*>(counter));
|
1176
1347
|
|
1177
1348
|
int key = rnd.Uniform(kNumKeys);
|
1178
1349
|
char keybuf[20];
|
@@ -1182,7 +1353,7 @@ static void MTThreadBody(void* arg) {
|
|
1182
1353
|
// Write values of the form <key, my id, counter>.
|
1183
1354
|
// We add some padding for force compactions.
|
1184
1355
|
snprintf(valbuf, sizeof(valbuf), "%d.%d.%-1000d",
|
1185
|
-
key,
|
1356
|
+
key, id, static_cast<int>(counter));
|
1186
1357
|
ASSERT_OK(db->Put(WriteOptions(), Slice(keybuf), Slice(valbuf)));
|
1187
1358
|
} else {
|
1188
1359
|
// Read a value and verify that it matches the pattern written above.
|
@@ -1203,11 +1374,11 @@ static void MTThreadBody(void* arg) {
|
|
1203
1374
|
}
|
1204
1375
|
counter++;
|
1205
1376
|
}
|
1206
|
-
t->state->thread_done[
|
1207
|
-
fprintf(stderr, "... stopping thread %d after %d ops\n",
|
1377
|
+
t->state->thread_done[id].Release_Store(t);
|
1378
|
+
fprintf(stderr, "... stopping thread %d after %d ops\n", id, int(counter));
|
1208
1379
|
}
|
1209
1380
|
|
1210
|
-
}
|
1381
|
+
} // namespace
|
1211
1382
|
|
1212
1383
|
TEST(DBTest, MultiThreaded) {
|
1213
1384
|
// Initialize state
|
@@ -1525,7 +1696,7 @@ void BM_LogAndApply(int iters, int num_base_files) {
|
|
1525
1696
|
buf, iters, us, ((float)us) / iters);
|
1526
1697
|
}
|
1527
1698
|
|
1528
|
-
}
|
1699
|
+
} // namespace leveldb
|
1529
1700
|
|
1530
1701
|
int main(int argc, char** argv) {
|
1531
1702
|
if (argc > 1 && std::string(argv[1]) == "--benchmark") {
|