leveldb-ruby 0.10 → 0.11
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.
- 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") {
|