leveldb-ruby 0.14 → 0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/LICENSE +24 -0
  2. data/README +60 -16
  3. data/ext/leveldb/extconf.rb +1 -1
  4. data/ext/leveldb/leveldb.cc +187 -18
  5. data/leveldb/Makefile +82 -96
  6. data/leveldb/build_detect_platform +137 -51
  7. data/leveldb/db/c.cc +110 -0
  8. data/leveldb/db/db_bench.cc +105 -4
  9. data/leveldb/db/db_impl.cc +135 -45
  10. data/leveldb/db/db_impl.h +12 -10
  11. data/leveldb/db/db_test.cc +666 -431
  12. data/leveldb/db/dbformat.cc +20 -0
  13. data/leveldb/db/dbformat.h +12 -0
  14. data/leveldb/db/repair.cc +3 -1
  15. data/leveldb/db/skiplist.h +2 -1
  16. data/leveldb/db/table_cache.cc +42 -16
  17. data/leveldb/db/table_cache.h +11 -0
  18. data/leveldb/db/version_set.cc +46 -41
  19. data/leveldb/db/version_set.h +9 -0
  20. data/leveldb/db/write_batch.cc +13 -4
  21. data/leveldb/db/write_batch_internal.h +2 -0
  22. data/leveldb/db/write_batch_test.cc +31 -0
  23. data/leveldb/include/leveldb/c.h +29 -0
  24. data/leveldb/include/leveldb/db.h +2 -1
  25. data/leveldb/include/leveldb/filter_policy.h +70 -0
  26. data/leveldb/include/leveldb/options.h +8 -0
  27. data/leveldb/include/leveldb/status.h +6 -0
  28. data/leveldb/include/leveldb/table.h +15 -0
  29. data/leveldb/include/leveldb/table_builder.h +1 -0
  30. data/leveldb/port/atomic_pointer.h +13 -5
  31. data/leveldb/port/port.h +0 -2
  32. data/leveldb/port/port_example.h +10 -0
  33. data/leveldb/port/port_posix.cc +4 -0
  34. data/leveldb/port/port_posix.h +24 -9
  35. data/leveldb/table/block.cc +8 -4
  36. data/leveldb/table/block.h +3 -2
  37. data/leveldb/table/filter_block.cc +111 -0
  38. data/leveldb/table/filter_block.h +68 -0
  39. data/leveldb/table/filter_block_test.cc +128 -0
  40. data/leveldb/table/format.cc +17 -7
  41. data/leveldb/table/format.h +9 -4
  42. data/leveldb/table/table.cc +107 -6
  43. data/leveldb/table/table_builder.cc +49 -6
  44. data/leveldb/table/table_test.cc +8 -24
  45. data/leveldb/util/bloom.cc +95 -0
  46. data/leveldb/util/bloom_test.cc +159 -0
  47. data/leveldb/util/coding_test.cc +23 -0
  48. data/leveldb/util/comparator.cc +8 -3
  49. data/leveldb/util/env_posix.cc +46 -4
  50. data/leveldb/util/filter_policy.cc +11 -0
  51. data/leveldb/util/options.cc +2 -1
  52. data/lib/leveldb.rb +31 -5
  53. metadata +227 -109
  54. data/leveldb/port/port_android.cc +0 -64
  55. data/leveldb/port/port_android.h +0 -156
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2011--2012 William Morgan.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of the <organization> nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README CHANGED
@@ -1,28 +1,72 @@
1
- LevelDB Ruby bindings.
1
+ LevelDB is a very fast, persistent, in-process key-value store.
2
+ Read more about it here: http://code.google.com/p/leveldb/.
2
3
 
3
- Do this:
4
+ This gem contains Ruby bindings so that you can use it from your
5
+ Ruby process.
4
6
 
5
- gem install leveldb-ruby
7
+ INSTALLATION
6
8
 
9
+ gem install leveldb-ruby
7
10
 
8
- And then run this:
11
+ SYNOPSIS
9
12
 
10
- require 'rubygems' # on ruby < 1.9
13
+ require 'rubygems' # on for ruby 1.8
11
14
  require 'leveldb'
12
15
 
16
+ ## make a new database
13
17
  db = LevelDB::DB.new "/tmp/asdf"
14
- db.put "it", "works"
15
- db.get "it"
16
18
 
17
- Only a very few operations are supported right now:
19
+ ## getting and setting
20
+ db.put "it", "works" # => "works"
21
+ db.get "it" # => "works"
22
+
23
+ db["hello"] = "there" # => "there"
24
+ db["hello"] # => "there"
25
+
26
+ db["nonexistent"] # => nil
27
+
28
+ ## testing
29
+ db.includes? "hello" # => true
30
+ db.contains? "hello" # => true
31
+
32
+ ## keys and values
33
+ db.keys # => "it", "hello"
34
+ db.values # => "there", "works"
35
+
36
+ ## iterating
37
+ db.each { |k, v| ... }
38
+ db.map { |k, v| ... }
39
+ db.each # => LevelDB::Iterator
40
+
41
+ ## ranges
42
+ db.each(:from => "a", :to => "b") # => LevelDB::Iterator
43
+ db.each(:from => "a", :to => "b").
44
+ map { |k, v| ... }
45
+ # etc...
46
+
47
+ ## deleting
48
+ db.delete "hello" # => "there"
49
+ db.delete "hello" # => nil
50
+
51
+ LICENSE
52
+
53
+ Leveldb-ruby is available for your use under the terms of
54
+ the New BSD License. See the LICENSE file for details.
55
+
56
+ CREDIT
57
+
58
+ This gem brought to you by William Morgan <http://masanjin.net/>
59
+ and the following honorable contributors:
60
+ - Rick Olson
61
+ - byplayer
62
+ - Yukio Goto
63
+ - Johannes Holzfuß
64
+ - Steve Wilhelm
65
+ - Gabriel Ebner
66
+ and by users like you.
67
+
68
+ BUGS
18
69
 
19
- DB.new # creates or loads as necessary
20
- DB.create # dies if it already exists
21
- DB.load # dies unless it alread exists
70
+ Please report bugs to https://github.com/wmorgan/leveldb-ruby/issues.
22
71
 
23
- DB#get # alias: DB#[]
24
- DB#put # alias: DB#[]=
25
- DB#delete
26
72
 
27
- DB#each
28
- ... and all the enumerable methods
@@ -3,7 +3,7 @@ require 'fileutils'
3
3
  require "./platform.rb"
4
4
 
5
5
  Dir.chdir "../../leveldb"
6
- system "make libleveldb.a" or abort
6
+ system "OPT=\"-O2 -DNDEBUG -fPIC\" make libleveldb.a" or abort
7
7
  Dir.chdir "../ext/leveldb"
8
8
 
9
9
  set_platform_specific_variables!
@@ -1,14 +1,20 @@
1
1
  #include <ruby.h>
2
+ #include <memory>
2
3
 
3
4
  #include "leveldb/db.h"
5
+ #include "leveldb/cache.h"
4
6
  #include "leveldb/slice.h"
5
7
  #include "leveldb/write_batch.h"
6
8
 
9
+ using namespace std;
10
+
7
11
  static VALUE m_leveldb;
8
12
  static VALUE c_db;
9
13
  static VALUE c_iter;
10
14
  static VALUE c_batch;
11
15
  static VALUE c_error;
16
+ static VALUE c_no_compression;
17
+ static VALUE c_snappy_compression;
12
18
  static VALUE k_fill;
13
19
  static VALUE k_verify;
14
20
  static VALUE k_sync;
@@ -17,9 +23,20 @@ static VALUE k_to;
17
23
  static VALUE k_reversed;
18
24
  static VALUE k_class;
19
25
  static VALUE k_name;
20
- static ID to_s;
26
+ static ID k_to_s;
21
27
  static leveldb::ReadOptions uncached_read_options;
22
28
 
29
+ static VALUE c_db_options;
30
+ static VALUE k_create_if_missing;
31
+ static VALUE k_error_if_exists;
32
+ static VALUE k_paranoid_checks;
33
+ static VALUE k_write_buffer_size;
34
+ static VALUE k_block_cache_size;
35
+ static VALUE k_block_size;
36
+ static VALUE k_block_restart_interval;
37
+ static VALUE k_compression;
38
+ static VALUE k_max_open_files;
39
+
23
40
  // support 1.9 and 1.8
24
41
  #ifndef RSTRING_PTR
25
42
  #define RSTRING_PTR(v) RSTRING(v)->ptr
@@ -45,21 +62,154 @@ static void db_free(bound_db* db) {
45
62
  delete db;
46
63
  }
47
64
 
