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.
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: