leveldb-ruby 0.10 → 0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/ext/leveldb/extconf.rb +2 -6
  2. data/ext/leveldb/leveldb.cc +377 -33
  3. data/ext/leveldb/platform.rb +83 -0
  4. data/leveldb/Makefile +29 -28
  5. data/leveldb/build_detect_platform +23 -4
  6. data/leveldb/db/builder.cc +1 -1
  7. data/leveldb/db/builder.h +1 -1
  8. data/leveldb/db/corruption_test.cc +1 -1
  9. data/leveldb/db/db_bench.cc +2 -2
  10. data/leveldb/db/db_impl.cc +8 -16
  11. data/leveldb/db/db_impl.h +1 -1
  12. data/leveldb/db/db_iter.cc +1 -1
  13. data/leveldb/db/db_iter.h +1 -1
  14. data/leveldb/db/db_test.cc +180 -9
  15. data/leveldb/db/dbformat.cc +9 -7
  16. data/leveldb/db/dbformat.h +2 -2
  17. data/leveldb/db/dbformat_test.cc +1 -1
  18. data/leveldb/db/filename.cc +6 -2
  19. data/leveldb/db/filename.h +1 -1
  20. data/leveldb/db/filename_test.cc +1 -1
  21. data/leveldb/db/log_format.h +2 -2
  22. data/leveldb/db/log_reader.cc +2 -2
  23. data/leveldb/db/log_reader.h +2 -2
  24. data/leveldb/db/log_test.cc +2 -2
  25. data/leveldb/db/log_writer.cc +2 -2
  26. data/leveldb/db/log_writer.h +2 -2
  27. data/leveldb/db/memtable.cc +1 -1
  28. data/leveldb/db/memtable.h +1 -1
  29. data/leveldb/db/repair.cc +2 -2
  30. data/leveldb/db/skiplist.h +1 -1
  31. data/leveldb/db/skiplist_test.cc +1 -1
  32. data/leveldb/db/snapshot.h +1 -1
  33. data/leveldb/db/table_cache.cc +1 -1
  34. data/leveldb/db/table_cache.h +1 -1
  35. data/leveldb/db/version_edit.cc +1 -1
  36. data/leveldb/db/version_edit.h +1 -1
  37. data/leveldb/db/version_edit_test.cc +1 -1
  38. data/leveldb/db/version_set.cc +39 -14
  39. data/leveldb/db/version_set.h +1 -1
  40. data/leveldb/db/version_set_test.cc +1 -1
  41. data/leveldb/db/write_batch.cc +2 -2
  42. data/leveldb/db/write_batch_internal.h +1 -1
  43. data/leveldb/db/write_batch_test.cc +1 -1
  44. data/leveldb/helpers/memenv/memenv.cc +374 -0
  45. data/leveldb/helpers/memenv/memenv.h +20 -0
  46. data/leveldb/helpers/memenv/memenv_test.cc +232 -0
  47. data/leveldb/include/leveldb/cache.h +1 -1
  48. data/leveldb/include/leveldb/comparator.h +1 -1
  49. data/leveldb/include/leveldb/db.h +1 -1
  50. data/leveldb/include/leveldb/env.h +1 -1
  51. data/leveldb/include/leveldb/iterator.h +1 -1
  52. data/leveldb/include/leveldb/options.h +1 -1
  53. data/leveldb/include/leveldb/slice.h +1 -1
  54. data/leveldb/include/leveldb/status.h +1 -1
  55. data/leveldb/include/leveldb/table.h +1 -1
  56. data/leveldb/include/leveldb/table_builder.h +1 -1
  57. data/leveldb/include/leveldb/write_batch.h +1 -1
  58. data/leveldb/port/atomic_pointer.h +2 -2
  59. data/leveldb/port/port_android.cc +2 -2
  60. data/leveldb/port/port_android.h +2 -2
  61. data/leveldb/port/port_example.h +2 -2
  62. data/leveldb/port/port_posix.cc +2 -2
  63. data/leveldb/port/port_posix.h +11 -3
  64. data/leveldb/table/block.cc +1 -1
  65. data/leveldb/table/block.h +1 -1
  66. data/leveldb/table/block_builder.cc +1 -1
  67. data/leveldb/table/block_builder.h +1 -1
  68. data/leveldb/table/format.cc +1 -1
  69. data/leveldb/table/format.h +1 -1
  70. data/leveldb/table/iterator.cc +2 -2
  71. data/leveldb/table/merger.cc +2 -2
  72. data/leveldb/table/merger.h +1 -1
  73. data/leveldb/table/table.cc +1 -1
  74. data/leveldb/table/table_builder.cc +1 -1
  75. data/leveldb/table/table_test.cc +3 -3
  76. data/leveldb/table/two_level_iterator.cc +2 -2
  77. data/leveldb/table/two_level_iterator.h +1 -1
  78. data/leveldb/util/arena.cc +1 -1
  79. data/leveldb/util/arena.h +1 -1
  80. data/leveldb/util/arena_test.cc +1 -1
  81. data/leveldb/util/cache.cc +1 -1
  82. data/leveldb/util/cache_test.cc +1 -1
  83. data/leveldb/util/coding.cc +1 -1
  84. data/leveldb/util/coding.h +1 -1
  85. data/leveldb/util/coding_test.cc +1 -1
  86. data/leveldb/util/comparator.cc +7 -4
  87. data/leveldb/util/crc32c.cc +2 -2
  88. data/leveldb/util/crc32c.h +2 -2
  89. data/leveldb/util/crc32c_test.cc +2 -2
  90. data/leveldb/util/env.cc +17 -3
  91. data/leveldb/util/env_posix.cc +2 -2
  92. data/leveldb/util/env_test.cc +13 -11
  93. data/leveldb/util/hash.cc +1 -1
  94. data/leveldb/util/histogram.cc +1 -1
  95. data/leveldb/util/histogram.h +1 -1
  96. data/leveldb/util/logging.cc +1 -1
  97. data/leveldb/util/logging.h +1 -1
  98. data/leveldb/util/mutexlock.h +1 -1
  99. data/leveldb/util/options.cc +1 -1
  100. data/leveldb/util/posix_logger.h +1 -1
  101. data/leveldb/util/random.h +1 -1
  102. data/leveldb/util/status.cc +1 -1
  103. data/leveldb/util/testharness.cc +2 -2
  104. data/leveldb/util/testharness.h +2 -2
  105. data/leveldb/util/testutil.cc +2 -2
  106. data/leveldb/util/testutil.h +2 -2
  107. data/lib/leveldb.rb +34 -2
  108. metadata +7 -13
  109. data/leveldb/port/port_chromium.cc +0 -80
  110. data/leveldb/port/port_chromium.h +0 -97
  111. data/leveldb/port/port_osx.cc +0 -50
  112. data/leveldb/port/port_osx.h +0 -125
  113. data/leveldb/port/sha1_portable.cc +0 -298
  114. data/leveldb/port/sha1_portable.h +0 -25
  115. data/leveldb/port/sha1_test.cc +0 -39
  116. 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