48
- static VALUE db_make(VALUE klass, VALUE v_pathname, VALUE v_create_if_necessary, VALUE v_break_if_exists) {
65
+ static void sync_vals(VALUE opts, VALUE key, VALUE db_options, bool* pOptionVal) {
66
+ VALUE v = rb_hash_aref(opts, key);
67
+
68
+ if(!NIL_P(v)) *pOptionVal = RTEST(v);
69
+ string param("@");
70
+ param += rb_id2name(SYM2ID(key));
71
+ rb_iv_set(db_options, param.c_str(), *pOptionVal ? Qtrue : Qfalse);
72
+ }
73
+
74
+ static void sync_vals(VALUE opts, VALUE key, VALUE db_options, size_t* pOptionVal) {
75
+ VALUE v = rb_hash_aref(opts, key);
76
+
77
+ if(!NIL_P(v)) *pOptionVal = NUM2UINT(v);
78
+ string param("@");
79
+ param += rb_id2name(SYM2ID(key));
80
+ rb_iv_set(db_options, param.c_str(), UINT2NUM(*pOptionVal));
81
+ }
82
+
83
+ static void sync_vals(VALUE opts, VALUE key, VALUE db_options, int* pOptionVal) {
84
+ VALUE v = rb_hash_aref(opts, key);
85
+
86
+ if(!NIL_P(v)) *pOptionVal = NUM2INT(v);
87
+ string param("@");
88
+ param += rb_id2name(SYM2ID(key));
89
+ rb_iv_set(db_options, param.c_str(), INT2NUM(*pOptionVal));
90
+ }
91
+
92
+ static void set_db_option(VALUE o_options, VALUE opts, leveldb::Options* options) {
93
+ if(NIL_P(o_options)) return;
94
+ Check_Type(opts, T_HASH);
95
+
96
+ sync_vals(opts, k_create_if_missing, o_options, &(options->create_if_missing));
97
+ sync_vals(opts, k_error_if_exists, o_options, &(options->error_if_exists));
98
+ sync_vals(opts, k_paranoid_checks, o_options, &(options->paranoid_checks));
99
+ sync_vals(opts, k_write_buffer_size, o_options, &(options->write_buffer_size));
100
+ sync_vals(opts, k_max_open_files, o_options, &(options->max_open_files));
101
+ sync_vals(opts, k_block_size, o_options, &(options->block_size));
102
+ sync_vals(opts, k_block_restart_interval, o_options, &(options->block_restart_interval));
103
+
104
+ VALUE v = rb_hash_aref(opts, k_block_cache_size);
105
+ if(!NIL_P(v)) {
106
+ options->block_cache = leveldb::NewLRUCache(NUM2INT(v));
107
+ rb_iv_set(o_options, "@block_cache_size", v);
108
+ }
109
+
110
+ v = rb_hash_aref(opts, k_compression);
111
+ if(!NIL_P(v)) {
112
+ if(v == c_no_compression) options->compression = leveldb::kNoCompression;
113
+ else if(v == c_snappy_compression) options->compression = leveldb::kSnappyCompression;
114
+ else rb_raise(rb_eTypeError, "invalid type for %s", rb_id2name(SYM2ID(k_compression)));
115
+ }
116
+
117
+ if(options->compression == leveldb::kNoCompression) rb_iv_set(o_options, "@compression", c_no_compression);
118
+ else if(options->compression == leveldb::kSnappyCompression) rb_iv_set(o_options, "@compression", c_snappy_compression);
119
+ }
120
+
121
+ /*
122
+ * call-seq:
123
+ * make(pathname, options)
124
+ *
125
+ * open level-db database
126
+ *
127
+ * pathname path for database
128
+ *
129
+ * [options[ :create_if_missing ]] create if database doesn't exit
130
+ *
131
+ * [options[ :error_if_exists ]] raise error if database exists
132
+ *
133
+ * [options[ :paranoid_checks ]] If true, the implementation will do aggressive checking of the
134
+ * data it is processing and will stop early if it detects any
135
+ * errors. This may have unforeseen ramifications: for example, a
136
+ * corruption of one DB entry may cause a large number of entries to
137
+ * become unreadable or for the entire DB to become unopenable.
138
+ *
139
+ * Default: false
140
+ * [options[ :write_buffer_size ]] Amount of data to build up in memory (backed by an unsorted log
141
+ * on disk) before converting to a sorted on-disk file.
142
+ *
143
+ * Larger values increase performance, especially during bulk
144
+ * loads.
145
+ * Up to two write buffers may be held in memory at the same time,
146
+ * so you may wish to adjust this parameter to control memory
147
+ * usage.
148
+ * Also, a larger write buffer will result in a longer recovery
149
+ * time the next time the database is opened.
150
+ *
151
+ * Default: 4MB
152
+ * [options[ :max_open_files ]] Number of open files that can be used by the DB. You may need to
153
+ * increase this if your database has a large working set (budget
154
+ * one open file per 2MB of working set).
155
+ *
156
+ * Default: 1000
157
+ * [options[ :block_cache_size ]] Control over blocks (user data is stored in a set of blocks,
158
+ * and a block is the unit of reading from disk).
159
+ *
160
+ * If non nil, use the specified cache size.
161
+ * If nil, leveldb will automatically create and use an 8MB
162
+ * internal cache.
163
+ *
164
+ * Default: nil
165
+ * [options[ :block_size ]] Approximate size of user data packed per block. Note that the
166
+ * block size specified here corresponds to uncompressed data. The
167
+ * actual size of the unit read from disk may be smaller if
168
+ * compression is enabled. This parameter can be changed dynamically.
169
+ *
170
+ * Default: 4K
171
+ * [options[ :block_restart_interval ]] Number of keys between restart points for delta
172
+ * encoding of keys.
173
+ * This parameter can be changed dynamically.
174
+ * Most clients should leave this parameter alone.
175
+ *
176
+ * Default: 16
177
+ * [options[ :compression ]] LevelDB::CompressionType::SnappyCompression or
178
+ * LevelDB::CompressionType::NoCompression.
179
+ *
180
+ * Compress blocks using the specified compression algorithm.
181
+ * This parameter can be changed dynamically.
182
+ *
183
+ * Default: LevelDB::CompressionType::SnappyCompression,
184
+ * which gives lightweight but fast compression.
185
+ *
186
+ * Typical speeds of SnappyCompression on an Intel(R) Core(TM)2 2.4GHz:
187
+ * ~200-500MB/s compression
188
+ * ~400-800MB/s decompression
189
+ * Note that these speeds are significantly faster than most
190
+ * persistent storage speeds, and therefore it is typically never
191
+ * worth switching to NoCompression. Even if the input data is
192
+ * incompressible, the SnappyCompression implementation will
193
+ * efficiently detect that and will switch to uncompressed mode.
194
+ * [return] LevelDB::DB instance
195
+ */
196
+ static VALUE db_make(VALUE self, VALUE v_pathname, VALUE v_options) {
49
197
  Check_Type(v_pathname, T_STRING);
50
198
 
51
- bound_db* db = new bound_db;
199
+ auto_ptr<bound_db> db(new bound_db);
52
200
  std::string pathname = std::string((char*)RSTRING_PTR(v_pathname));
53
201
 
54
202
  leveldb::Options options;
55
- if(RTEST(v_create_if_necessary)) options.create_if_missing = true;
56
- if(RTEST(v_break_if_exists)) options.error_if_exists = true;
203
+ VALUE o_options = rb_class_new_instance(0, NULL, c_db_options);
204
+ set_db_option(o_options, v_options, &options);
205
+
57
206
  leveldb::Status status = leveldb::DB::Open(options, pathname, &db->db);
207
+ VALUE o_db = Data_Wrap_Struct(self, NULL, db_free, db.release());
58
208
  RAISE_ON_ERROR(status);
59
209
 
60
- VALUE o_db = Data_Wrap_Struct(klass, NULL, db_free, db);
61
- VALUE argv[1] = { v_pathname };
62
- rb_obj_call_init(o_db, 1, argv);
210
+ rb_iv_set(o_db, "@options", o_options);
211
+ VALUE init_argv[1] = { v_pathname };
212
+ rb_obj_call_init(o_db, 1, init_argv);
63
213
 
64
214
  return o_db;
65
215
  }
@@ -80,10 +230,12 @@ static leveldb::ReadOptions parse_read_options(VALUE options) {
80
230
 
81
231
  if(!NIL_P(options)) {
82
232
  Check_Type(options, T_HASH);
83
- if(rb_hash_aref(options, k_fill) == Qfalse)
84
- readOptions.fill_cache = false;
85
- if(rb_hash_aref(options, k_verify) == Qtrue)
86
- readOptions.verify_checksums = true;
233
+
234
+ VALUE v_fill = rb_hash_aref(options, k_fill);
235
+ VALUE v_verify = rb_hash_aref(options, k_verify);
236
+
237
+ if(!NIL_P(v_fill)) readOptions.fill_cache = RTEST(v_fill);
238
+ if(!NIL_P(v_verify)) readOptions.verify_checksums = RTEST(v_verify);
87
239
  }
88
240
 
89
241
  return readOptions;
@@ -94,8 +246,8 @@ static leveldb::WriteOptions parse_write_options(VALUE options) {
94
246
 
95
247
  if(!NIL_P(options)) {
96
248
  Check_Type(options, T_HASH);
97
- if(rb_hash_aref(options, k_sync) == Qtrue)
98
- writeOptions.sync = true;
249
+ VALUE v_sync = rb_hash_aref(options, k_sync);
250
+ if(!NIL_P(v_sync)) writeOptions.sync = RTEST(v_sync);
99
251
  }
100
252
 
101
253
  return writeOptions;
@@ -299,7 +451,7 @@ static VALUE iter_init(VALUE self, VALUE db, VALUE options) {
299
451
 
300
452
  if(RTEST(key_to)) {
301
453
  iter->check_limit = true;
302
- iter->key_to_str = RUBY_STRING_TO_SLICE(rb_funcall(key_to, to_s, 0)).ToString();
454
+ iter->key_to_str = RUBY_STRING_TO_SLICE(rb_funcall(key_to, k_to_s, 0)).ToString();
303
455
  }
304
456
 
305
457
  rb_iv_set(self, "@from", key_from);
@@ -314,7 +466,7 @@ static VALUE iter_init(VALUE self, VALUE db, VALUE options) {
314
466
  }
315
467
 
316
468
  if(RTEST(key_from)) {
317
- iter->iterator->Seek(RUBY_STRING_TO_SLICE(rb_funcall(key_from, to_s, 0)));
469
+ iter->iterator->Seek(RUBY_STRING_TO_SLICE(rb_funcall(key_from, k_to_s, 0)));
318
470
  } else {
319
471
  if(iter->reversed) {
320
472
  iter->iterator->SeekToLast();
@@ -494,14 +646,24 @@ void Init_leveldb() {
494
646
  k_reversed = ID2SYM(rb_intern("reversed"));
495
647
  k_class = rb_intern("class");
496
648
  k_name = rb_intern("name");
497
- to_s = rb_intern("to_s");
649
+ k_create_if_missing = ID2SYM(rb_intern("create_if_missing"));
650
+ k_error_if_exists = ID2SYM(rb_intern("error_if_exists"));
651
+ k_paranoid_checks = ID2SYM(rb_intern("paranoid_checks"));
652
+ k_write_buffer_size = ID2SYM(rb_intern("write_buffer_size"));
653
+ k_block_cache_size = ID2SYM(rb_intern("block_cache_size"));
654
+ k_block_size = ID2SYM(rb_intern("block_size"));
655
+ k_block_restart_interval = ID2SYM(rb_intern("block_restart_interval"));
656
+ k_compression = ID2SYM(rb_intern("compression"));
657
+ k_max_open_files = ID2SYM(rb_intern("max_open_files"));
658
+ k_to_s = rb_intern("to_s");
659
+
498
660
  uncached_read_options = leveldb::ReadOptions();
499
661
  uncached_read_options.fill_cache = false;
500
662
 
501
663
  m_leveldb = rb_define_module("LevelDB");
502
664
 
503
665
  c_db = rb_define_class_under(m_leveldb, "DB", rb_cObject);
504
- rb_define_singleton_method(c_db, "make", RUBY_METHOD_FUNC(db_make), 3);
666
+ rb_define_singleton_method(c_db, "make", RUBY_METHOD_FUNC(db_make), 2);
505
667
  rb_define_method(c_db, "initialize", RUBY_METHOD_FUNC(db_init), 1);
506
668
  rb_define_method(c_db, "get", RUBY_METHOD_FUNC(db_get), -1);
507
669
  rb_define_method(c_db, "delete", RUBY_METHOD_FUNC(db_delete), -1);
@@ -525,6 +687,13 @@ void Init_leveldb() {
525
687
  rb_define_method(c_batch, "put", RUBY_METHOD_FUNC(batch_put), 2);
526
688
  rb_define_method(c_batch, "delete", RUBY_METHOD_FUNC(batch_delete), 1);
527
689
 
690
+ c_db_options = rb_define_class_under(m_leveldb, "Options", rb_cObject);
691
+
692
+ VALUE m_ctype = rb_define_module_under(m_leveldb, "CompressionType");
693
+ VALUE c_base = rb_define_class_under(m_ctype, "Base", rb_cObject);
694
+ c_no_compression = rb_define_class_under(m_ctype, "NoCompression", c_base);
695
+ c_snappy_compression = rb_define_class_under(m_ctype, "SnappyCompression", c_base);
696
+
528
697
  c_error = rb_define_class_under(m_leveldb, "Error", rb_eStandardError);
529
698
  }
530
699
  }
@@ -2,87 +2,37 @@
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
- CXX ?= g++
6
- CC ?= gcc
5
+ # Inherit some settings from environment variables, if available
6
+ INSTALL_PATH ?= $(CURDIR)
7
7
 
8
8
  #-----------------------------------------------
9
9
  # Uncomment exactly one of the lines labelled (A), (B), and (C) below
10
10
  # to switch between compilation modes.
11
11
 
12
- OPT ?= -O2 -DNDEBUG -fPIC # (A) Production use (optimized mode)
12
+ OPT ?= -O2 -DNDEBUG # (A) Production use (optimized mode)
13
13
  # OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols
14
14
  # OPT ?= -O2 -g2 -DNDEBUG # (C) Profiling mode: opt, but w/debugging symbols
15
15
  #-----------------------------------------------
16
16
 
17
17
  # detect what platform we're building on
18
- $(shell sh ./build_detect_platform)
19
- # this file is generated by build_detect_platform to set build flags
18
+ $(shell ./build_detect_platform build_config.mk)
19
+ # this file is generated by the previous line to set build flags and sources
20
20
  include build_config.mk
21
21
 
22
- # If Snappy is installed, add compilation and linker flags
23
- # (see http://code.google.com/p/snappy/)
24
- ifeq ($(SNAPPY), 1)
25
- SNAPPY_CFLAGS=-DSNAPPY
26
- SNAPPY_LDFLAGS=-lsnappy
27
- else
28
- SNAPPY_CFLAGS=
29
- SNAPPY_LDFLAGS=
30
- endif
22
+ CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
23
+ CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)
31
24
 
32
- # If Google Perf Tools are installed, add compilation and linker flags
33
- # (see http://code.google.com/p/google-perftools/)
34
- ifeq ($(GOOGLE_PERFTOOLS), 1)
35
- GOOGLE_PERFTOOLS_LDFLAGS=-ltcmalloc
36
- else
37
- GOOGLE_PERFTOOLS_LDFLAGS=
38
- endif
25
+ LDFLAGS += $(PLATFORM_LDFLAGS)
39
26
 
40
- CFLAGS = -c -I. -I./include $(PORT_CFLAGS) $(PLATFORM_CFLAGS) $(OPT) $(SNAPPY_CFLAGS)
41
-
42
- LDFLAGS += $(PLATFORM_LDFLAGS) $(SNAPPY_LDFLAGS) $(GOOGLE_PERFTOOLS_LDFLAGS)
43
-
44
- LIBOBJECTS = \
45
- ./db/builder.o \
46
- ./db/c.o \
47
- ./db/db_impl.o \
48
- ./db/db_iter.o \
49
- ./db/filename.o \
50
- ./db/dbformat.o \
51
- ./db/log_reader.o \
52
- ./db/log_writer.o \
53
- ./db/memtable.o \
54
- ./db/repair.o \
55
- ./db/table_cache.o \
56
- ./db/version_edit.o \
57
- ./db/version_set.o \
58
- ./db/write_batch.o \
59
- ./port/port_posix.o \
60
- ./table/block.o \
61
- ./table/block_builder.o \
62
- ./table/format.o \
63
- ./table/iterator.o \
64
- ./table/merger.o \
65
- ./table/table.o \
66
- ./table/table_builder.o \
67
- ./table/two_level_iterator.o \
68
- ./util/arena.o \
69
- ./util/cache.o \
70
- ./util/coding.o \
71
- ./util/comparator.o \
72
- ./util/crc32c.o \
73
- ./util/env.o \
74
- ./util/env_posix.o \
75
- ./util/hash.o \
76
- ./util/histogram.o \
77
- ./util/logging.o \
78
- ./util/options.o \
79
- ./util/status.o
27
+ LIBOBJECTS = $(SOURCES:.cc=.o)
28
+ MEMENVOBJECTS = $(MEMENV_SOURCES:.cc=.o)
80
29
 
81
30
  TESTUTIL = ./util/testutil.o
82
31
  TESTHARNESS = ./util/testharness.o $(TESTUTIL)
83
32
 
84
33
  TESTS = \
85
34
  arena_test \
35
+ bloom_test \
86
36
  c_test \
87
37
  cache_test \
88
38
  coding_test \
@@ -92,6 +42,7 @@ TESTS = \
92
42
  dbformat_test \
93
43
  env_test \
94
44
  filename_test \
45
+ filter_block_test \
95
46
  log_test \
96
47
  memenv_test \
97
48
  skiplist_test \
@@ -106,109 +57,144 @@ BENCHMARKS = db_bench_sqlite3 db_bench_tree_db
106
57
  LIBRARY = libleveldb.a
107
58
  MEMENVLIBRARY = libmemenv.a
108
59
 
109
- all: $(LIBRARY)
60
+ default: all
110
61
 
111
- check: $(PROGRAMS) $(TESTS)
62
+ # Should we build shared libraries?
63
+ ifneq ($(PLATFORM_SHARED_EXT),)
64
+
65
+ ifneq ($(PLATFORM_SHARED_VERSIONED),true)
66
+ SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
67
+ SHARED2 = $(SHARED1)
68
+ SHARED3 = $(SHARED1)
69
+ SHARED = $(SHARED1)
70
+ else
71
+ # Update db.h if you change these.
72
+ SHARED_MAJOR = 1
73
+ SHARED_MINOR = 5
74
+ SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
75
+ SHARED2 = $(SHARED1).$(SHARED_MAJOR)
76
+ SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR)
77
+ SHARED = $(SHARED1) $(SHARED2) $(SHARED3)
78
+ $(SHARED1): $(SHARED3)
79
+ ln -fs $(SHARED3) $(SHARED1)
80
+ $(SHARED2): $(SHARED3)
81
+ ln -fs $(SHARED3) $(SHARED2)
82
+ endif
83
+
84
+ $(SHARED3):
85
+ $(CXX) $(LDFLAGS) $(PLATFORM_SHARED_LDFLAGS)$(SHARED2) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(SOURCES) -o $(SHARED3)
86
+
87
+ endif # PLATFORM_SHARED_EXT
88
+
89
+ all: $(SHARED) $(LIBRARY)
90
+
91
+ check: all $(PROGRAMS) $(TESTS)
112
92
  for t in $(TESTS); do echo "***** Running $$t"; ./$$t || exit 1; done
113
93
 
114
94
  clean:
115
- -rm -f $(PROGRAMS) $(BENCHMARKS) $(LIBRARY) $(MEMENVLIBRARY) */*.o */*/*.o ios-x86/*/*.o ios-arm/*/*.o
95
+ -rm -f $(PROGRAMS) $(BENCHMARKS) $(LIBRARY) $(SHARED) $(MEMENVLIBRARY) */*.o */*/*.o ios-x86/*/*.o ios-arm/*/*.o build_config.mk
116
96
  -rm -rf ios-x86/* ios-arm/*
117
- -rm build_config.mk
118
97
 
119
98
  $(LIBRARY): $(LIBOBJECTS)
120
99
  rm -f $@
121
100
  $(AR) -rs $@ $(LIBOBJECTS)
122
101
 
123
102
  db_bench: db/db_bench.o $(LIBOBJECTS) $(TESTUTIL)
124
- $(CXX) $(LDFLAGS) db/db_bench.o $(LIBOBJECTS) $(TESTUTIL) -o $@
103
+ $(CXX) db/db_bench.o $(LIBOBJECTS) $(TESTUTIL) -o $@ $(LDFLAGS)
125
104
 
126
105
  db_bench_sqlite3: doc/bench/db_bench_sqlite3.o $(LIBOBJECTS) $(TESTUTIL)
127
- $(CXX) $(LDFLAGS) -lsqlite3 doc/bench/db_bench_sqlite3.o $(LIBOBJECTS) $(TESTUTIL) -o $@
106
+ $(CXX) doc/bench/db_bench_sqlite3.o $(LIBOBJECTS) $(TESTUTIL) -o $@ $(LDFLAGS) -lsqlite3
128
107
 
129
108
  db_bench_tree_db: doc/bench/db_bench_tree_db.o $(LIBOBJECTS) $(TESTUTIL)
130
- $(CXX) $(LDFLAGS) -lkyotocabinet doc/bench/db_bench_tree_db.o $(LIBOBJECTS) $(TESTUTIL) -o $@
109
+ $(CXX) doc/bench/db_bench_tree_db.o $(LIBOBJECTS) $(TESTUTIL) -o $@ $(LDFLAGS) -lkyotocabinet
131
110
 
132
111
  arena_test: util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS)
133
- $(CXX) $(LDFLAGS) util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
112
+ $(CXX) util/arena_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
113
+
114
+ bloom_test: util/bloom_test.o $(LIBOBJECTS) $(TESTHARNESS)
115
+ $(CXX) util/bloom_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
134
116
 
135
117
  c_test: db/c_test.o $(LIBOBJECTS) $(TESTHARNESS)
136
- $(CXX) $(LDFLAGS) db/c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
118
+ $(CXX) db/c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
137
119
 
138
120
  cache_test: util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS)
139
- $(CXX) $(LDFLAGS) util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
121
+ $(CXX) util/cache_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
140
122
 
141
123
  coding_test: util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS)
142
- $(CXX) $(LDFLAGS) util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
124
+ $(CXX) util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
143
125
 
144
126
  corruption_test: db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS)
145
- $(CXX) $(LDFLAGS) db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
127
+ $(CXX) db/corruption_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
146
128
 
147
129
  crc32c_test: util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS)
148
- $(CXX) $(LDFLAGS) util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
130
+ $(CXX) util/crc32c_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
149
131
 
150
132
  db_test: db/db_test.o $(LIBOBJECTS) $(TESTHARNESS)
151
- $(CXX) $(LDFLAGS) db/db_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
133
+ $(CXX) db/db_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
152
134
 
153
135
  dbformat_test: db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS)
154
- $(CXX) $(LDFLAGS) db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
136
+ $(CXX) db/dbformat_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
155
137
 
156
138
  env_test: util/env_test.o $(LIBOBJECTS) $(TESTHARNESS)
157
- $(CXX) $(LDFLAGS) util/env_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
139
+ $(CXX) util/env_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
158
140
 
159
141
  filename_test: db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS)
160
- $(CXX) $(LDFLAGS) db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
142
+ $(CXX) db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
143
+
144
+ filter_block_test: table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS)
145
+ $(CXX) table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
161
146
 
162
147
  log_test: db/log_test.o $(LIBOBJECTS) $(TESTHARNESS)
163
- $(CXX) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
148
+ $(CXX) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
164
149
 
165
150
  table_test: table/table_test.o $(LIBOBJECTS) $(TESTHARNESS)
166
- $(CXX) $(LDFLAGS) table/table_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
151
+ $(CXX) table/table_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
167
152
 
168
153
  skiplist_test: db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS)
169
- $(CXX) $(LDFLAGS) db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
154
+ $(CXX) db/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
170
155
 
171
156
  version_edit_test: db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS)
172
- $(CXX) $(LDFLAGS) db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
157
+ $(CXX) db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
173
158
 
174
159
  version_set_test: db/version_set_test.o $(LIBOBJECTS) $(TESTHARNESS)
175
- $(CXX) $(LDFLAGS) db/version_set_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
160
+ $(CXX) db/version_set_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
176
161
 
177
162
  write_batch_test: db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS)
178
- $(CXX) $(LDFLAGS) db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@
163
+ $(CXX) db/write_batch_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LDFLAGS)
179
164
 
180
- $(MEMENVLIBRARY) : helpers/memenv/memenv.o
165
+ $(MEMENVLIBRARY) : $(MEMENVOBJECTS)
181
166
  rm -f $@
182
- $(AR) -rs $@ helpers/memenv/memenv.o
167
+ $(AR) -rs $@ $(MEMENVOBJECTS)
183
168
 
184
169
  memenv_test : helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS)
185
- $(CXX) $(LDFLAGS) helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS) -o $@
170
+ $(CXX) helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS) -o $@ $(LDFLAGS)
186
171
 
187
172
  ifeq ($(PLATFORM), IOS)
188
173
  # For iOS, create universal object files to be used on both the simulator and
189
174
  # a device.
190
- SIMULATORROOT=/Developer/Platforms/iPhoneSimulator.platform/Developer
191
- DEVICEROOT=/Developer/Platforms/iPhoneOS.platform/Developer
192
- IOSVERSION=$(shell defaults read /Developer/Platforms/iPhoneOS.platform/version CFBundleShortVersionString)
175
+ PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms
176
+ SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer
177
+ DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer
178
+ IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString)
193
179
 
194
180
  .cc.o:
195
181
  mkdir -p ios-x86/$(dir $@)
196
- $(SIMULATORROOT)/usr/bin/$(CXX) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 $< -o ios-x86/$@
182
+ $(SIMULATORROOT)/usr/bin/$(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@
197
183
  mkdir -p ios-arm/$(dir $@)
198
- $(DEVICEROOT)/usr/bin/$(CXX) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 $< -o ios-arm/$@
184
+ $(DEVICEROOT)/usr/bin/$(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@
199
185
  lipo ios-x86/$@ ios-arm/$@ -create -output $@
200
186
 
201
187
  .c.o:
202
188
  mkdir -p ios-x86/$(dir $@)
203
- $(SIMULATORROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 $< -o ios-x86/$@
189
+ $(SIMULATORROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@
204
190
  mkdir -p ios-arm/$(dir $@)
205
- $(DEVICEROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 $< -o ios-arm/$@
191
+ $(DEVICEROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@
206
192
  lipo ios-x86/$@ ios-arm/$@ -create -output $@
207
193
 
208
194
  else
209
195
  .cc.o:
210
- $(CXX) $(CFLAGS) $< -o $@
196
+ $(CXX) $(CXXFLAGS) -c $< -o $@
211
197
 
212
198
  .c.o:
213
- $(CC) $(CFLAGS) $< -o $@
199
+ $(CC) $(CFLAGS) -c $< -o $@
214
200
  endif