higgs 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/ChangeLog +208 -0
  2. data/LICENSE +26 -0
  3. data/README +2 -0
  4. data/Rakefile +75 -0
  5. data/bin/higgs_backup +67 -0
  6. data/bin/higgs_dump_index +43 -0
  7. data/bin/higgs_dump_jlog +42 -0
  8. data/bin/higgs_verify +37 -0
  9. data/lib/cgi/session/higgs.rb +72 -0
  10. data/lib/higgs/block.rb +192 -0
  11. data/lib/higgs/cache.rb +117 -0
  12. data/lib/higgs/dbm.rb +55 -0
  13. data/lib/higgs/exceptions.rb +31 -0
  14. data/lib/higgs/flock.rb +77 -0
  15. data/lib/higgs/index.rb +164 -0
  16. data/lib/higgs/jlog.rb +159 -0
  17. data/lib/higgs/lock.rb +189 -0
  18. data/lib/higgs/storage.rb +1086 -0
  19. data/lib/higgs/store.rb +228 -0
  20. data/lib/higgs/tar.rb +390 -0
  21. data/lib/higgs/thread.rb +370 -0
  22. data/lib/higgs/tman.rb +513 -0
  23. data/lib/higgs/utils/bman.rb +285 -0
  24. data/lib/higgs/utils.rb +22 -0
  25. data/lib/higgs/version.rb +21 -0
  26. data/lib/higgs.rb +59 -0
  27. data/misc/cache_bench/cache_bench.rb +43 -0
  28. data/misc/dbm_bench/.strc +8 -0
  29. data/misc/dbm_bench/Rakefile +78 -0
  30. data/misc/dbm_bench/dbm_multi_thread.rb +199 -0
  31. data/misc/dbm_bench/dbm_rnd_delete.rb +43 -0
  32. data/misc/dbm_bench/dbm_rnd_read.rb +44 -0
  33. data/misc/dbm_bench/dbm_rnd_update.rb +44 -0
  34. data/misc/dbm_bench/dbm_seq_read.rb +45 -0
  35. data/misc/dbm_bench/dbm_seq_write.rb +44 -0
  36. data/misc/dbm_bench/st_verify.rb +28 -0
  37. data/misc/io_bench/cksum_bench.rb +48 -0
  38. data/misc/io_bench/jlog_bench.rb +71 -0
  39. data/misc/io_bench/write_bench.rb +128 -0
  40. data/misc/thread_bench/lock_bench.rb +132 -0
  41. data/mkrdoc.rb +8 -0
  42. data/rdoc.yml +13 -0
  43. data/sample/count.rb +60 -0
  44. data/sample/dbmtest.rb +38 -0
  45. data/test/Rakefile +45 -0
  46. data/test/run.rb +32 -0
  47. data/test/test_block.rb +163 -0
  48. data/test/test_cache.rb +214 -0
  49. data/test/test_cgi_session.rb +142 -0
  50. data/test/test_flock.rb +162 -0
  51. data/test/test_index.rb +258 -0
  52. data/test/test_jlog.rb +180 -0
  53. data/test/test_lock.rb +320 -0
  54. data/test/test_online_backup.rb +169 -0
  55. data/test/test_storage.rb +439 -0
  56. data/test/test_storage_conf.rb +202 -0
  57. data/test/test_storage_init_opts.rb +89 -0
  58. data/test/test_store.rb +211 -0
  59. data/test/test_tar.rb +432 -0
  60. data/test/test_thread.rb +541 -0
  61. data/test/test_tman.rb +875 -0
  62. data/test/test_tman_init_opts.rb +56 -0
  63. data/test/test_utils_bman.rb +234 -0
  64. metadata +115 -0
