roma 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/LICENSE.rdoc +675 -0
  2. data/README.rdoc +0 -0
  3. data/Rakefile +70 -0
  4. data/bin/mkrecent +7 -0
  5. data/bin/mkroute +7 -0
  6. data/bin/recoverlost +8 -0
  7. data/bin/recoverlost_alist +8 -0
  8. data/bin/romad +7 -0
  9. data/bin/sample_watcher +8 -0
  10. data/bin/sample_watcher2 +8 -0
  11. data/bin/simple_bench +8 -0
  12. data/bin/ssroute +7 -0
  13. data/bin/tribunus +7 -0
  14. data/lib/roma/async_process.rb +696 -0
  15. data/lib/roma/command/bg_command_receiver.rb +188 -0
  16. data/lib/roma/command/mh_command_receiver.rb +117 -0
  17. data/lib/roma/command/receiver.rb +287 -0
  18. data/lib/roma/command/rt_command_receiver.rb +147 -0
  19. data/lib/roma/command/st_command_receiver.rb +564 -0
  20. data/lib/roma/command/util_command_receiver.rb +67 -0
  21. data/lib/roma/command/vn_command_receiver.rb +143 -0
  22. data/lib/roma/command_plugin.rb +11 -0
  23. data/lib/roma/config.rb +64 -0
  24. data/lib/roma/event/con_pool.rb +140 -0
  25. data/lib/roma/event/handler.rb +159 -0
  26. data/lib/roma/plugin/plugin_alist.rb +1572 -0
  27. data/lib/roma/plugin/plugin_debug.rb +19 -0
  28. data/lib/roma/plugin/plugin_test.rb +14 -0
  29. data/lib/roma/romad.rb +582 -0
  30. data/lib/roma/routing/cb_rttable.rb +326 -0
  31. data/lib/roma/routing/merkle_tree.rb +54 -0
  32. data/lib/roma/routing/rttable.rb +148 -0
  33. data/lib/roma/stats.rb +112 -0
  34. data/lib/roma/storage/basic_storage.rb +510 -0
  35. data/lib/roma/storage/dbm_storage.rb +80 -0
  36. data/lib/roma/storage/dummy_storage.rb +44 -0
  37. data/lib/roma/storage/rh_storage.rb +35 -0
  38. data/lib/roma/storage/sqlite3_storage.rb +73 -0
  39. data/lib/roma/storage/tc_storage.rb +133 -0
  40. data/lib/roma/tools/mkrecent.rb +138 -0
  41. data/lib/roma/tools/mkroute.rb +52 -0
  42. data/lib/roma/tools/recoverlost.rb +9 -0
  43. data/lib/roma/tools/recoverlost_alist.rb +9 -0
  44. data/lib/roma/tools/recoverlost_lib.rb +217 -0
  45. data/lib/roma/tools/sample_watcher.rb +38 -0
  46. data/lib/roma/tools/sample_watcher2.rb +38 -0
  47. data/lib/roma/tools/simple_bench.rb +57 -0
  48. data/lib/roma/tools/ssroute.rb +23 -0
  49. data/lib/roma/tools/tribunus.rb +299 -0
  50. data/lib/roma/version.rb +4 -0
  51. data/lib/roma/write_behind.rb +179 -0
  52. data/test/rcirb.rb +16 -0
  53. data/test/roma-test-utils.rb +65 -0
  54. data/test/run-test.rb +16 -0
  55. data/test/t_cpdata.rb +277 -0
  56. data/test/t_listplugin.rb +592 -0
  57. data/test/t_rclient.rb +318 -0
  58. data/test/t_routing_data.rb +100 -0
  59. data/test/t_storage.rb +644 -0
  60. data/test/t_writebehind.rb +200 -0
  61. metadata +134 -0