+
@@ -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
- CC = g++
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 = -O2 -DNDEBUG -fPIC # (A) Production use (optimized mode)
12
- # OPT = -g2 # (B) Debug mode, w/ full line-level debugging symbols
13
- # OPT = -O2 -g2 -DNDEBUG # (C) Profiling mode: opt, but w/debugging symbols
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=$(PLATFORM_LDFLAGS) $(SNAPPY_LDFLAGS) $(GOOGLE_PERFTOOLS_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
- $(CC) $(LDFLAGS) db/db_bench.o $(LIBOBJECTS) $(TESTUTIL) -o $@
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
- $(CC) $(LDFLAGS) -lsqlite3 doc/bench/db_bench_sqlite3.o $(LIBOBJECTS) $(TESTUTIL) -o $@
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
- $(CC) $(LDFLAGS) -lkyotocabinet doc/bench/db_bench_tree_db.o $(LIBOBJECTS) $(TESTUTIL) -o $@
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
- $(CC) $(LDFLAGS) util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
133
+ $(CXX) $(LDFLAGS) util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
133
134
 
134
135
  c_test: db/c_test.o $(LIBOBJECTS) $(TESTHARNESS)
135
- $(CC) $(LDFLAGS) db/c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
136
+ $(CXX) $(LDFLAGS) db/c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
136
137
 
137
138
  cache_test: util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS)
138
- $(CC) $(LDFLAGS) util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
139
+ $(CXX) $(LDFLAGS) util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
139
140
 
140
141
  coding_test: util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS)
141
- $(CC) $(LDFLAGS) util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
142
+ $(CXX) $(LDFLAGS) util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
142
143
 
143
144
  corruption_test: db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS)
144
- $(CC) $(LDFLAGS) db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
145
+ $(CXX) $(LDFLAGS) db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
145
146
 
