leveldb-ruby 0.10 → 0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -1,18 +1,14 @@
1
1
  require 'mkmf'
2
2
  require 'fileutils'
3
+ require "./platform.rb"
3
4
 
4
5
  Dir.chdir "../../leveldb"
5
6
  system "make libleveldb.a" or abort
6
7
  Dir.chdir "../ext/leveldb"
7
8
 
8
- CONFIG['LDSHARED'] = "$(CXX) -shared"
9
+ set_platform_specific_variables!
9
10
 
10
11
  $CFLAGS << " -I../../leveldb/include"
11
12
  $LIBS << " -L../../leveldb -lleveldb"
12
- if RUBY_PLATFORM =~ /darwin/
13
- $CFLAGS.sub! "-arch i386", ""
14
- $LDFLAGS.sub! "-arch i386", ""
15
- $LIBS << " -lruby" # whyyyyy
16
- end
17
13
 
18
14
  create_makefile "leveldb/leveldb"
@@ -2,10 +2,23 @@
2
2
 
3
3
  #include "leveldb/db.h"
4
4
  #include "leveldb/slice.h"
5
+ #include "leveldb/write_batch.h"
5
6
 
6
7
  static VALUE m_leveldb;
7
8
  static VALUE c_db;
9
+ static VALUE c_iter;
10
+ static VALUE c_batch;
8
11
  static VALUE c_error;
12
+ static VALUE k_fill;
13
+ static VALUE k_verify;
14
+ static VALUE k_sync;
15
+ static VALUE k_from;
16
+ static VALUE k_to;
17
+ static VALUE k_reversed;
18
+ static VALUE k_class;
19
+ static VALUE k_name;
20
+ static ID to_s;
21
+ static leveldb::ReadOptions uncached_read_options;
9
22
 
10
23
  // support 1.9 and 1.8
11
24
  #ifndef RSTRING_PTR
@@ -62,37 +75,89 @@ static VALUE db_close(VALUE self) {
62
75
  return Qtrue;
63
76
  }
64
77
 
78
+ static leveldb::ReadOptions parse_read_options(VALUE options) {
79
+ leveldb::ReadOptions readOptions;
80
+
81
+ if(!NIL_P(options)) {
82
+ 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;
87
+ }
88
+
89
+ return readOptions;
90
+ }
91
+
92
+ static leveldb::WriteOptions parse_write_options(VALUE options) {
93
+ leveldb::WriteOptions writeOptions;
94
+
95
+ if(!NIL_P(options)) {
96
+ Check_Type(options, T_HASH);
97
+ if(rb_hash_aref(options, k_sync) == Qtrue)
98
+ writeOptions.sync = true;
99
+ }
100
+
101
+ return writeOptions;
102
+ }
103
+
65
104
  #define RUBY_STRING_TO_SLICE(x) leveldb::Slice(RSTRING_PTR(x), RSTRING_LEN(x))
66
105
  #define SLICE_TO_RUBY_STRING(x) rb_str_new(x.data(), x.size())
67
106
  #define STRING_TO_RUBY_STRING(x) rb_str_new(x.data(), x.size())
68
- static VALUE db_get(VALUE self, VALUE v_key) {
107
+
108
+ /*
109
+ * call-seq:
110
+ * get(key, options = nil)
111
+ *
112
+ * get data from db
113
+ *
114
+ * [key] key you want to get
115
+ * [options[ :fill_cache ]] Should the data read for this iteration be cached in memory?
116
+ * Callers may wish to set this field to false for bulk scans.
117
+ *
118
+ * true or false
119
+ *
120
+ * Default: true
121
+ * [options[ :verify_checksums ]] If true, all data read from underlying storage will be
122
+ * verified against corresponding checksums.
123
+ *
124
+ * Default: false
125
+ * [return] value of stored db
126
+ */
127
+ static VALUE db_get(int argc, VALUE* argv, VALUE self) {
128
+ VALUE v_key, v_options;
129
+ rb_scan_args(argc, argv, "11", &v_key, &v_options);
69
130
  Check_Type(v_key, T_STRING);
131
+ leveldb::ReadOptions readOptions = parse_read_options(v_options);
70
132
 
71
133
  bound_db* db;
72
134
  Data_Get_Struct(self, bound_db, db);
73
135
 
74
136
  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
75
137
  std::string value;
76
- leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);
138
+ leveldb::Status status = db->db->Get(readOptions, key, &value);
77
139
  if(status.IsNotFound()) return Qnil;
78
140
 
79
141
  RAISE_ON_ERROR(status);
80
142
  return STRING_TO_RUBY_STRING(value);
81
143
  }
82
144
 
