higgs 0.1.0
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/ChangeLog +208 -0
- data/LICENSE +26 -0
- data/README +2 -0
- data/Rakefile +75 -0
- data/bin/higgs_backup +67 -0
- data/bin/higgs_dump_index +43 -0
- data/bin/higgs_dump_jlog +42 -0
- data/bin/higgs_verify +37 -0
- data/lib/cgi/session/higgs.rb +72 -0
- data/lib/higgs/block.rb +192 -0
- data/lib/higgs/cache.rb +117 -0
- data/lib/higgs/dbm.rb +55 -0
- data/lib/higgs/exceptions.rb +31 -0
- data/lib/higgs/flock.rb +77 -0
- data/lib/higgs/index.rb +164 -0
- data/lib/higgs/jlog.rb +159 -0
- data/lib/higgs/lock.rb +189 -0
- data/lib/higgs/storage.rb +1086 -0
- data/lib/higgs/store.rb +228 -0
- data/lib/higgs/tar.rb +390 -0
- data/lib/higgs/thread.rb +370 -0
- data/lib/higgs/tman.rb +513 -0
- data/lib/higgs/utils/bman.rb +285 -0
- data/lib/higgs/utils.rb +22 -0
- data/lib/higgs/version.rb +21 -0
- data/lib/higgs.rb +59 -0
- data/misc/cache_bench/cache_bench.rb +43 -0
- data/misc/dbm_bench/.strc +8 -0
- data/misc/dbm_bench/Rakefile +78 -0
- data/misc/dbm_bench/dbm_multi_thread.rb +199 -0
- data/misc/dbm_bench/dbm_rnd_delete.rb +43 -0
- data/misc/dbm_bench/dbm_rnd_read.rb +44 -0
- data/misc/dbm_bench/dbm_rnd_update.rb +44 -0
- data/misc/dbm_bench/dbm_seq_read.rb +45 -0
- data/misc/dbm_bench/dbm_seq_write.rb +44 -0
- data/misc/dbm_bench/st_verify.rb +28 -0
- data/misc/io_bench/cksum_bench.rb +48 -0
- data/misc/io_bench/jlog_bench.rb +71 -0
- data/misc/io_bench/write_bench.rb +128 -0
- data/misc/thread_bench/lock_bench.rb +132 -0
- data/mkrdoc.rb +8 -0
- data/rdoc.yml +13 -0
- data/sample/count.rb +60 -0
- data/sample/dbmtest.rb +38 -0
- data/test/Rakefile +45 -0
- data/test/run.rb +32 -0
- data/test/test_block.rb +163 -0
- data/test/test_cache.rb +214 -0
- data/test/test_cgi_session.rb +142 -0
- data/test/test_flock.rb +162 -0
- data/test/test_index.rb +258 -0
- data/test/test_jlog.rb +180 -0
- data/test/test_lock.rb +320 -0
- data/test/test_online_backup.rb +169 -0
- data/test/test_storage.rb +439 -0
- data/test/test_storage_conf.rb +202 -0
- data/test/test_storage_init_opts.rb +89 -0
- data/test/test_store.rb +211 -0
- data/test/test_tar.rb +432 -0
- data/test/test_thread.rb +541 -0
- data/test/test_tman.rb +875 -0
- data/test/test_tman_init_opts.rb +56 -0
- data/test/test_utils_bman.rb +234 -0
- metadata +115 -0
data/lib/higgs/thread.rb
ADDED
@@ -0,0 +1,370 @@
|
|
1
|
+
# = multi-thread utilities
|
2
|
+
#
|
3
|
+
# Author:: $Author: toki $
|
4
|
+
# Date:: $Date: 2007-09-26 00:20:20 +0900 (Wed, 26 Sep 2007) $
|
5
|
+
# Revision:: $Revision: 559 $
|
6
|
+
#
|
7
|
+
# == license
|
8
|
+
# :include:LICENSE
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'forwardable'
|
12
|
+
require 'higgs/exceptions'
|
13
|
+
require 'thread'
|
14
|
+
|
15
|
+
module Higgs
|
16
|
+
class Latch
|
17
|
+
# for ident(1)
|
18
|
+
CVS_ID = '$Id: thread.rb 559 2007-09-25 15:20:20Z toki $'
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@lock = Mutex.new
|
22
|
+
@cond = ConditionVariable.new
|
23
|
+
@start = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def start
|
27
|
+
@lock.synchronize{
|
28
|
+
@start = true
|
29
|
+
@cond.broadcast
|
30
|
+
}
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def wait
|
35
|
+
@lock.synchronize{
|
36
|
+
until (@start)
|
37
|
+
@cond.wait(@lock)
|
38
|
+
end
|
39
|
+
}
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class CountDownLatch
|
45
|
+
# for ident(1)
|
46
|
+
CVS_ID = '$Id: thread.rb 559 2007-09-25 15:20:20Z toki $'
|
47
|
+
|
48
|
+
def initialize(count)
|
49
|
+
@count = count
|
50
|
+
@lock = Mutex.new
|
51
|
+
@cond = ConditionVariable.new
|
52
|
+
end
|
53
|
+
|
54
|
+
def count_down
|
55
|
+
@lock.synchronize{
|
56
|
+
if (@count > 0) then
|
57
|
+
@count -= 1
|
58
|
+
@cond.broadcast
|
59
|
+
end
|
60
|
+
}
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def wait
|
65
|
+
@lock.synchronize{
|
66
|
+
while (@count > 0)
|
67
|
+
@cond.wait(@lock)
|
68
|
+
end
|
69
|
+
}
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Barrier
|
75
|
+
# for ident(1)
|
76
|
+
CVS_ID = '$Id: thread.rb 559 2007-09-25 15:20:20Z toki $'
|
77
|
+
|
78
|
+
def initialize(count)
|
79
|
+
@count = count
|
80
|
+
@lock = Mutex.new
|
81
|
+
@cond = ConditionVariable.new
|
82
|
+
end
|
83
|
+
|
84
|
+
def wait
|
85
|
+
@lock.synchronize{
|
86
|
+
if (@count > 0) then
|
87
|
+
@count -= 1
|
88
|
+
if (@count > 0) then
|
89
|
+
while (@count > 0)
|
90
|
+
@cond.wait(@lock)
|
91
|
+
end
|
92
|
+
else
|
93
|
+
@cond.broadcast
|
94
|
+
end
|
95
|
+
else
|
96
|
+
raise 'not recycle'
|
97
|
+
end
|
98
|
+
}
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class SharedWork
|
104
|
+
# for ident(1)
|
105
|
+
CVS_ID = '$Id: thread.rb 559 2007-09-25 15:20:20Z toki $'
|
106
|
+
|
107
|
+
def initialize(&work)
|
108
|
+
unless (work) then
|
109
|
+
raise 'required work block'
|
110
|
+
end
|
111
|
+
@work = work
|
112
|
+
@lock = Mutex.new
|
113
|
+
@cond = ConditionVariable.new
|
114
|
+
@state = :init
|
115
|
+
@result = nil
|
116
|
+
end
|
117
|
+
|
118
|
+
def result
|
119
|
+
@lock.synchronize{
|
120
|
+
case (@state)
|
121
|
+
when :done
|
122
|
+
return @result
|
123
|
+
when :init
|
124
|
+
@state = :working
|
125
|
+
# fall through
|
126
|
+
when :working
|
127
|
+
until (@state == :done)
|
128
|
+
@cond.wait(@lock)
|
129
|
+
end
|
130
|
+
return @result
|
131
|
+
else
|
132
|
+
raise 'internal error'
|
133
|
+
end
|
134
|
+
}
|
135
|
+
|
136
|
+
r = @result = @work.call
|
137
|
+
@lock.synchronize{
|
138
|
+
@state = :done
|
139
|
+
@cond.broadcast
|
140
|
+
}
|
141
|
+
r
|
142
|
+
end
|
143
|
+
|
144
|
+
def result=(value)
|
145
|
+
@lock.synchronize{
|
146
|
+
case (@state)
|
147
|
+
when :init
|
148
|
+
@state = :done
|
149
|
+
when :working
|
150
|
+
until (@state == :done)
|
151
|
+
@cond.wait(@lock)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
@result = value
|
155
|
+
}
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class ReadWriteLock
|
160
|
+
# for ident(1)
|
161
|
+
CVS_ID = '$Id: thread.rb 559 2007-09-25 15:20:20Z toki $'
|
162
|
+
|
163
|
+
def initialize
|
164
|
+
@lock = Mutex.new
|
165
|
+
@read_cond = ConditionVariable.new
|
166
|
+
@write_cond = ConditionVariable.new
|
167
|
+
@count_of_working_readers = 0
|
168
|
+
@count_of_standby_writers = 0
|
169
|
+
@priority_to_writer = true
|
170
|
+
@writing = false
|
171
|
+
end
|
172
|
+
|
173
|
+
def __read_lock__
|
174
|
+
@lock.synchronize{
|
175
|
+
while (@writing || (@priority_to_writer && @count_of_standby_writers > 0))
|
176
|
+
@read_cond.wait(@lock)
|
177
|
+
end
|
178
|
+
@count_of_working_readers += 1
|
179
|
+
}
|
180
|
+
nil
|
181
|
+
end
|
182
|
+
|
183
|
+
def __read_try_lock__
|
184
|
+
@lock.synchronize{
|
185
|
+
if (@writing || (@priority_to_writer && @count_of_standby_writers > 0)) then
|
186
|
+
return false
|
187
|
+
else
|
188
|
+
@count_of_working_readers += 1
|
189
|
+
return true
|
190
|
+
end
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
194
|
+
def __read_unlock__
|
195
|
+
@lock.synchronize{
|
196
|
+
@count_of_working_readers -= 1
|
197
|
+
@priority_to_writer = true
|
198
|
+
if (@count_of_standby_writers > 0) then
|
199
|
+
@write_cond.signal
|
200
|
+
else
|
201
|
+
@read_cond.broadcast
|
202
|
+
end
|
203
|
+
}
|
204
|
+
nil
|
205
|
+
end
|
206
|
+
|
207
|
+
def __write_lock__
|
208
|
+
@lock.synchronize{
|
209
|
+
@count_of_standby_writers += 1
|
210
|
+
begin
|
211
|
+
while (@writing || @count_of_working_readers > 0)
|
212
|
+
@write_cond.wait(@lock)
|
213
|
+
end
|
214
|
+
@writing = true
|
215
|
+
ensure
|
216
|
+
@count_of_standby_writers -= 1
|
217
|
+
end
|
218
|
+
}
|
219
|
+
nil
|
220
|
+
end
|
221
|
+
|
222
|
+
def __write_try_lock__
|
223
|
+
@lock.synchronize{
|
224
|
+
@count_of_standby_writers += 1
|
225
|
+
begin
|
226
|
+
if (@writing || @count_of_working_readers > 0) then
|
227
|
+
return false
|
228
|
+
else
|
229
|
+
@writing = true
|
230
|
+
return true
|
231
|
+
end
|
232
|
+
ensure
|
233
|
+
@count_of_standby_writers -= 1
|
234
|
+
end
|
235
|
+
}
|
236
|
+
raise 'not to reach'
|
237
|
+
end
|
238
|
+
|
239
|
+
def __write_unlock__
|
240
|
+
@lock.synchronize{
|
241
|
+
@writing = false
|
242
|
+
@priority_to_writer = false
|
243
|
+
@read_cond.broadcast
|
244
|
+
if (@count_of_standby_writers > 0) then
|
245
|
+
@write_cond.signal
|
246
|
+
end
|
247
|
+
}
|
248
|
+
nil
|
249
|
+
end
|
250
|
+
|
251
|
+
class ChildLock
|
252
|
+
def initialize(rw_lock)
|
253
|
+
@rw_lock = rw_lock
|
254
|
+
end
|
255
|
+
|
256
|
+
def synchronize
|
257
|
+
lock
|
258
|
+
begin
|
259
|
+
r = yield
|
260
|
+
ensure
|
261
|
+
unlock
|
262
|
+
end
|
263
|
+
r
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
class ReadLock < ChildLock
|
268
|
+
extend Forwardable
|
269
|
+
|
270
|
+
def_delegator :@rw_lock, :__read_lock__, :lock
|
271
|
+
def_delegator :@rw_lock, :__read_try_lock__, :try_lock
|
272
|
+
def_delegator :@rw_lock, :__read_unlock__, :unlock
|
273
|
+
end
|
274
|
+
|
275
|
+
class WriteLock < ChildLock
|
276
|
+
extend Forwardable
|
277
|
+
|
278
|
+
def_delegator :@rw_lock, :__write_lock__, :lock
|
279
|
+
def_delegator :@rw_lock, :__write_try_lock__, :try_lock
|
280
|
+
def_delegator :@rw_lock, :__write_unlock__, :unlock
|
281
|
+
end
|
282
|
+
|
283
|
+
def read_lock
|
284
|
+
ReadLock.new(self)
|
285
|
+
end
|
286
|
+
|
287
|
+
def write_lock
|
288
|
+
WriteLock.new(self)
|
289
|
+
end
|
290
|
+
|
291
|
+
def to_a
|
292
|
+
[ read_lock, write_lock ]
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
class Pool
|
297
|
+
# for ident(1)
|
298
|
+
CVS_ID = '$Id: thread.rb 559 2007-09-25 15:20:20Z toki $'
|
299
|
+
|
300
|
+
class ShutdownException < Exceptions::ShutdownException
|
301
|
+
end
|
302
|
+
|
303
|
+
def initialize(size)
|
304
|
+
@size = size
|
305
|
+
@running = true
|
306
|
+
@queue = []
|
307
|
+
@q_lock = Mutex.new
|
308
|
+
@q_cond = ConditionVariable.new
|
309
|
+
@size.times do
|
310
|
+
@queue << yield
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
attr_reader :size
|
315
|
+
|
316
|
+
def fetch
|
317
|
+
@q_lock.synchronize{
|
318
|
+
loop do
|
319
|
+
unless (@running) then
|
320
|
+
@q_cond.signal # for shutdown
|
321
|
+
raise ShutdownException, 'pool shutdown'
|
322
|
+
end
|
323
|
+
if (@queue.empty?) then
|
324
|
+
@q_cond.wait(@q_lock)
|
325
|
+
else
|
326
|
+
break
|
327
|
+
end
|
328
|
+
end
|
329
|
+
@queue.shift
|
330
|
+
}
|
331
|
+
end
|
332
|
+
|
333
|
+
def restore(obj)
|
334
|
+
@q_lock.synchronize{
|
335
|
+
@queue.push(obj)
|
336
|
+
@q_cond.signal
|
337
|
+
}
|
338
|
+
nil
|
339
|
+
end
|
340
|
+
|
341
|
+
def transaction
|
342
|
+
obj = fetch
|
343
|
+
begin
|
344
|
+
r = yield(obj)
|
345
|
+
ensure
|
346
|
+
restore(obj)
|
347
|
+
end
|
348
|
+
r
|
349
|
+
end
|
350
|
+
|
351
|
+
def shutdown
|
352
|
+
@size.times do
|
353
|
+
obj = @q_lock.synchronize{
|
354
|
+
@running = false
|
355
|
+
while (@queue.empty?)
|
356
|
+
@q_cond.wait(@q_lock)
|
357
|
+
end
|
358
|
+
@queue.shift
|
359
|
+
}
|
360
|
+
yield(obj) if block_given?
|
361
|
+
end
|
362
|
+
nil
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
# Local Variables:
|
368
|
+
# mode: Ruby
|
369
|
+
# indent-tabs-mode: nil
|
370
|
+
# End:
|