@@ -0,0 +1,510 @@
1
+ require 'digest/sha1'
2
+
3
+ module Roma
4
+ module Storage
5
+
6
+ class BasicStorage
7
+
8
+ attr :hdb
9
+ attr :hdiv
10
+ attr :ext_name
11
+
12
+ attr_reader :error_message
13
+
14
+ attr_writer :vn_list
15
+ attr_writer :storage_path
16
+ attr_writer :divnum
17
+ attr_writer :option
18
+
19
+ attr_accessor :each_vn_dump_sleep
20
+ attr_accessor :each_vn_dump_sleep_count
21
+ attr_accessor :each_clean_up_sleep
22
+ attr_accessor :logic_clock_expire
23
+
24
+ def initialize
25
+ @hdb = []
26
+ @hdiv = Hash.new(0)
27
+
28
+ @ext_name = 'db'
29
+
30
+ @divnum = 10
31
+
32
+ @each_vn_dump_sleep = 0.001
33
+ @each_vn_dump_sleep_count = 100
34
+ @each_clean_up_sleep = 0.01
35
+ @logic_clock_expire = 300
36
+ end
37
+
38
+ def get_stat
39
+ ret = {}
40
+ ret['storage.storage_path'] = File.expand_path(@storage_path)
41
+ ret['storage.divnum'] = @divnum
42
+ ret['storage.option'] = @option
43
+ ret['storage.each_vn_dump_sleep'] = @each_vn_dump_sleep
44
+ ret['storage.each_vn_dump_sleep_count'] = @each_vn_dump_sleep_count
45
+ ret['storage.each_clean_up_sleep'] = @each_clean_up_sleep
46
+ ret['storage.logic_clock_expire'] = @logic_clock_expire
47
+ ret
48
+ end
49
+
50
+ # Compare this clock with the specified.
51
+ #
52
+ # -1, 0 or 1 as +clk1+ is numerically less than, equal to,
53
+ # or greater than the +clk2+ given as the parameter.
54
+ #
55
+ # logical clock space is a 32bit ring.
56
+ def cmp_clk(clk1, clk2)
57
+ if (clk1-clk2).abs < 0x80000000 # 1<<31
58
+ clk1 <=> clk2
59
+ else
60
+ clk2 <=> clk1
61
+ end
62
+ end
63
+ private :cmp_clk
64
+
65
+ def create_div_hash
66
+ @vn_list.each{ |vn|
67
+ @hdiv[vn] = Digest::SHA1.hexdigest(vn.to_s).hex % @divnum
68
+ }
69
+ end
70
+ protected :create_div_hash
71
+
72
+ def opendb
73
+ create_div_hash
74
+ path = ''
75
+ @storage_path.split('/').each{|p|
76
+ if p.length==0
77
+ path = '/'
78
+ next
79
+ end
80
+ path << p
81
+ Dir::mkdir(path) unless File.exist?(path)
82
+ path << '/'
83
+ }
84
+ @divnum.times{ |i|
85
+ @hdb[i] = open_db("#{@storage_path}/#{i}.#{@ext_name}")
86
+ }
87
+ end
88
+
89
+ def closedb
90
+ buf = @hdb; @hdb = []
91
+ buf.each{ |hdb| close_db(hdb) }
92
+ end
93
+
94
+
95
+ # [ 0.. 3] vn
96
+ # [ 4.. 7] physical clock (unix time)
97
+ # [ 8..11] logical clock
98
+ # [12..15] exptime(unix time)
99
+ # [16.. ] value data
100
+
101
+ PACK_HEADER_TEMPLATE='NNNN'
102
+ PACK_TEMPLATE=PACK_HEADER_TEMPLATE+'a*'
103
+ def pack_header(vn, physical_clock, logical_clock, expire)
104
+ [vn,physical_clock, logical_clock, expire].pack(PACK_HEADER_TEMPLATE)
105
+ end
106
+ def unpack_header(str)
107
+ str.unpack(PACK_HEADER_TEMPLATE)
108
+ end
109
+ def pack_data(vn, physical_clock, logical_clock, expire,value)
110
+ [vn,physical_clock, logical_clock, expire, value].pack(PACK_TEMPLATE)
111
+ end
112
+ def unpack_data(str)
113
+ str.unpack(PACK_TEMPLATE)
114
+ end
115
+ private :pack_header, :unpack_header, :pack_data, :unpack_data
116
+
117
+
118
+ def get_context(vn, k, d)
119
+ buf = @hdb[@hdiv[vn]].get(k)
120
+ return nil unless buf
121
+ unpack_header(buf)
122
+ end
123
+
124
+ def cas(vn, k, d, clk, expt, v)
125
+ buf = @hdb[@hdiv[vn]].get(k)
126
+ return :not_found unless buf
127
+ t = Time.now.to_i
128
+ data = unpack_data(buf)
129
+ return :not_found if t > data[3]
130
+ return :exists if clk != data[2]
131
+ clk = (data[2] + 1) & 0xffffffff
132
+ ret = [vn, t, clk, expt, v]
133
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
134
+ nil
135
+ end
136
+
137
+ def rset(vn, k, d, clk, expt, v)
138
+ buf = @hdb[@hdiv[vn]].get(k)
139
+ t = Time.now.to_i
140
+ if buf
141
+ data = unpack_data(buf)
142
+ if t - data[1] < @logic_clock_expire && cmp_clk(clk,data[2]) <= 0
143
+ @error_message = "error:#{t-data[1]} < #{@logic_clock_expire} && cmp_clk(#{clk},#{data[2]})<=0"
144
+ return nil
145
+ end
146
+ end
147
+
148
+ ret = [vn, t, clk, expt, v]
149
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
150
+ @error_message = "error:put"
151
+ nil
152
+ end
153
+
154
+ def set(vn, k, d, expt, v)
155
+ buf = @hdb[@hdiv[vn]].get(k)
156
+ clk = 0
157
+ if buf
158
+ data = unpack_data(buf)
159
+ clk = (data[2] + 1) & 0xffffffff
160
+ end
161
+
162
+ ret = [vn, Time.now.to_i, clk, expt, v]
163
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
164
+ nil
165
+ end
166
+
167
+ def add(vn, k, d, expt, v)
168
+ buf = @hdb[@hdiv[vn]].get(k)
169
+ clk = 0
170
+ if buf
171
+ vn, t, clk, expt2, v2 = unpack_data(buf)
172
+ return nil if Time.now.to_i <= expt2
173
+ clk = (clk + 1) & 0xffffffff
174
+ end
175
+
176
+ # not exist
177
+ ret = [vn, Time.now.to_i, clk, expt, v]
178
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
179
+ nil
180
+ end
181
+
182
+ def replace(vn, k, d, expt, v)
183
+ buf = @hdb[@hdiv[vn]].get(k)
184
+ return nil unless buf
185
+
186
+ # buf != nil
187
+ vn, t, clk, expt2, v2 = unpack_data(buf)
188
+ return nil if Time.now.to_i > expt2
189
+ clk = (clk + 1) & 0xffffffff
190
+
191
+ ret = [vn, Time.now.to_i, clk, expt, v]
192
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
193
+ nil
194
+ end
195
+
196
+ def append(vn, k, d, expt, v)
197
+ buf = @hdb[@hdiv[vn]].get(k)
198
+ return nil unless buf
199
+
200
+ # buf != nil
201
+ vn, t, clk, expt2, v2 = unpack_data(buf)
202
+ return nil if Time.now.to_i > expt2
203
+ clk = (clk + 1) & 0xffffffff
204
+
205
+ ret = [vn, Time.now.to_i, clk, expt, v2 + v]
206
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
207
+ nil
208
+ end
209
+
210
+ def prepend(vn, k, d, expt, v)
211
+ buf = @hdb[@hdiv[vn]].get(k)
212
+ return nil unless buf
213
+
214
+ # buf != nil
215
+ vn, t, clk, expt2, v2 = unpack_data(buf)
216
+ return nil if Time.now.to_i > expt2
217
+ clk = (clk + 1) & 0xffffffff
218
+
219
+ ret = [vn, Time.now.to_i, clk, expt, v + v2]
220
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
221
+ nil
222
+ end
223
+
224
+ def get(vn, k, d)
225
+ buf = @hdb[@hdiv[vn]].get(k)
226
+ return nil unless buf
227
+ vn, t, clk, expt, v = unpack_data(buf)
228
+
229
+ return nil if Time.now.to_i > expt
230
+ v
231
+ end
232
+
233
+ def get_raw(vn, k, d)
234
+ buf = @hdb[@hdiv[vn]].get(k)
235
+ return nil unless buf
236
+
237
+ unpack_data(buf)
238
+ end
239
+
240
+ def rdelete(vn, k, d, clk)
241
+ buf = @hdb[@hdiv[vn]].get(k)
242
+ t = Time.now.to_i
243
+ if buf
244
+ data = unpack_header(buf)
245
+ if t - data[1] < @logic_clock_expire && cmp_clk(clk,data[2]) <= 0
246
+ @error_message = "error:#{t-data[1]} < #{@logic_clock_expire} && cmp_clk(#{clk},#{data[2]})<=0"
247
+ return nil
248
+ end
249
+ end
250
+
251
+ # [ 0.. 3] vn
252
+ # [ 4.. 7] physical clock(unix time)
253
+ # [ 8..11] logical clock
254
+ # [12..15] exptime(unix time) => 0
255
+ ret = [vn, t, clk, 0]
256
+ if @hdb[@hdiv[vn]].put(k,pack_header(*ret))
257
+ return ret
258
+ else
259
+ return nil
260
+ end
261
+ end
262
+
263
+ def delete(vn, k, d)
264
+ buf = @hdb[@hdiv[vn]].get(k)
265
+ v = ret = nil
266
+ clk = 0
267
+ if buf
268
+ vn, t, clk, expt, v2 = unpack_data(buf)
269
+ return :deletemark if expt == 0
270
+ clk = (clk + 1) & 0xffffffff
271
+ v = v2 if v2 && v2.length != 0 && Time.now.to_i <= expt
272
+ end
273
+
274
+ # [ 0.. 3] vn
275
+ # [ 4.. 7] physical clock(unix time)
276
+ # [ 8..11] logical clock
277
+ # [12..15] exptime(unix time) => 0
278
+ ret = [vn, Time.now.to_i, clk, 0, v]
279
+ if @hdb[@hdiv[vn]].put(k,pack_header(*ret[0..-2]))
280
+ return ret
281
+ else
282
+ return nil
283
+ end
284
+ end
285
+
286
+ def out(vn, k, d)
287
+ @hdb[@hdiv[vn]].out(k)
288
+ end
289
+
290
+ def incr(vn, k, d, v)
291
+ buf = @hdb[@hdiv[vn]].get(k)
292
+ return nil unless buf
293
+
294
+ # buf != nil
295
+ vn, t, clk, expt2, v2 = unpack_data(buf)
296
+ return nil if Time.now.to_i > expt2
297
+ clk = (clk + 1) & 0xffffffff
298
+
299
+ v = (v2.to_i + v)
300
+ v = 0 if v < 0
301
+ v = v & 0xffffffffffffffff
302
+
303
+ ret = [vn, Time.now.to_i, clk, expt2, v.to_s]
304
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
305
+ nil
306
+ end
307
+
308
+ def decr(vn, k, d, v)
309
+ buf = @hdb[@hdiv[vn]].get(k)
310
+ return nil unless buf
311
+
312
+ # buf != nil
313
+ vn, t, clk, expt2, v2 = unpack_data(buf)
314
+ return nil if Time.now.to_i > expt2
315
+ clk = (clk + 1) & 0xffffffff
316
+
317
+ v = (v2.to_i - v)
318
+ v = 0 if v < 0
319
+ v = v & 0xffffffffffffffff
320
+
321
+ ret = [vn, Time.now.to_i, clk, expt2, v.to_s]
322
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
323
+ nil
324
+ end
325
+
326
+ def true_length
327
+ res = 0
328
+ @hdb.each{ |hdb| res += hdb.rnum }
329
+ res
330
+ end
331
+
332
+ def add_vnode(vn)
333
+ end
334
+
335
+ def del_vnode(vn)
336
+ buf = get_vnode_hash(vn)
337
+ buf.each_key{ |k| @hdb[@hdiv[vn]].out(k) }
338
+ end
339
+
340
+ def clean_up(t,unit_test_flg=nil)
341
+ n = 0
342
+ nt = Time.now.to_i
343
+ @hdb.each_index{ |i|
344
+ delkey = []
345
+ @hdb[i].each{ |k, v|
346
+ vn, last, clk, expt = unpack_header(v)
347
+ if nt > expt && t > last
348
+ n += 1
349
+ #delkey << k
350
+ @hdb[i].out(k)
351
+ end
352
+ if unit_test_flg
353
+ closedb
354
+ end
355
+ sleep @each_clean_up_sleep
356
+ }
357
+ #delkey.each{ |k| @hdb[i].out(k) }
358
+ }
359
+ n
360
+ rescue => e
361
+ raise NoMethodError(e.message)
362
+ end
363
+
364
+ def each_clean_up(t, vnhash)
365
+ @do_clean_up = true
366
+ nt = Time.now.to_i
367
+ @hdb.each{ |hdb|
368
+ hdb.each{ |k, v|
369
+ return unless @do_clean_up
370
+ vn, last, clk, expt = unpack_header(v)
371
+ vn_stat = vnhash[vn]
372
+ if vn_stat == :primary && ( (expt != 0 && nt > expt) || (expt == 0 && t > last) )
373
+ yield k, vn
374
+ hdb.out(k) if hdb.get(k) == v
375
+ elsif vn_stat == nil && t > last
376
+ yield k, vn
377
+ hdb.out(k) if hdb.get(k) == v
378
+ end
379
+ sleep @each_clean_up_sleep
380
+ }
381
+ }
382
+ end
383
+
384
+ def stop_clean_up
385
+ @do_clean_up = false
386
+ end
387
+
388
+ def load(dmp)
389
+ n = 0
390
+ h = Marshal.load(dmp)
391
+ h.each_pair{ |k, v|
392
+ # remort data
393
+ r_vn, r_last, r_clk, r_expt = unpack_header(v)
394
+ raise "An invalid vnode number is include.key=#{k} vn=#{r_vn}" unless @hdiv.key?(r_vn)
395
+ local = @hdb[@hdiv[r_vn]].get(k)
396
+ if local == nil
397
+ n += 1
398
+ @hdb[@hdiv[r_vn]].put(k, v)
399
+ else
400
+ # local data
401
+ l_vn, l_last, l_clk, l_expt = unpack_data(local)
402
+ if r_last - l_last < @logic_clock_expire && cmp_clk(r_clk,l_clk) <= 0
403
+ else # remort is newer.
404
+ n += 1
405
+ @hdb[@hdiv[r_vn]].put(k, v)
406
+ end
407
+ end
408
+ sleep @each_vn_dump_sleep
409
+ }
410
+ n
411
+ end
412
+
413
+ def load_stream_dump(vn, last, clk, expt, k, v)
414
+ buf = @hdb[@hdiv[vn]].get(k)
415
+ if buf
416
+ data = unpack_header(buf)
417
+ if last - data[1] < @logic_clock_expire && cmp_clk(clk,data[2]) <= 0
418
+ return nil
419
+ end
420
+ end
421
+
422
+ ret = [vn, last, clk, expt, v]
423
+ if expt == 0
424
+ return ret if @hdb[@hdiv[vn]].put(k, pack_header(*ret[0..3]))
425
+ else
426
+ return ret if @hdb[@hdiv[vn]].put(k, pack_data(*ret))
427
+ end
428
+ nil
429
+ end
430
+
431
+ # Returns the vnode dump.
432
+ def dump(vn)
433
+ buf = get_vnode_hash(vn)
434
+ return nil if buf.length == 0
435
+ Marshal.dump(buf)
436
+ end
437
+
438
+ def dump_file(path,except_vnh = nil)
439
+ pbuf = ''
440
+ path.split('/').each{|p|
441
+ pbuf << p
442
+ begin
443
+ Dir::mkdir(pbuf) unless File.exist?(pbuf)
444
+ rescue
445
+ end
446
+ pbuf << '/'
447
+ }
448
+ @divnum.times{|i|
449
+ f = open("#{path}/#{i}.dump","wb")
450
+ each_hdb_dump(i,except_vnh){|data| f.write(data) }
451
+ f.close
452
+ }
453
+ open("#{path}/eod","w"){|f|
454
+ f.puts Time.now
455
+ }
456
+ end
457
+
458
+ def each_vn_dump(target_vn)
459
+ count = 0
460
+ @divnum.times{|i|
461
+ tn = Time.now.to_i
462
+ @hdb[i].each{|k,v|
463
+ vn, last, clk, expt, val = unpack_data(v)
464
+ if vn != target_vn || (expt != 0 && tn > expt)
465
+ count += 1
466
+ sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
467
+ next
468
+ end
469
+ if val
470
+ yield [vn, last, clk, expt, k.length, k, val.length, val].pack("NNNNNa#{k.length}Na#{val.length}")
471
+ else
472
+ yield [vn, last, clk, expt, k.length, k, 0].pack("NNNNNa#{k.length}N")
473
+ end
474
+ }
475
+ }
476
+ end
477
+
478
+ def each_hdb_dump(i,except_vnh = nil)
479
+ count = 0
480
+ @hdb[i].each{|k,v|
481
+ vn, last, clk, expt, val = unpack_data(v)
482
+ if except_vnh && except_vnh.key?(vn) || Time.now.to_i > expt
483
+ count += 1
484
+ sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
485
+ else
486
+ yield [vn, last, clk, expt, k.length, k, val.length, val].pack("NNNNNa#{k.length}Na#{val.length}")
487
+ sleep @each_vn_dump_sleep
488
+ end
489
+ }
490
+ end
491
+ private :each_hdb_dump
492
+
493
+ # Create vnode dump.
494
+ def get_vnode_hash(vn)
495
+ buf = {}
496
+ count = 0
497
+ @hdb[@hdiv[vn]].each{ |k, v|
498
+ count += 1
499
+ sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
500
+ dat = unpack_data(v) #v.unpack('NNNN')
501
+ buf[k] = v if dat[0] == vn
502
+ }
503
+ return buf
504
+ end
505
+ private :get_vnode_hash
506
+
507
+ end # class BasicStorage
508
+
509
+ end # module Storage
510
+ end # module Roma
@@ -0,0 +1,80 @@
1
+ require 'gdbm'
2
+ require 'roma/storage/basic_storage'
3
+
4
+ module Roma
5
+ module Storage
6
+
7
+ module GDBM_Ext
8
+ def put(k,v); self[k] = v; end
9
+ def get(k); self[k]; end
10
+ def out(k); delete(k); end
11
+ def rnum; length; end
12
+ end
13
+
14
+ class DbmStorage < BasicStorage
15
+
16
+ def initialize
17
+ super
18
+ @ext_name = 'dbm'
19
+ end
20
+
21
+ def clean_up(t,unit_test_flg=nil)
22
+ n = 0
23
+ nt = Time.now.to_i
24
+ @hdb.each_index{ |i|
25
+ delkey = []
26
+ @hdb[i].each{ |k, v|
27
+ vn, last, clk, expt = unpack_header(v)
28
+ if nt > expt && t > last
29
+ n += 1
30
+ delkey << k
31
+ end
32
+ if unit_test_flg
33
+ closedb
34
+ end
35
+ }
36
+ delkey.each{ |k| @hdb[i].out(k) }
37
+ }
38
+ n
39
+ rescue => e
40
+ raise NoMethodError(e.message)
41
+ end
42
+
43
+ def each_clean_up(t, vnhash)
44
+ @do_clean_up = true
45
+ nt = Time.now.to_i
46
+ @hdb.each{ |hdb|
47
+ delkey = []
48
+ hdb.each{ |k, v|
49
+ return unless @do_clean_up
50
+ vn, last, clk, expt = unpack_header(v)
51
+ vn_stat = vnhash[vn]
52
+ if vn_stat == :primary && ( (expt != 0 && nt > expt) || (expt == 0 && t > last) )
53
+ delkey << [vn, k, v]
54
+ elsif vn_stat == nil && t > last
55
+ delkey << [vn, k, v]
56
+ end
57
+ sleep @each_clean_up_sleep
58
+ }
59
+ delkey.each{ |vn, k, v|
60
+ yield k, vn
61
+ hdb.out(k) if hdb.get(k) == v
62
+ }
63
+ }
64
+ end
65
+
66
+ private
67
+
68
+ def open_db(fname)
69
+ hdb = GDBM::open(fname,0666)
70
+ raise RuntimeError.new("dbm open error.") unless hdb
71
+ hdb.extend(Roma::Storage::GDBM_Ext)
72
+ return hdb
73
+ end
74
+
75
+ def close_db(hdb); hdb.close; end
76
+
77
+ end # class DbmStorage
78
+
79
+ end # module Storage
80
+ end # module Roma
@@ -0,0 +1,44 @@
1
+
2
+ module Roma
3
+ module Storage
4
+
5
+ class DummyStorage
6
+
7
+ def initialize; end
8
+ def init(*args); end
9
+ def opendb(fname,divnum); end
10
+ def closedb; end
11
+ def get_context(vn, k, d) nil; end
12
+ def rset(vn, k, d, lclock, exptime, v); end
13
+ def set(vn, k, d, exptime, v); end
14
+ def add(vn, k, d, exptime, v); end
15
+ def replace(vn, k, d, exptime, v); end
16
+ def append(vn, k, d, exptime, v); end
17
+ def prepend(vn, k, d, exptime, v); end
18
+ def get(vn,k,d); 'dummy'; end
19
+ def rdelete(vn,k,d,lclock); end
20
+ def delete(vn,k,d); end
21
+ def incr(vn, k, d, v); end
22
+ def decr(vn, k, d, v); end
23
+ def true_length; 100; end
24
+ def add_vnode(vn); end
25
+ def del_vnode(vn); end
26
+ def clean_up(t); end
27
+
28
+ def load(dmp); 10 end
29
+
30
+ # Returns the vnode dump.
31
+ def dump(vn)
32
+ Marshal.dump(get_vnode_hash(vn))
33
+ end
34
+
35
+ private
36
+
37
+ # Create vnode dump.
38
+ def get_vnode_hash(vn)
39
+ {'dummy'=>'dummy'}
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,35 @@
1
+ require 'roma/storage/basic_storage'
2
+
3
+ module Roma
4
+ module Storage
5
+
6
+ module RH_Ext
7
+ def put(k,v); self[k] = v; end
8
+ def get(k); self[k]; end
9
+ def out(k); delete(k); end
10
+ def rnum; length; end
11
+ end
12
+
13
+ class RubyHashStorage < BasicStorage
14
+
15
+ def opendb
16
+ create_div_hash
17
+ @divnum.times{ |i|
18
+ @hdb[i] = open_db(nil)
19
+ }
20
+ end
21
+
22
+ private
23
+
24
+ def open_db(fname)
25
+ hdb = {}
26
+ hdb.extend(Roma::Storage::RH_Ext)
27
+ return hdb
28
+ end
29
+
30
+ def close_db(hdb); end
31
+
32
+ end # class RubyHashStorage
33
+
34
+ end # module Storage
35
+ end # module Roma