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.
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,326 @@
1
+ require 'roma/routing/rttable'
2
+
3
+ module Roma
4
+ module Routing
5
+
6
+ class ChurnbasedRoutingTable < RoutingTable
7
+
8
+ attr :fname
9
+ attr :log_fd
10
+ attr :log_name
11
+ attr :trans # transaction
12
+ attr :leave_proc
13
+ attr :lost_proc
14
+ attr_accessor :lost_action
15
+ attr_reader :version_of_nodes
16
+ attr_reader :min_version
17
+
18
+ def initialize(rd,fname)
19
+ super(rd)
20
+ @rd.nodes.sort!
21
+ @trans={}
22
+ @fname=fname
23
+ @leave_proc=nil
24
+ @lost_proc=nil
25
+ @lost_action=:no_action
26
+ @enabled_failover=false
27
+ @lock = Mutex.new
28
+ @version_of_nodes = Hash.new(0)
29
+ @min_version = nil
30
+ open_log
31
+ end
32
+
33
+ def get_stat(ap)
34
+ ret = super(ap)
35
+ ret['routing.lost_action'] = @lost_action.to_s
36
+ ret['routing.version_of_nodes'] = @version_of_nodes.inspect
37
+ ret['routing.min_version'] = @min_version
38
+ ret
39
+ end
40
+
41
+ def set_version(nid,ver)
42
+ @version_of_nodes[nid] = ver
43
+ if @min_version == nil || @min_version > ver
44
+ @min_version = ver
45
+ end
46
+ end
47
+
48
+ def find_min_version
49
+ ret = 0xffffff
50
+ @version_of_nodes.each_value{|ver| ret = ver if ret > ver}
51
+ ret
52
+ end
53
+
54
+ def set_leave_proc(&block)
55
+ @leave_proc=block
56
+ end
57
+
58
+ def set_lost_proc(&block)
59
+ @lost_proc=block
60
+ end
61
+
62
+ def open_log
63
+ log_list=@rd.get_file_list(@fname)
64
+ if log_list.length==0
65
+ @log_name="#{@fname}.1"
66
+ else
67
+ if File::stat("#{@fname}.#{log_list.last[0]}").size == 0
68
+ @log_name="#{@fname}.#{log_list.last[0]}"
69
+ else
70
+ @log_name="#{@fname}.#{log_list.last[0]+1}"
71
+ end
72
+ end
73
+ @log_fd=File.open(@log_name,"a")
74
+ end
75
+
76
+ def write_log_setroute(vn, clk, nids)
77
+ log="setroute #{vn} #{clk}"
78
+ nids.each{ |nid| log << " #{nid}" }
79
+ write_log(log)
80
+ end
81
+
82
+ def write_log(line)
83
+ # log rotation
84
+ if File::stat(@log_name).size > 1000 * 1024
85
+ close_log
86
+ open_log
87
+ end
88
+ t = Time.now
89
+ tstr = "#{t.strftime('%Y-%m-%dT%H:%M:%S')}.#{t.usec}"
90
+ @log_fd.write("#{tstr} #{line}\n")
91
+ @log_fd.flush
92
+ end
93
+
94
+ def close_log
95
+ @log_fd.close
96
+ end
97
+
98
+ def can_i_recover?
99
+ @rd.nodes.length >= @rd.rn
100
+ end
101
+
102
+ # Retuens the list of losted-data vnode newer than argument time.
103
+ def search_lost_vnodes(t)
104
+ ret = []
105
+ @rd.each_log_all(@fname){|log_t,line|
106
+ next if t > log_t
107
+ s = line.split(/ /)
108
+ if s[0] == 'setroute' && s.length == 3
109
+ # vnode has a no pnode. therefor this vnode was lost.
110
+ ret << s[1].to_i
111
+ end
112
+ }
113
+ ret
114
+ end
115
+
116
+ # select a vnodes where short of redundancy.
117
+ def select_a_short_vnodes(exclued_nodes)
118
+ ret = []
119
+ @rd.v_idx.each_pair{|vn, nids|
120
+ if nids.length < @rd.rn && list_include?(nids,exclued_nodes) == false
121
+ ret << [vn,nids]
122
+ end
123
+ }
124
+ ret
125
+ end
126
+
127
+ # vnode sampling without +without_nodes+
128
+ def sample_vnode(without_nodes)
129
+ short_idx = {}
130
+ idx = {}
131
+ @rd.v_idx.each_pair{|vn, nids|
132
+ unless list_include?(nids, without_nodes)
133
+ idx[vn] = nids
134
+ short_idx[vn] = nids if nids.length < @rd.rn
135
+ end
136
+ }
137
+ idx = short_idx if short_idx.length > 0
138
+
139
+ ks = idx.keys
140
+ return nil if ks.length == 0
141
+ vn = ks[rand(ks.length)]
142
+ nids = idx[vn]
143
+ [vn, nids]
144
+ end
145
+
146
+ def list_include?(list,nodes)
147
+ nodes.each{|nid|
148
+ return true if list.include?(nid)
149
+ }
150
+ false
151
+ end
152
+ private :list_include?
153
+
154
+ def set_route(vn, clk, nids)
155
+ return "#{vn} is not found." unless @rd.v_idx.key?(vn)
156
+ @lock.synchronize {
157
+ return "It's old table." if @rd.v_clk[vn] > clk
158
+ nids.each{ |nid|
159
+ add_node(nid) unless @rd.nodes.include?(nid)
160
+ }
161
+ @rd.v_idx[vn] = nids.clone
162
+ clk += 1
163
+ @rd.v_clk[vn] = clk
164
+ @mtree.set(vn, nids)
165
+ write_log_setroute(vn, clk, nids)
166
+ return clk
167
+ }
168
+ end
169
+
170
+ def add_node(nid)
171
+ unless @rd.nodes.include?(nid)
172
+ @rd.nodes << nid
173
+ @rd.nodes.sort!
174
+ write_log("join #{nid}")
175
+ end
176
+ end
177
+
178
+ def enabled_failover=(b)
179
+ @enabled_failover=b
180
+ @fail_cnt.clear
181
+ end
182
+
183
+ def enabled_failover
184
+ @enabled_failover
185
+ end
186
+
187
+ def leave(nid)
188
+ unless @enabled_failover
189
+ return
190
+ end
191
+ return unless @rd.nodes.include?(nid)
192
+
193
+ @leave_proc.call(nid) if @leave_proc
194
+ @rd.nodes.delete(nid)
195
+ @version_of_nodes.delete(nid)
196
+ @min_version = find_min_version
197
+
198
+ @log.warn("#{nid} just failed.")
199
+ write_log("leave #{nid}")
200
+
201
+ lost_vnodes=[]
202
+ @lock.synchronize {
203
+ @rd.v_idx.each_pair{ |vn, nids|
204
+ buf = nids.clone
205
+ if buf.delete(nid)
206
+ set_route_and_inc_clk_inside_sync(vn, buf)
207
+ if buf.length == 0
208
+ lost_vnodes << vn
209
+ @log.error("Vnode data is lost.(Vnode=#{vn})")
210
+ end
211
+ end
212
+ }
213
+ }
214
+ if lost_vnodes.length > 0
215
+ @lost_proc.call if @lost_proc
216
+ if @lost_action == :auto_assign
217
+ lost_vnodes.each{ |vn|
218
+ set_route_and_inc_clk_inside_sync( vn, next_alive_vnode(vn) )
219
+ }
220
+ end
221
+ end
222
+ @fail_cnt.delete(nid)
223
+ end
224
+
225
+ def set_route_and_inc_clk_inside_sync(vn, nodes)
226
+ @rd.v_idx[vn] = nodes
227
+ clk = @rd.v_clk[vn] + 1
228
+ @rd.v_clk[vn] = clk
229
+ @mtree.set(vn, nodes)
230
+ write_log_setroute(vn, clk, nodes)
231
+ clk
232
+ end
233
+ private :set_route_and_inc_clk_inside_sync
234
+
235
+ def next_alive_vnode(vn)
236
+ svn = vn
237
+ while( (vn = @rd.next_vnode(vn)) != svn )
238
+ return @rd.v_idx[vn].clone if @rd.v_idx[vn].length != 0
239
+ end
240
+ []
241
+ end
242
+ private :next_alive_vnode
243
+
244
+ def each_vnode
245
+ @rd.v_idx.each_pair{ |k, v| yield(k, v) }
246
+ end
247
+
248
+ def v_idx
249
+ @rd.v_idx.clone
250
+ end
251
+
252
+ def search_nodes_for_write(vn)
253
+ return @trans[vn][0].clone if @trans.key?(vn)
254
+ @rd.v_idx[vn].clone
255
+ rescue
256
+ nil
257
+ end
258
+
259
+ def search_nodes_with_clk(vn)
260
+ @lock.synchronize {
261
+ return [@rd.v_clk[vn], @rd.v_idx[vn].clone]
262
+ }
263
+ rescue
264
+ nil
265
+ end
266
+
267
+ # +vn+: vnode-id
268
+ # +nids+: node-id list
269
+ def transaction(vn, nids)
270
+ return false if @trans.key?(vn)
271
+ @trans[vn]=[nids.clone, Time.now]
272
+ true
273
+ end
274
+
275
+ def commit(vn)
276
+ return false unless @trans.key?(vn)
277
+ @lock.synchronize {
278
+ @rd.v_idx[vn]=@trans[vn][0]
279
+ @trans.delete(vn)
280
+ clk = @rd.v_clk[vn] + 1
281
+ @rd.v_clk[vn] = clk
282
+ @mtree.set(vn, @rd.v_idx[vn])
283
+ write_log_setroute(vn, clk, @rd.v_idx[vn])
284
+ return clk
285
+ }
286
+ end
287
+
288
+ def rollback(vn)
289
+ @trans.delete(vn)
290
+ end
291
+
292
+ # +sec+: elapsed-time
293
+ def delete_old_trans(sec=3600)
294
+ @trans.delete_if{|vn,val| val[1] < Time.now-sec }
295
+ end
296
+
297
+ # Returns the status of vnode balance.
298
+ # +ap+: my address_port string(ex."roma0_11211")
299
+ def vnode_balance(ap)
300
+ # amount of primary at node = amount of vnode / amount of node
301
+ n = (2**div_bits) / nodes.length
302
+
303
+ pcount = scount = 0
304
+ @rd.v_idx.each_pair{ |vn, nids|
305
+ next if nids == nil or nids.length == 0
306
+ if nids[0] == ap
307
+ pcount += 1
308
+ elsif nids.include?(ap)
309
+ scount += 1
310
+ end
311
+ }
312
+
313
+ @log.debug("#{__FILE__}:#{__LINE__}:n=#{n} pcount=#{pcount} scount=#{scount}")
314
+
315
+ if pcount > n*1.1
316
+ return :over
317
+ elsif pcount < n*0.9
318
+ return :less
319
+ end
320
+ :even
321
+ end
322
+
323
+ end # class ChurnbasedRoutingTable
324
+
325
+ end # module Routing
326
+ end # module Roma
@@ -0,0 +1,54 @@
1
+ require 'digest/sha1'
2
+
3
+ module Roma
4
+ module Routing
5
+
6
+ class MerkleTree
7
+
8
+ attr :tree
9
+ attr :div_bits
10
+ attr :dgst_bits
11
+
12
+ def initialize(dgst_bits,div_bits)
13
+ @tree = {}
14
+ @dgst_bits = dgst_bits
15
+ @div_bits = div_bits
16
+ create_tree_instance('0')
17
+ end
18
+
19
+ def set(vn,nodes)
20
+ id = '0' + (vn >> (@dgst_bits-@div_bits)).to_s(2).rjust(@div_bits,'0')
21
+ @tree[id] = Digest::SHA1.hexdigest(nodes.to_s)
22
+ update(parent(id))
23
+ end
24
+
25
+ def get(id)
26
+ @tree[id]
27
+ end
28
+
29
+ def to_vn(id)
30
+ id[1,id.length].to_i(2) << (@dgst_bits-@div_bits)
31
+ end
32
+
33
+ private
34
+
35
+ def create_tree_instance(id)
36
+ @tree[id] = 0
37
+ return if id.length > @div_bits
38
+ create_tree_instance("#{id}0")
39
+ create_tree_instance("#{id}1")
40
+ end
41
+
42
+ def update(id)
43
+ @tree[id] = Digest::SHA1.hexdigest("#{@tree[id+'0']}:#{@tree[id+'1']}")
44
+ update(parent(id)) if id.length != 1
45
+ end
46
+
47
+ def parent(id)
48
+ id.chop
49
+ end
50
+
51
+ end # class MerkleTree
52
+
53
+ end # module Routing
54
+ end # module Roma
@@ -0,0 +1,148 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'roma/logging/rlogger'
3
+ require 'roma/routing/routing_data'
4
+ require 'roma/routing/merkle_tree'
5
+ require 'yaml'
6
+ require 'json'
7
+
8
+ module Roma
9
+ module Routing
10
+
11
+ class RoutingTable
12
+
13
+ attr :rd
14
+ attr :search_mask
15
+ attr :fail_cnt
16
+ attr :mtree
17
+ attr_reader :hbits
18
+ attr_reader :rn
19
+ attr_reader :div_bits
20
+ attr_accessor :fail_cnt_threshold
21
+ attr_accessor :fail_cnt_gap
22
+
23
+ def initialize(rd)
24
+ @log = Roma::Logging::RLogger.instance
25
+ @rd = rd
26
+ @rn = @rd.rn
27
+ @div_bits=@rd.div_bits
28
+ @hbits = 2**@rd.dgst_bits
29
+ @search_mask = @rd.search_mask
30
+ @fail_cnt = Hash.new(0)
31
+ @fail_cnt_threshold = 5
32
+ @fail_cnt_gap = 0
33
+ @fail_time = Time.now
34
+ init_mtree
35
+ end
36
+
37
+ def get_stat(ap)
38
+
39
+ pn = sn = short = lost = 0
40
+ @rd.v_idx.each_pair{|vn, nids|
41
+ if nids == nil || nids.length == 0
42
+ lost += 1
43
+ next
44
+ elsif nids[0] == ap
45
+ pn += 1
46
+ elsif nids.include?(ap)
47
+ sn += 1
48
+ end
49
+ short += 1 if nids.length < @rd.rn
50
+ }
51
+
52
+ ret = {}
53
+ ret['routing.redundant'] = @rn
54
+ ret['routing.nodes.length'] = nodes.length
55
+ ret['routing.nodes'] = nodes.inspect
56
+ ret['routing.dgst_bits'] = @rd.dgst_bits
57
+ ret['routing.div_bits'] = @div_bits
58
+ ret['routing.vnodes.length'] = vnodes.length
59
+ ret['routing.primary'] = pn
60
+ ret['routing.secondary'] = sn
61
+ ret['routing.short_vnodes'] = short
62
+ ret['routing.lost_vnodes'] = lost
63
+ ret['routing.fail_cnt_threshold'] = @fail_cnt_threshold
64
+ ret['routing.fail_cnt_gap'] = @fail_cnt_gap
65
+ ret
66
+ end
67
+
68
+ def init_mtree
69
+ @mtree = MerkleTree.new(@rd.dgst_bits,@rd.div_bits)
70
+ @rd.v_idx.each_pair{ |vn, nids|
71
+ @mtree.set(vn,nids)
72
+ }
73
+ end
74
+
75
+ def nodes
76
+ @rd.nodes.clone
77
+ end
78
+
79
+ def vnodes
80
+ @rd.v_idx.keys
81
+ end
82
+
83
+ # ハッシュ値からvnode idを返す
84
+ def get_vnode_id(d)
85
+ d & @search_mask
86
+ end
87
+
88
+ # vnode があるノードIDの配列を返す
89
+ # +vn+: vnode id
90
+ def search_nodes(vn)
91
+ @rd.v_idx[vn].clone
92
+ rescue
93
+ nil
94
+ end
95
+
96
+ # 離脱ノードを検索リストから削除する
97
+ # +nid+: 離脱ノード
98
+ def leave(nid)
99
+ @rd.nodes.delete(nid)
100
+ # リストから nid を消す
101
+ @rd.v_idx.each_pair{ |vn, nids|
102
+ nids.delete_if{ |nid2| nid2 == nid}
103
+ if nids.length == 0
104
+ @log.error("Vnode data is lost.(Vnode=#{vn})")
105
+ end
106
+ @mtree.set(vn,nids)
107
+ }
108
+ @fail_cnt.delete(nid)
109
+ end
110
+
111
+ def dump
112
+ Marshal.dump(@rd)
113
+ end
114
+
115
+ def dump_yaml
116
+ YAML.dump(@rd)
117
+ end
118
+
119
+ def dump_json
120
+ JSON.generate(
121
+ [{:dgst_bits=>@rd.dgst_bits,:div_bits=>@rd.div_bits,:rn=>@rd.rn},
122
+ @rd.nodes,@rd.v_idx])
123
+ end
124
+
125
+ def proc_failed(nid)
126
+ t = Time.now
127
+ if t - @fail_time > @fail_cnt_gap
128
+ @fail_cnt[nid] += 1
129
+ if @fail_cnt[nid] >= @fail_cnt_threshold
130
+ leave(nid)
131
+ end
132
+ end
133
+ @fail_time = t
134
+ end
135
+
136
+ def proc_succeed(nid)
137
+ @fail_cnt.delete(nid)
138
+ end
139
+
140
+ # v_idx から nodes を再構築する
141
+ def create_nodes_from_v_idx
142
+ @rd.create_nodes_from_v_idx
143
+ end
144
+
145
+ end # class RoutingTable
146
+
147
+ end # module Routing
148
+ end # module Roma
data/lib/roma/stats.rb ADDED
@@ -0,0 +1,112 @@
1
+ require 'singleton'
2
+ require 'roma/config'
3
+
4
+ module Roma
5
+
6
+ class Stats
7
+ include Singleton
8
+
9
+ # command options
10
+ attr_accessor :address, :port
11
+ attr_accessor :daemon
12
+ attr_accessor :join_ap
13
+ attr_accessor :start_with_failover
14
+ attr_accessor :name
15
+ attr_accessor :verbose
16
+ attr_accessor :enabled_repetition_host_in_routing
17
+
18
+ # proc mode
19
+ attr_accessor :enabled_vnodes_balance
20
+
21
+ # proc status
22
+ attr_accessor :run_acquire_vnodes
23
+ attr_accessor :run_recover
24
+ attr_accessor :run_sync_routing
25
+ attr_accessor :run_iterate_storage
26
+ attr_accessor :run_storage_clean_up
27
+ attr_accessor :run_receive_a_vnode
28
+ attr_accessor :run_release
29
+
30
+ # proc param
31
+ attr_accessor :stream_copy_wait_param
32
+
33
+ # compressed redundant param
34
+ attr_accessor :size_of_zredundant
35
+
36
+ # performance counter
37
+ attr_accessor :write_count
38
+ attr_accessor :read_count
39
+ attr_accessor :delete_count
40
+ attr_accessor :out_count
41
+ attr_accessor :out_message_count
42
+ attr_accessor :redundant_count
43
+
44
+ def initialize
45
+ @run_acquire_vnodes = false
46
+ @run_recover = false
47
+ @run_sync_routing = false
48
+ @run_iterate_storage = false
49
+ @run_storage_clean_up = false
50
+ @run_receive_a_vnode = false
51
+ @run_release = false
52
+ @stream_copy_wait_param =
53
+ Roma::Config::DATACOPY_STREAM_COPY_WAIT_PARAM
54
+ @enabled_vnodes_balance = nil
55
+ @write_count = 0
56
+ @read_count = 0
57
+ @delete_count = 0
58
+ @out_count = 0
59
+ @out_message_count = 0
60
+ @redundant_count = 0
61
+ @size_of_zredundant = 0
62
+ end
63
+
64
+ def ap_str
65
+ "#{@address}_#{port}"
66
+ end
67
+
68
+ def get_stat
69
+ ret = {}
70
+ ret['stats.address'] = @address
71
+ ret['stats.port'] = @port
72
+ ret['stats.daemon'] = @daemon
73
+ ret['stats.name'] = @name
74
+ ret['stats.verbose'] = @verbose
75
+ ret['stats.enabled_repetition_host_in_routing'] = @enabled_repetition_host_in_routing
76
+ ret['stats.run_acquire_vnodes'] = @run_acquire_vnodes
77
+ ret['stats.run_recover'] = @run_recover
78
+ ret['stats.run_sync_routing'] = @run_sync_routing
79
+ ret['stats.run_iterate_storage'] = @run_iterate_storage
80
+ ret['stats.run_storage_clean_up'] = @run_storage_clean_up
81
+ ret['stats.run_release'] = @run_release
82
+ ret['stats.stream_copy_wait_param'] = @stream_copy_wait_param
83
+ ret['stats.size_of_zredundant'] = @size_of_zredundant
84
+ ret['stats.write_count'] = @write_count
85
+ ret['stats.read_count'] = @read_count
86
+ ret['stats.delete_count'] = @delete_count
87
+ ret['stats.out_count'] = @out_count
88
+ ret['stats.out_message_count'] = @out_message_count
89
+ ret['stats.redundant_count'] = @redundant_count
90
+ ret
91
+ end
92
+
93
+ def clear_counters
94
+ clear_count(:@write_count)
95
+ clear_count(:@read_count)
96
+ clear_count(:@delete_count)
97
+ clear_count(:@out_count)
98
+ clear_count(:@out_message_count)
99
+ clear_count(:@redundant_count)
100
+ end
101
+
102
+ private
103
+
104
+ def clear_count(var)
105
+ if self.instance_variable_get(var) > 0xffffffff
106
+ self.instance_variable_set(var,0)
107
+ end
108
+ end
109
+
110
+ end # class Stats
111
+
112
+ end # module Roma