leveldb-ruby 0.14 → 0.15

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.
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