@@ -0,0 +1,541 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'higgs/thread'
4
+ require 'test/unit'
5
+ require 'timeout'
6
+
7
+ Thread.abort_on_exception = true if $DEBUG
8
+
9
+ module Higgs::Test
10
+ module ThreadParams
11
+ COUNT_OF_THREADS = (ENV['THREADS'] || '10').to_i
12
+ WORK_COUNT = (ENV['WORK'] || '100').to_i
13
+ DELTA_T = (ENV['DELTA_T'] || '0.1').to_f
14
+
15
+ if ($DEBUG) then
16
+ puts 'thread test parameters...'
17
+ for name in constants
18
+ puts "#{name} = #{const_get(name)}"
19
+ end
20
+ puts ''
21
+ end
22
+ end
23
+
24
+ class LatchTest < Test::Unit::TestCase
25
+ include Higgs
26
+ include ThreadParams
27
+ include Timeout
28
+
29
+ # for ident(1)
30
+ CVS_ID = '$Id: test_thread.rb 559 2007-09-25 15:20:20Z toki $'
31
+
32
+ def test_start_wait
33
+ latch = Latch.new
34
+
35
+ lock = Mutex.new
36
+ count = 0
37
+ th_grp = ThreadGroup.new
38
+ COUNT_OF_THREADS.times do
39
+ th_grp.add Thread.new{
40
+ latch.wait
41
+ lock.synchronize{ count += 1 }
42
+ }
43
+ end
44
+
45
+ sleep(DELTA_T)
46
+ assert_equal(0, lock.synchronize{ count })
47
+
48
+ latch.start
49
+ timeout(10) {
50
+ for t in th_grp.list
51
+ t.join
52
+ end
53
+ }
54
+ assert_equal(COUNT_OF_THREADS, lock.synchronize{ count })
55
+ end
56
+ end
57
+
58
+ class CountDownLatchTest < Test::Unit::TestCase
59
+ include Higgs
60
+ include ThreadParams
61
+ include Timeout
62
+
63
+ # for ident(1)
64
+ CVS_ID = '$Id: test_thread.rb 559 2007-09-25 15:20:20Z toki $'
65
+
66
+ def test_count_down_wait
67
+ latch = CountDownLatch.new(3)
68
+
69
+ lock = Mutex.new
70
+ count = 0
71
+ th_grp = ThreadGroup.new
72
+ COUNT_OF_THREADS.times do
73
+ th_grp.add Thread.new{
74
+ latch.wait
75
+ lock.synchronize{ count += 1 }
76
+ }
77
+ end
78
+
79
+ sleep(DELTA_T)
80
+ assert_equal(0, lock.synchronize{ count })
81
+
82
+ latch.count_down
83
+ sleep(DELTA_T)
84
+ assert_equal(0, lock.synchronize{ count })
85
+
86
+ latch.count_down
87
+ sleep(DELTA_T)
88
+ assert_equal(0, lock.synchronize{ count })
89
+
90
+ latch.count_down
91
+ timeout(10) {
92
+ for t in th_grp.list
93
+ t.join
94
+ end
95
+ }
96
+ assert_equal(COUNT_OF_THREADS, lock.synchronize{ count })
97
+ end
98
+ end
99
+
100
+ class BarrierTest < Test::Unit::TestCase
101
+ include Higgs
102
+ include ThreadParams
103
+ include Timeout
104
+
105
+ # for ident(1)
106
+ CVS_ID = '$Id: test_thread.rb 559 2007-09-25 15:20:20Z toki $'
107
+
108
+ def test_wait
109
+ barrier = Barrier.new(COUNT_OF_THREADS)
110
+
111
+ lock = Mutex.new
112
+ count = 0
113
+ th_new = proc{
114
+ Thread.new{
115
+ barrier.wait
116
+ lock.synchronize{ count += 1 }
117
+ }
118
+ }
119
+
120
+ th_grp = ThreadGroup.new
121
+ (COUNT_OF_THREADS - 1).times do
122
+ th_grp.add(th_new.call)
123
+ end
124
+
125
+ sleep(DELTA_T)
126
+ assert_equal(0, lock.synchronize{ count })
127
+
128
+ th_grp.add(th_new.call)
129
+ timeout(10) {
130
+ for t in th_grp.list
131
+ t.join
132
+ end
133
+ }
134
+ assert_equal(COUNT_OF_THREADS, lock.synchronize{ count })
135
+ end
136
+
137
+ def test_not_recycle
138
+ barrier = Barrier.new(1)
139
+ barrier.wait
140
+ assert_raise(RuntimeError) { barrier.wait }
141
+ end
142
+ end
143
+
144
+ class SharedWorkTest < Test::Unit::TestCase
145
+ include Higgs
146
+ include ThreadParams
147
+ include Timeout
148
+
149
+ # for ident(1)
150
+ CVS_ID = '$Id: test_thread.rb 559 2007-09-25 15:20:20Z toki $'
151
+
152
+ def calc
153
+ @s = 0 # @s's scope is over multi-threading
154
+ for i in 1..WORK_COUNT
155
+ @s += i
156
+ end
157
+ @s
158
+ end
159
+
160
+ def test_calc_single_thread
161
+ a = calc
162
+ b = calc
163
+ assert_equal(a, b)
164
+ end
165
+
166
+ def test_calc_race_condition
167
+ a = nil
168
+ b = nil
169
+ begin
170
+ barrier = Barrier.new(3)
171
+
172
+ th1 = Thread.new{
173
+ barrier.wait
174
+ a = calc
175
+ }
176
+
177
+ th2 = Thread.new{
178
+ barrier.wait
179
+ b = calc
180
+ }
181
+
182
+ barrier.wait
183
+ th1.join
184
+ th2.join
185
+ end until (a != b) # race condition
186
+ end
187
+
188
+ def test_result
189
+ expected_result = calc
190
+
191
+ latch = Latch.new
192
+ work = SharedWork.new{
193
+ latch.wait
194
+ calc
195
+ }
196
+
197
+ barrier = Barrier.new(COUNT_OF_THREADS + 1)
198
+ lock = Mutex.new
199
+ count = 0
200
+
201
+ th_grp = ThreadGroup.new
202
+ COUNT_OF_THREADS.times{|i| # `i' should be local scope of thread block
203
+ th_grp.add Thread.new{
204
+ barrier.wait
205
+ assert_equal(expected_result, work.result, "th#{i}")
206
+ lock.synchronize{ count += 1 }
207
+ }
208
+ }
209
+
210
+ barrier.wait
211
+ assert_equal(0, lock.synchronize{ count })
212
+
213
+ latch.start
214
+ timeout(10) {
215
+ for t in th_grp.list
216
+ t.join
217
+ end
218
+ }
219
+ assert_equal(COUNT_OF_THREADS, lock.synchronize{ count })
220
+ assert_equal(expected_result, work.result)
221
+ end
222
+
223
+ def test_no_work_block
224
+ assert_raise(RuntimeError) { SharedWork.new }
225
+ end
226
+
227
+ def test_set_result
228
+ work = SharedWork.new{ :foo }
229
+ work.result = :bar
230
+ assert_equal(:bar, work.result)
231
+ end
232
+
233
+ def test_set_result_after_work
234
+ work = SharedWork.new{ :foo }
235
+ assert_equal(:foo, work.result)
236
+ work.result = :bar
237
+ assert_equal(:bar, work.result)
238
+ end
239
+
240
+ def test_set_result_after_work_multithread
241
+ barrier = Barrier.new(3)
242
+
243
+ work = SharedWork.new{
244
+ barrier.wait
245
+ sleep(DELTA_T)
246
+ :foo
247
+ }
248
+
249
+ th_set_result = Thread.new{
250
+ barrier.wait
251
+ work.result = :bar
252
+ }
253
+
254
+ th_work = Thread.new{
255
+ assert_equal(:foo, work.result)
256
+ }
257
+
258
+ barrier.wait
259
+ th_set_result.join
260
+ th_work.join
261
+
262
+ assert_equal(:bar, work.result)
263
+ end
264
+ end
265
+
266
+ class ReadWriteLockTest < Test::Unit::TestCase
267
+ include Higgs
268
+ include ThreadParams
269
+
270
+ # for ident(1)
271
+ CVS_ID = '$Id: test_thread.rb 559 2007-09-25 15:20:20Z toki $'
272
+
273
+ def setup
274
+ @rw_lock = ReadWriteLock.new
275
+ end
276
+
277
+ def test_read_lock_single_thread
278
+ v = "foo"
279
+ r_lock = @rw_lock.read_lock
280
+ WORK_COUNT.times do
281
+ assert_equal("foo", r_lock.synchronize{ v })
282
+ end
283
+ end
284
+
285
+ def test_write_lock_single_thread
286
+ count = 0
287
+ w_lock = @rw_lock.write_lock
288
+ WORK_COUNT.times do
289
+ w_lock.synchronize{
290
+ count += 1
291
+ }
292
+ end
293
+ assert_equal(WORK_COUNT, count)
294
+ end
295
+
296
+ def test_read_lock_multithread
297
+ v = "foo"
298
+ th_grp = ThreadGroup.new
299
+ barrier = Barrier.new(COUNT_OF_THREADS + 1)
300
+
301
+ COUNT_OF_THREADS.times{|i| # `i' should be local scope of thread block
302
+ th_grp.add Thread.new{
303
+ r_lock = @rw_lock.read_lock
304
+ r_lock.synchronize{
305
+ barrier.wait
306
+ WORK_COUNT.times do |j|
307
+ assert_equal("foo", v, "read_lock: #{i}.#{j}")
308
+ end
309
+ }
310
+ }
311
+ }
312
+
313
+ barrier.wait
314
+ for t in th_grp.list
315
+ t.join
316
+ end
317
+ end
318
+
319
+ def test_write_lock_multithread
320
+ count = 0
321
+ th_grp = ThreadGroup.new
322
+ barrier = Barrier.new(COUNT_OF_THREADS + 1)
323
+
324
+ COUNT_OF_THREADS.times do
325
+ th_grp.add Thread.new{
326
+ w_lock = @rw_lock.write_lock
327
+ barrier.wait
328
+ WORK_COUNT.times do
329
+ w_lock.synchronize{
330
+ count += 1
331
+ }
332
+ end
333
+ }
334
+ end
335
+
336
+ barrier.wait
337
+ for t in th_grp.list
338
+ t.join
339
+ end
340
+ assert_equal(COUNT_OF_THREADS * WORK_COUNT, count)
341
+ end
342
+
343
+ def test_read_write_lock_multithread
344
+ count = 0
345
+ th_grp = ThreadGroup.new
346
+ barrier = Barrier.new(COUNT_OF_THREADS * 2 + 1)
347
+
348
+ COUNT_OF_THREADS.times{|i| # `i' should be local scope of thread block
349
+ th_grp.add Thread.new{
350
+ r_lock = @rw_lock.read_lock
351
+ r_lock.synchronize{
352
+ barrier.wait
353
+ WORK_COUNT.times do |j|
354
+ assert_equal(0, count, "read_lock: #{i}.#{j}")
355
+ end
356
+ }
357
+ }
358
+ }
359
+
360
+ COUNT_OF_THREADS.times do
361
+ th_grp.add Thread.new{
362
+ w_lock = @rw_lock.write_lock
363
+ barrier.wait
364
+ WORK_COUNT.times do
365
+ w_lock.synchronize{
366
+ count += 1
367
+ }
368
+ end
369
+ }
370
+ end
371
+
372
+ barrier.wait
373
+ for t in th_grp.list
374
+ t.join
375
+ end
376
+ assert_equal(COUNT_OF_THREADS * WORK_COUNT, count)
377
+ end
378
+
379
+ def test_write_read_lock_multithread
380
+ count = 0
381
+ th_grp = ThreadGroup.new
382
+ barrier = Barrier.new(COUNT_OF_THREADS + 2)
383
+
384
+ th_grp.add Thread.new{
385
+ w_lock = @rw_lock.write_lock
386
+ w_lock.synchronize{
387
+ barrier.wait
388
+ COUNT_OF_THREADS.times do
389
+ WORK_COUNT.times do
390
+ count += 1
391
+ end
392
+ end
393
+ }
394
+ }
395
+
396
+ COUNT_OF_THREADS.times{|i| # `i' should be local scope of thread block
397
+ th_grp.add Thread.new{
398
+ r_lock = @rw_lock.read_lock
399
+ barrier.wait
400
+ r_lock.synchronize{
401
+ assert_equal(COUNT_OF_THREADS * WORK_COUNT, count, "read_lock: #{i}")
402
+ }
403
+ }
404
+ }
405
+
406
+ barrier.wait
407
+ for t in th_grp.list
408
+ t.join
409
+ end
410
+ end
411
+
412
+ def test_read_write_race
413
+ count = 0
414
+ value = true
415
+ th_grp = ThreadGroup.new
416
+ barrier = Barrier.new(COUNT_OF_THREADS + 2)
417
+
418
+ COUNT_OF_THREADS.times{|i| # `i' should be local scope of thread block
419
+ th_grp.add Thread.new{
420
+ r_lock = @rw_lock.read_lock
421
+ barrier.wait
422
+ WORK_COUNT.times do
423
+ r_lock.synchronize{
424
+ p "#{i}: #{count}" if $DEBUG
425
+ assert_equal(true, value, "read_lock: #{i}")
426
+ }
427
+ end
428
+ }
429
+ }
430
+
431
+ th_grp.add Thread.new{
432
+ w_lock = @rw_lock.write_lock
433
+ barrier.wait
434
+ WORK_COUNT.times do
435
+ w_lock.synchronize{
436
+ count += 1
437
+ value = false
438
+ value = true
439
+ }
440
+ end
441
+ }
442
+
443
+ barrier.wait
444
+ for t in th_grp.list
445
+ t.join
446
+ end
447
+ end
448
+ end
449
+
450
+ class PoolTest < Test::Unit::TestCase
451
+ include Higgs
452
+ include ThreadParams
453
+
454
+ # for ident(1)
455
+ CVS_ID = '$Id: test_thread.rb 559 2007-09-25 15:20:20Z toki $'
456
+
457
+ class Counter
458
+ def initialize
459
+ @value = 0
460
+ end
461
+
462
+ attr_reader :value
463
+
464
+ def count
465
+ @value += 1
466
+ end
467
+ end
468
+
469
+ def setup
470
+ @pool = Pool.new(2) { Counter.new }
471
+ end
472
+
473
+ def test_transaction
474
+ th_grp = ThreadGroup.new
475
+ barrier = Barrier.new(COUNT_OF_THREADS + 1)
476
+
477
+ COUNT_OF_THREADS.times{|i| # `i' should be local scope of thread block
478
+ th_grp.add Thread.new{
479
+ barrier.wait
480
+ WORK_COUNT.times do |j|
481
+ @pool.transaction{|c|
482
+ v = c.value
483
+ c.count
484
+ assert_equal(v + 1, c.value, "thread: #{i}.#{j}")
485
+ }
486
+ end
487
+ }
488
+ }
489
+
490
+ barrier.wait
491
+ for t in th_grp.list
492
+ t.join
493
+ end
494
+
495
+ n = 0
496
+ s = 0
497
+ @pool.shutdown{|c|
498
+ n += 1
499
+ s += c.value
500
+ }
501
+ assert_equal(@pool.size, n)
502
+ assert_equal(WORK_COUNT * COUNT_OF_THREADS, s)
503
+ end
504
+
505
+ def test_shutdown
506
+ th_grp = ThreadGroup.new
507
+ barrier = Barrier.new(COUNT_OF_THREADS + 1)
508
+ latch = CountDownLatch.new(COUNT_OF_THREADS)
509
+
510
+ COUNT_OF_THREADS.times{|i| # `i' should be local scope of thread block
511
+ th_grp.add Thread.new{
512
+ barrier.wait
513
+ assert_raise(Pool::ShutdownException) {
514
+ j = 0
515
+ loop do
516
+ @pool.transaction{|c|
517
+ v = c.value
518
+ c.count
519
+ assert_equal(v + 1, c.value, "thread: #{i}.#{j}")
520
+ latch.count_down if (j > WORK_COUNT)
521
+ }
522
+ j += 1
523
+ end
524
+ }
525
+ }
526
+ }
527
+
528
+ barrier.wait
529
+ latch.wait
530
+ @pool.shutdown
531
+ for t in th_grp.list
532
+ t.join
533
+ end
534
+ end
535
+ end
536
+ end
537
+
538
+ # Local Variables:
539
+ # mode: Ruby
540
+ # indent-tabs-mode: nil
541
+ # End: