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
@@ -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
  }