83
- static VALUE db_delete(VALUE self, VALUE v_key) {
145
+ static VALUE db_delete(int argc, VALUE* argv, VALUE self) {
146
+ VALUE v_key, v_options;
147
+ rb_scan_args(argc, argv, "11", &v_key, &v_options);
84
148
  Check_Type(v_key, T_STRING);
149
+ leveldb::WriteOptions writeOptions = parse_write_options(v_options);
85
150
 
86
151
  bound_db* db;
87
152
  Data_Get_Struct(self, bound_db, db);
88
153
 
89
154
  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
90
155
  std::string value;
91
- leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);
156
+ leveldb::Status status = db->db->Get(uncached_read_options, key, &value);
92
157
 
93
158
  if(status.IsNotFound()) return Qnil;
94
159
 
95
- status = db->db->Delete(leveldb::WriteOptions(), key);
160
+ status = db->db->Delete(writeOptions, key);
96
161
  RAISE_ON_ERROR(status);
97
162
 
98
163
  return STRING_TO_RUBY_STRING(value);
@@ -112,16 +177,46 @@ static VALUE db_exists(VALUE self, VALUE v_key) {
112
177
  return Qtrue;
113
178
  }
114
179
 
115
- static VALUE db_put(VALUE self, VALUE v_key, VALUE v_value) {
180
+ /*
181
+ * call-seq:
182
+ * put(key, value, options = nil)
183
+ *
184
+ * store data into DB
185
+ *
186
+ * [key] key you want to store
187
+ * [value] data you want to store
188
+ * [options[ :sync ]] If true, the write will be flushed from the operating system
189
+ * buffer cache (by calling WritableFile::Sync()) before the write
190
+ * is considered complete. If this flag is true, writes will be
191
+ * slower.
192
+ *
193
+ * If this flag is false, and the machine crashes, some recent
194
+ * writes may be lost. Note that if it is just the process that
195
+ * crashes (i.e., the machine does not reboot), no writes will be
196
+ * lost even if sync==false.
197
+ *
198
+ * In other words, a DB write with sync==false has similar
199
+ * crash semantics as the "write()" system call. A DB write
200
+ * with sync==true has similar crash semantics to a "write()"
201
+ * system call followed by "fsync()".
202
+ *
203
+ * Default: false
204
+ * [return] stored value
205
+ */
206
+ static VALUE db_put(int argc, VALUE* argv, VALUE self) {
207
+ VALUE v_key, v_value, v_options;
208
+
209
+ rb_scan_args(argc, argv, "21", &v_key, &v_value, &v_options);
116
210
  Check_Type(v_key, T_STRING);
117
211
  Check_Type(v_value, T_STRING);
212
+ leveldb::WriteOptions writeOptions = parse_write_options(v_options);
118
213
 
119
214
  bound_db* db;
120
215
  Data_Get_Struct(self, bound_db, db);
121
216
 
122
217
  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
123
218
  leveldb::Slice value = RUBY_STRING_TO_SLICE(v_value);
124
- leveldb::Status status = db->db->Put(leveldb::WriteOptions(), key, value);
219
+ leveldb::Status status = db->db->Put(writeOptions, key, value);
125
220
 
126
221
  RAISE_ON_ERROR(status);
127
222
 
@@ -133,7 +228,7 @@ static VALUE db_size(VALUE self) {
133
228
 
134
229
  bound_db* db;
135
230
  Data_Get_Struct(self, bound_db, db);
136
- leveldb::Iterator* it = db->db->NewIterator(leveldb::ReadOptions());
231
+ leveldb::Iterator* it = db->db->NewIterator(uncached_read_options);
137
232
 
138
233
  // apparently this is how we have to do it. slow and painful!
139
234
  for (it->SeekToFirst(); it->Valid(); it->Next()) count++;
@@ -142,45 +237,294 @@ static VALUE db_size(VALUE self) {
142
237
  return INT2NUM(count);
143
238
  }
144
239
 
145
- static VALUE db_each(VALUE self) {
146
- bound_db* db;
147
- Data_Get_Struct(self, bound_db, db);
148
- leveldb::Iterator* it = db->db->NewIterator(leveldb::ReadOptions());
149
-
150
- for (it->SeekToFirst(); it->Valid(); it->Next()) {
151
- VALUE key = SLICE_TO_RUBY_STRING(it->key());
152
- VALUE value = SLICE_TO_RUBY_STRING(it->value());
153
- VALUE ary = rb_ary_new2(2);
154
- rb_ary_push(ary, key);
155
- rb_ary_push(ary, value);
156
- rb_yield(ary);
240
+ static VALUE db_init(VALUE self, VALUE v_pathname) {
241
+ rb_iv_set(self, "@pathname", v_pathname);
242
+ return self;
243
+ }
244
+
245
+ typedef struct current_iteration {
246
+ leveldb::Iterator* iterator;
247
+ bool passed_limit;
248
+ bool check_limit;
249
+ bool reversed;
250
+ int checked_valid; // 0 = unchecked, 1 = valid, -1 = invalid
251
+ std::string key_to_str;
252
+ leveldb::Slice current_key;
253
+ } current_iteration;
254
+
255
+ static void current_iteration_free(current_iteration* iter) {
256
+ delete iter;
257
+ }
258
+
259
+ static VALUE iter_make(VALUE klass, VALUE db, VALUE options) {
260
+ if(c_db != rb_funcall(db, k_class, 0)) {
261
+ rb_raise(rb_eArgError, "db must be a LevelDB::DB");
157
262
  }
158
263
 
159
- RAISE_ON_ERROR(it->status());
160
- delete it;
264
+ bound_db* b_db;
265
+ Data_Get_Struct(db, bound_db, b_db);
266
+
267
+ current_iteration* iter = new current_iteration;
268
+ iter->passed_limit = false;
269
+ iter->check_limit = false;
270
+ iter->checked_valid = 0;
271
+ iter->iterator = b_db->db->NewIterator(uncached_read_options);
272
+
273
+ VALUE o_iter = Data_Wrap_Struct(klass, NULL, current_iteration_free, iter);
274
+
275
+ VALUE argv[2];
276
+ argv[0] = db;
277
+ argv[1] = options;
278
+ rb_obj_call_init(o_iter, 2, argv);
279
+
280
+ return o_iter;
281
+ }
282
+
283
+ static VALUE iter_init(VALUE self, VALUE db, VALUE options) {
284
+ if(c_db != rb_funcall(db, k_class, 0)) {
285
+ rb_raise(rb_eArgError, "db must be a LevelDB::DB");
286
+ }
287
+
288
+ rb_iv_set(self, "@db", db);
289
+ current_iteration* iter;
290
+ Data_Get_Struct(self, current_iteration, iter);
291
+
292
+ VALUE key_from = Qnil;
293
+ VALUE key_to = Qnil;
294
+
295
+ if(!NIL_P(options)) {
296
+ Check_Type(options, T_HASH);
297
+ key_from = rb_hash_aref(options, k_from);
298
+ key_to = rb_hash_aref(options, k_to);
299
+
300
+ if(RTEST(key_to)) {
301
+ iter->check_limit = true;
302
+ iter->key_to_str = RUBY_STRING_TO_SLICE(rb_funcall(key_to, to_s, 0)).ToString();
303
+ }
304
+
305
+ rb_iv_set(self, "@from", key_from);
306
+ rb_iv_set(self, "@to", key_to);
307
+ if(NIL_P(rb_hash_aref(options, k_reversed))) {
308
+ iter->reversed = false;
309
+ rb_iv_set(self, "@reversed", false);
310
+ } else {
311
+ iter->reversed = true;
312
+ rb_iv_set(self, "@reversed", true);
313
+ }
314
+ }
315
+
316
+ if(RTEST(key_from)) {
317
+ iter->iterator->Seek(RUBY_STRING_TO_SLICE(rb_funcall(key_from, to_s, 0)));
318
+ } else {
319
+ if(iter->reversed) {
320
+ iter->iterator->SeekToLast();
321
+ } else {
322
+ iter->iterator->SeekToFirst();
323
+ }
324
+ }
161
325
 
162
326
  return self;
163
327
  }
164
328
 
165
- static VALUE db_init(VALUE self, VALUE v_pathname) {
166
- rb_iv_set(self, "@pathname", v_pathname);
329
+ static bool iter_valid(current_iteration* iter) {
330
+ if(iter->checked_valid == 0) {
331
+ if(iter->passed_limit) {
332
+ iter->checked_valid = -2;
333
+ } else {
334
+ if(iter->iterator->Valid()) {
335
+ iter->current_key = iter->iterator->key();
336
+
337
+ if(iter->check_limit &&
338
+ (iter->reversed ?
339
+ (iter->current_key.ToString() < iter->key_to_str) :
340
+ (iter->current_key.ToString() > iter->key_to_str))) {
341
+ iter->passed_limit = true;
342
+ iter->checked_valid = -2;
343
+ } else {
344
+ iter->checked_valid = 1;
345
+ }
346
+
347
+ } else {
348
+ iter->checked_valid = -1;
349
+ }
350
+ }
351
+ }
352
+
353
+ if(iter->checked_valid == 1)
354
+ return true;
355
+ else
356
+ return false;
357
+ }
358
+
359
+ static VALUE iter_invalid_reason(VALUE self) {
360
+ current_iteration* iter;
361
+ Data_Get_Struct(self, current_iteration, iter);
362
+ if(iter_valid(iter)) {
363
+ return Qnil;
364
+ } else {
365
+ return INT2FIX(iter->checked_valid);
366
+ }
367
+ }
368
+
369
+ static VALUE iter_next_value(current_iteration* iter) {
370
+ VALUE arr = rb_ary_new2(2);
371
+ rb_ary_push(arr, SLICE_TO_RUBY_STRING(iter->current_key));
372
+ rb_ary_push(arr, SLICE_TO_RUBY_STRING(iter->iterator->value()));
373
+ }
374
+
375
+ static void iter_scan_iterator(current_iteration* iter) {
376
+ if(iter->reversed)
377
+ iter->iterator->Prev();
378
+ else
379
+ iter->iterator->Next();
380
+ iter->checked_valid = 0;
381
+ }
382
+
383
+ static VALUE iter_peek(VALUE self) {
384
+ current_iteration* iter;
385
+ Data_Get_Struct(self, current_iteration, iter);
386
+ if(iter_valid(iter)) {
387
+ return iter_next_value(iter);
388
+ } else {
389
+ return Qnil;
390
+ }
391
+ }
392
+
393
+ static VALUE iter_scan(VALUE self) {
394
+ current_iteration* iter;
395
+ Data_Get_Struct(self, current_iteration, iter);
396
+ if(iter_valid(iter))
397
+ iter_scan_iterator(iter);
398
+ return Qnil;
399
+ }
400
+
401
+ static VALUE iter_next(VALUE self) {
402
+ current_iteration* iter;
403
+ Data_Get_Struct(self, current_iteration, iter);
404
+
405
+ VALUE arr = Qnil;
406
+
407
+ if(iter_valid(iter)) {
408
+ arr = iter_next_value(iter);
409
+ iter_scan_iterator(iter);
410
+ }
411
+
412
+ return arr;
413
+ }
414
+
415
+ static VALUE iter_each(VALUE self) {
416
+ current_iteration* iter;
417
+ Data_Get_Struct(self, current_iteration, iter);
418
+
419
+ while(iter_valid(iter)) {
420
+ rb_yield(iter_next_value(iter));
421
+ iter_scan_iterator(iter);
422
+ }
423
+
424
+ RAISE_ON_ERROR(iter->iterator->status());
425
+ delete iter->iterator;
167
426
  return self;
168
427
  }
169
428
 
429
+ typedef struct bound_batch {
430
+ leveldb::WriteBatch batch;
431
+ } bound_batch;
432
+
433
+ static void batch_free(bound_batch* batch) {
434
+ delete batch;
435
+ }
436
+
437
+ static VALUE batch_make(VALUE klass) {
438
+ bound_batch* batch = new bound_batch;
439
+ batch->batch = leveldb::WriteBatch();
440
+
441
+ VALUE o_batch = Data_Wrap_Struct(klass, NULL, batch_free, batch);
442
+ VALUE argv[0];
443
+ rb_obj_call_init(o_batch, 0, argv);
444
+
445
+ return o_batch;
446
+ }
447
+
448
+ static VALUE batch_put(VALUE self, VALUE v_key, VALUE v_value) {
449
+ Check_Type(v_key, T_STRING);
450
+ Check_Type(v_value, T_STRING);
451
+
452
+ bound_batch* batch;
453
+ Data_Get_Struct(self, bound_batch, batch);
454
+ batch->batch.Put(RUBY_STRING_TO_SLICE(v_key), RUBY_STRING_TO_SLICE(v_value));
455
+
456
+ return v_value;
457
+ }
458
+
459
+ static VALUE batch_delete(VALUE self, VALUE v_key) {
460
+ Check_Type(v_key, T_STRING);
461
+ bound_batch* batch;
462
+ Data_Get_Struct(self, bound_batch, batch);
463
+ batch->batch.Delete(RUBY_STRING_TO_SLICE(v_key));
464
+ return Qtrue;
465
+ }
466
+
467
+ static VALUE db_batch(int argc, VALUE* argv, VALUE self) {
468
+ VALUE o_batch = batch_make(c_batch);
469
+
470
+ rb_yield(o_batch);
471
+
472
+ bound_batch* batch;
473
+ bound_db* db;
474
+ Data_Get_Struct(o_batch, bound_batch, batch);
475
+ Data_Get_Struct(self, bound_db, db);
476
+
477
+ VALUE v_options;
478
+ rb_scan_args(argc, argv, "01", &v_options);
479
+ leveldb::WriteOptions writeOptions = parse_write_options(v_options);
480
+
481
+ leveldb::Status status = db->db->Write(writeOptions, &batch->batch);
482
+ RAISE_ON_ERROR(status);
483
+ return Qtrue;
484
+ }
485
+
170
486
  extern "C" {
171
487
  void Init_leveldb() {
488
+ k_fill = ID2SYM(rb_intern("fill_cache"));
489
+ k_verify = ID2SYM(rb_intern("verify_checksums"));
490
+ k_sync = ID2SYM(rb_intern("sync"));
491
+ k_from = ID2SYM(rb_intern("from"));
492
+ k_to = ID2SYM(rb_intern("to"));
493
+ k_reversed = ID2SYM(rb_intern("reversed"));
494
+ k_class = rb_intern("class");
495
+ k_name = rb_intern("name");
496
+ to_s = rb_intern("to_s");
497
+ uncached_read_options = leveldb::ReadOptions();
498
+ uncached_read_options.fill_cache = false;
499
+
172
500
  m_leveldb = rb_define_module("LevelDB");
173
501
 
502
+ printf("initialized the correct codebase\n");
503
+
174
504
  c_db = rb_define_class_under(m_leveldb, "DB", rb_cObject);
175
- rb_define_singleton_method(c_db, "make", (VALUE (*)(...))db_make, 3);
176
- rb_define_method(c_db, "initialize", (VALUE (*)(...))db_init, 1);
177
- rb_define_method(c_db, "get", (VALUE (*)(...))db_get, 1);
178
- rb_define_method(c_db, "delete", (VALUE (*)(...))db_delete, 1);
179
- rb_define_method(c_db, "put", (VALUE (*)(...))db_put, 2);
180
- rb_define_method(c_db, "exists?", (VALUE (*)(...))db_exists, 1);
181
- rb_define_method(c_db, "close", (VALUE (*)(...))db_close, 0);
182
- rb_define_method(c_db, "size", (VALUE (*)(...))db_size, 0);
183
- rb_define_method(c_db, "each", (VALUE (*)(...))db_each, 0);
505
+ rb_define_singleton_method(c_db, "make", RUBY_METHOD_FUNC(db_make), 3);
506
+ rb_define_method(c_db, "initialize", RUBY_METHOD_FUNC(db_init), 1);
507
+ rb_define_method(c_db, "get", RUBY_METHOD_FUNC(db_get), -1);
508
+ rb_define_method(c_db, "delete", RUBY_METHOD_FUNC(db_delete), -1);
509
+ rb_define_method(c_db, "put", RUBY_METHOD_FUNC(db_put), -1);
510
+ rb_define_method(c_db, "exists?", RUBY_METHOD_FUNC(db_exists), 1);
511
+ rb_define_method(c_db, "close", RUBY_METHOD_FUNC(db_close), 0);
512
+ rb_define_method(c_db, "size", RUBY_METHOD_FUNC(db_size), 0);
513
+ rb_define_method(c_db, "batch", RUBY_METHOD_FUNC(db_batch), -1);
514
+
515
+ c_iter = rb_define_class_under(m_leveldb, "Iterator", rb_cObject);
516
+ rb_define_singleton_method(c_iter, "make", RUBY_METHOD_FUNC(iter_make), 2);
517
+ rb_define_method(c_iter, "initialize", RUBY_METHOD_FUNC(iter_init), 2);
518
+ rb_define_method(c_iter, "each", RUBY_METHOD_FUNC(iter_each), 0);
519
+ rb_define_method(c_iter, "next", RUBY_METHOD_FUNC(iter_next), 0);
520
+ rb_define_method(c_iter, "scan", RUBY_METHOD_FUNC(iter_scan), 0);
521
+ rb_define_method(c_iter, "peek", RUBY_METHOD_FUNC(iter_peek), 0);
522
+ rb_define_method(c_iter, "invalid_reason", RUBY_METHOD_FUNC(iter_invalid_reason), 0);
523
+
524
+ c_batch = rb_define_class_under(m_leveldb, "WriteBatch", rb_cObject);
525
+ rb_define_singleton_method(c_batch, "make", RUBY_METHOD_FUNC(batch_make), 0);
526
+ rb_define_method(c_batch, "put", RUBY_METHOD_FUNC(batch_put), 2);
527
+ rb_define_method(c_batch, "delete", RUBY_METHOD_FUNC(batch_delete), 1);
184
528
 
185
529
  c_error = rb_define_class_under(m_leveldb, "Error", rb_eStandardError);
186
530
  }