roma 0.8.2
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.
- data/LICENSE.rdoc +675 -0
- data/README.rdoc +0 -0
- data/Rakefile +70 -0
- data/bin/mkrecent +7 -0
- data/bin/mkroute +7 -0
- data/bin/recoverlost +8 -0
- data/bin/recoverlost_alist +8 -0
- data/bin/romad +7 -0
- data/bin/sample_watcher +8 -0
- data/bin/sample_watcher2 +8 -0
- data/bin/simple_bench +8 -0
- data/bin/ssroute +7 -0
- data/bin/tribunus +7 -0
- data/lib/roma/async_process.rb +696 -0
- data/lib/roma/command/bg_command_receiver.rb +188 -0
- data/lib/roma/command/mh_command_receiver.rb +117 -0
- data/lib/roma/command/receiver.rb +287 -0
- data/lib/roma/command/rt_command_receiver.rb +147 -0
- data/lib/roma/command/st_command_receiver.rb +564 -0
- data/lib/roma/command/util_command_receiver.rb +67 -0
- data/lib/roma/command/vn_command_receiver.rb +143 -0
- data/lib/roma/command_plugin.rb +11 -0
- data/lib/roma/config.rb +64 -0
- data/lib/roma/event/con_pool.rb +140 -0
- data/lib/roma/event/handler.rb +159 -0
- data/lib/roma/plugin/plugin_alist.rb +1572 -0
- data/lib/roma/plugin/plugin_debug.rb +19 -0
- data/lib/roma/plugin/plugin_test.rb +14 -0
- data/lib/roma/romad.rb +582 -0
- data/lib/roma/routing/cb_rttable.rb +326 -0
- data/lib/roma/routing/merkle_tree.rb +54 -0
- data/lib/roma/routing/rttable.rb +148 -0
- data/lib/roma/stats.rb +112 -0
- data/lib/roma/storage/basic_storage.rb +510 -0
- data/lib/roma/storage/dbm_storage.rb +80 -0
- data/lib/roma/storage/dummy_storage.rb +44 -0
- data/lib/roma/storage/rh_storage.rb +35 -0
- data/lib/roma/storage/sqlite3_storage.rb +73 -0
- data/lib/roma/storage/tc_storage.rb +133 -0
- data/lib/roma/tools/mkrecent.rb +138 -0
- data/lib/roma/tools/mkroute.rb +52 -0
- data/lib/roma/tools/recoverlost.rb +9 -0
- data/lib/roma/tools/recoverlost_alist.rb +9 -0
- data/lib/roma/tools/recoverlost_lib.rb +217 -0
- data/lib/roma/tools/sample_watcher.rb +38 -0
- data/lib/roma/tools/sample_watcher2.rb +38 -0
- data/lib/roma/tools/simple_bench.rb +57 -0
- data/lib/roma/tools/ssroute.rb +23 -0
- data/lib/roma/tools/tribunus.rb +299 -0
- data/lib/roma/version.rb +4 -0
- data/lib/roma/write_behind.rb +179 -0
- data/test/rcirb.rb +16 -0
- data/test/roma-test-utils.rb +65 -0
- data/test/run-test.rb +16 -0
- data/test/t_cpdata.rb +277 -0
- data/test/t_listplugin.rb +592 -0
- data/test/t_rclient.rb +318 -0
- data/test/t_routing_data.rb +100 -0
- data/test/t_storage.rb +644 -0
- data/test/t_writebehind.rb +200 -0
- 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
|