146
147
  crc32c_test: util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS)
147
- $(CC) $(LDFLAGS) util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
148
+ $(CXX) $(LDFLAGS) util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
148
149
 
149
150
  db_test: db/db_test.o $(LIBOBJECTS) $(TESTHARNESS)
150
- $(CC) $(LDFLAGS) db/db_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
151
+ $(CXX) $(LDFLAGS) db/db_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
151
152
 
152
153
  dbformat_test: db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS)
153
- $(CC) $(LDFLAGS) db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
154
+ $(CXX) $(LDFLAGS) db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
154
155
 
155
156
  env_test: util/env_test.o $(LIBOBJECTS) $(TESTHARNESS)
156
- $(CC) $(LDFLAGS) util/env_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
157
+ $(CXX) $(LDFLAGS) util/env_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
157
158
 
158
159
  filename_test: db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS)
159
- $(CC) $(LDFLAGS) db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
160
+ $(CXX) $(LDFLAGS) db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
160
161
 
161
162
  log_test: db/log_test.o $(LIBOBJECTS) $(TESTHARNESS)
162
- $(CC) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
163
+ $(CXX) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
163
164
 
164
165
  table_test: table/table_test.o $(LIBOBJECTS) $(TESTHARNESS)
165
- $(CC) $(LDFLAGS) table/table_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
166
+ $(CXX) $(LDFLAGS) table/table_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
166
167
 
167
168
  skiplist_test: db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS)
168
- $(CC) $(LDFLAGS) db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
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
- $(CC) $(LDFLAGS) db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
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
- $(CC) $(LDFLAGS) db/version_set_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
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
- $(CC) $(LDFLAGS) db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
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
- $(CC) $(LDFLAGS) helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS) -o $@
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/$(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 $< -o ios-x86/$@
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/$(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 $< -o ios-arm/$@
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
- $(CC) $(CFLAGS) $< -o $@
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=-lpthread" >> build_config.mk
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 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
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
- g++ $CFLAGS -x c++ - -o /dev/null 2>/dev/null <<EOF
83
+ $CXX $CFLAGS -x c++ - -o /dev/null 2>/dev/null <<EOF
65
84
  #include <snappy.h>
66
85
  int main() {}
67
86
  EOF
@@ -85,4 +85,4 @@ Status BuildTable(const std::string& dbname,
85
85
  return s;
86
86
  }
87
87
 
88
- }
88
+ } // namespace leveldb
@@ -29,6 +29,6 @@ extern Status BuildTable(const std::string& dbname,
29
29
  Iterator* iter,
30
30
  FileMetaData* meta);
31
31
 
32
- }
32
+ } // namespace leveldb
33
33
 
34
34
  #endif // STORAGE_LEVELDB_DB_BUILDER_H_
@@ -352,7 +352,7 @@ TEST(CorruptionTest, UnrelatedKeys) {
352
352
  ASSERT_EQ(Value(1000, &tmp2).ToString(), v);
353
353
  }
354
354
 
355
- }
355
+ } // namespace leveldb
356
356
 
357
357
  int main(int argc, char** argv) {
358
358
  return leveldb::test::RunAllTests();
@@ -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;
@@ -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->outputs.clear();
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
@@ -187,6 +187,6 @@ extern Options SanitizeOptions(const std::string& db,
187
187
  const InternalKeyComparator* icmp,
188
188
  const Options& src);
189
189
 
190
- }
190
+ } // namespace leveldb
191
191
 
192
192
  #endif // STORAGE_LEVELDB_DB_DB_IMPL_H_
@@ -296,4 +296,4 @@ Iterator* NewDBIterator(
296
296
  return new DBIter(dbname, env, user_key_comparator, internal_iter, sequence);
297
297
  }
298
298
 
299
- }
299
+ } // namespace leveldb
@@ -21,6 +21,6 @@ extern Iterator* NewDBIterator(
21
21
  Iterator* internal_iter,
22
22
  const SequenceNumber& sequence);
23
23
 
24
- }
24
+ } // namespace leveldb
25
25
 
26
26
  #endif // STORAGE_LEVELDB_DB_DB_ITER_H_
@@ -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) { return base_->Append(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", t->id);
1171
- Random rnd(1000 + t->id);
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[t->id].Release_Store(reinterpret_cast<void*>(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, t->id, static_cast<int>(counter));
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[t->id].Release_Store(t);
1207
- fprintf(stderr, "... stopping thread %d after %d ops\n", t->id, int(counter));
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") {