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,199 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for ident(1)
4
+ CVS_ID = '$Id: dbm_multi_thread.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ $: << File.join(File.dirname($0), '..', '..', 'lib')
7
+
8
+ require 'benchmark'
9
+ require 'higgs/dbm'
10
+ require 'higgs/lock'
11
+ require 'higgs/thread'
12
+ require 'thread'
13
+
14
+ loop_count = (ARGV.shift || '100').to_i
15
+ transaction_count = (ARGV.shift || '100').to_i
16
+ thread_count = (ARGV.shift || '10').to_i
17
+ puts "#{$0}: LOOP:#{loop_count}, TRANSACTION:#{transaction_count}, THREAD:#{thread_count}"
18
+ puts ''
19
+
20
+ name = File.join(File.dirname($0), 'foo')
21
+ conf_path = File.join(File.dirname($0), '.strc')
22
+
23
+ options = {}
24
+ options.update(Higgs::Storage.load_conf(conf_path)) if (File.exist? conf_path)
25
+
26
+ [ Higgs::GiantLockManager.new,
27
+ Higgs::FineGrainLockManager.new
28
+ ].each do |lock_manager|
29
+ puts lock_manager.class
30
+ options[:lock_manager] = lock_manager
31
+ Higgs::DBM.open(name, options) {|dbm|
32
+ dbm.transaction{|tx|
33
+ tx[:foo] = 'a'
34
+ thread_count.times do |i|
35
+ tx[i] = i.to_s
36
+ end
37
+ }
38
+
39
+ Benchmark.bm(16) do |x|
40
+ x.report(' read') {
41
+ (thread_count * transaction_count).times do
42
+ dbm.transaction(true) {|tx|
43
+ loop_count.times do
44
+ tx[:foo]
45
+ end
46
+ }
47
+ end
48
+ }
49
+
50
+ barrier = Higgs::Barrier.new(thread_count + 1)
51
+ th_grp = ThreadGroup.new
52
+ thread_count.times do
53
+ th_grp.add Thread.new{
54
+ barrier.wait
55
+ transaction_count.times do
56
+ dbm.transaction(true) {|tx|
57
+ loop_count.times do
58
+ tx[:foo]
59
+ end
60
+ }
61
+ end
62
+ }
63
+ end
64
+
65
+ x.report('MT read') {
66
+ barrier.wait
67
+ for th in th_grp.list
68
+ th.join
69
+ end
70
+ }
71
+
72
+ x.report(' write') {
73
+ (thread_count * transaction_count).times do
74
+ dbm.transaction{|tx|
75
+ loop_count.times do
76
+ tx[:foo] = 'a'
77
+ end
78
+ }
79
+ end
80
+ }
81
+
82
+ barrier = Higgs::Barrier.new(thread_count + 1)
83
+ th_grp = ThreadGroup.new
84
+ thread_count.times do
85
+ th_grp.add Thread.new{
86
+ barrier.wait
87
+ transaction_count.times do
88
+ dbm.transaction{|tx|
89
+ loop_count.times do
90
+ tx[:foo] = 'a'
91
+ end
92
+ }
93
+ end
94
+ }
95
+ end
96
+
97
+ x.report('MT write') {
98
+ barrier.wait
99
+ for th in th_grp.list
100
+ th.join
101
+ end
102
+ }
103
+
104
+ x.report(' sparse write') {
105
+ thread_count.times do |i|
106
+ key = i
107
+ value = i.to_s
108
+ transaction_count.times do
109
+ dbm.transaction{|tx|
110
+ loop_count.times do
111
+ tx[key] = value
112
+ end
113
+ }
114
+ end
115
+ end
116
+ }
117
+
118
+ barrier = Higgs::Barrier.new(thread_count + 1)
119
+ th_grp = ThreadGroup.new
120
+ thread_count.times do |i|
121
+ key = i
122
+ value = i.to_s
123
+ th_grp.add Thread.new{
124
+ barrier.wait
125
+ transaction_count.times do
126
+ dbm.transaction{|tx|
127
+ loop_count.times do
128
+ tx[key] = value
129
+ end
130
+ }
131
+ end
132
+ }
133
+ end
134
+
135
+ x.report('MT sparse write') {
136
+ barrier.wait
137
+ for th in th_grp.list
138
+ th.join
139
+ end
140
+ }
141
+
142
+ x.report(' read/write') {
143
+ ((thread_count - 1) * transaction_count).times do
144
+ dbm.transaction(true) {|tx|
145
+ loop_count.times do
146
+ tx[:foo]
147
+ end
148
+ }
149
+ end
150
+ transaction_count.times do
151
+ dbm.transaction{|tx|
152
+ loop_count.times do
153
+ tx[:foo] = 'a'
154
+ end
155
+ }
156
+ end
157
+ }
158
+
159
+ barrier = Higgs::Barrier.new(thread_count + 1)
160
+ th_grp = ThreadGroup.new
161
+ (thread_count - 1).times do
162
+ th_grp.add Thread.new{
163
+ barrier.wait
164
+ transaction_count.times do
165
+ dbm.transaction(true) {|tx|
166
+ loop_count.times do
167
+ tx[:foo]
168
+ end
169
+ }
170
+ end
171
+ }
172
+ end
173
+ th_grp.add Thread.new{
174
+ barrier.wait
175
+ transaction_count.times do
176
+ dbm.transaction{|tx|
177
+ loop_count.times do
178
+ tx[:foo] = 'a'
179
+ end
180
+ }
181
+ end
182
+ }
183
+
184
+ x.report('MT read/write') {
185
+ barrier.wait
186
+ for th in th_grp.list
187
+ th.join
188
+ end
189
+ }
190
+ end
191
+
192
+ puts ''
193
+ }
194
+ end
195
+
196
+ # Local Variables:
197
+ # mode: Ruby
198
+ # indent-tabs-mode: nil
199
+ # End:
@@ -0,0 +1,43 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for ident(1)
4
+ CVS_ID = '$Id: dbm_rnd_delete.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ $: << File.join(File.dirname($0), '..', '..', 'lib')
7
+
8
+ require 'benchmark'
9
+ require 'higgs/dbm'
10
+
11
+ loop_count = (ARGV.shift || '100').to_i
12
+ data_count = (ARGV.shift || '10').to_i
13
+ puts "#{$0}: LOOP:#{loop_count}, DATA:#{data_count}"
14
+
15
+ name = File.join(File.dirname($0), 'foo')
16
+ conf_path = File.join(File.dirname($0), '.strc')
17
+
18
+ options = {}
19
+ options.update(Higgs::Storage.load_conf(conf_path)) if (File.exist? conf_path)
20
+
21
+ Higgs::DBM.open(name, options) {|dbm|
22
+ srand(0)
23
+ key_list = dbm.transaction{|tx| tx.keys }
24
+
25
+ Benchmark.bm do |x|
26
+ x.report('dbm rnd delete:') {
27
+ loop_count.times do
28
+ dbm.transaction{|tx|
29
+ data_count.times do
30
+ k = key_list[rand(key_list.length)]
31
+ tx.delete(k)
32
+ end
33
+ }
34
+ end
35
+ }
36
+ end
37
+ print "\n"
38
+ }
39
+
40
+ # Local Variables:
41
+ # mode: Ruby
42
+ # indent-tabs-mode: nil
43
+ # End:
@@ -0,0 +1,44 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for ident(1)
4
+ CVS_ID = '$Id: dbm_rnd_read.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ $: << File.join(File.dirname($0), '..', '..', 'lib')
7
+
8
+ require 'benchmark'
9
+ require 'higgs/dbm'
10
+
11
+ loop_count = (ARGV.shift || '100').to_i
12
+ data_count = (ARGV.shift || '10').to_i
13
+ puts "#{$0}: LOOP:#{loop_count}, DATA:#{data_count}"
14
+
15
+ name = File.join(File.dirname($0), 'foo')
16
+ conf_path = File.join(File.dirname($0), '.strc')
17
+
18
+ options = {}
19
+ options.update(Higgs::Storage.load_conf(conf_path)) if (File.exist? conf_path)
20
+ options[:read_only] = true
21
+
22
+ Higgs::DBM.open(name, options) {|dbm|
23
+ srand(0)
24
+ key_list = dbm.transaction{|tx| tx.keys }
25
+
26
+ Benchmark.bm do |x|
27
+ x.report('dbm rnd read:') {
28
+ loop_count.times do
29
+ dbm.transaction{|tx|
30
+ data_count.times do
31
+ k = key_list[rand(key_list.length)]
32
+ tx[k]
33
+ end
34
+ }
35
+ end
36
+ }
37
+ end
38
+ print "\n"
39
+ }
40
+
41
+ # Local Variables:
42
+ # mode: Ruby
43
+ # indent-tabs-mode: nil
44
+ # End:
@@ -0,0 +1,44 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for ident(1)
4
+ CVS_ID = '$Id: dbm_rnd_update.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ $: << File.join(File.dirname($0), '..', '..', 'lib')
7
+
8
+ require 'benchmark'
9
+ require 'higgs/dbm'
10
+
11
+ loop_count = (ARGV.shift || '100').to_i
12
+ data_count = (ARGV.shift || '10').to_i
13
+ max_dat_len = (ARGV.shift || '32768').to_i
14
+ puts "#{$0}: LOOP:#{loop_count}, DATA:#{data_count}, MAX_DAT_LEN:#{max_dat_len}"
15
+
16
+ name = File.join(File.dirname($0), 'foo')
17
+ conf_path = File.join(File.dirname($0), '.strc')
18
+
19
+ options = {}
20
+ options.update(Higgs::Storage.load_conf(conf_path)) if (File.exist? conf_path)
21
+
22
+ Higgs::DBM.open(name, options) {|dbm|
23
+ srand(0)
24
+ key_list = dbm.transaction{|tx| tx.keys }
25
+
26
+ Benchmark.bm do |x|
27
+ x.report('dbm rnd update:') {
28
+ loop_count.times do
29
+ dbm.transaction{|tx|
30
+ data_count.times do
31
+ k = key_list[rand(key_list.length)]
32
+ tx[k] = 0xFF.chr * (rand(max_dat_len))
33
+ end
34
+ }
35
+ end
36
+ }
37
+ end
38
+ print "\n"
39
+ }
40
+
41
+ # Local Variables:
42
+ # mode: Ruby
43
+ # indent-tabs-mode: nil
44
+ # End:
@@ -0,0 +1,45 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for ident(1)
4
+ CVS_ID = '$Id: dbm_seq_read.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ $: << File.join(File.dirname($0), '..', '..', 'lib')
7
+
8
+ require 'benchmark'
9
+ require 'higgs/dbm'
10
+
11
+ loop_count = (ARGV.shift || '100').to_i
12
+ data_count = (ARGV.shift || '10').to_i
13
+ puts "#{$0}: LOOP:#{loop_count}, DATA:#{data_count}"
14
+
15
+ name = File.join(File.dirname($0), 'foo')
16
+ conf_path = File.join(File.dirname($0), '.strc')
17
+
18
+ options = {}
19
+ options.update(Higgs::Storage.load_conf(conf_path)) if (File.exist? conf_path)
20
+ options[:read_only] = true
21
+
22
+ Higgs::DBM.open(name, options) {|dbm|
23
+ key_list = dbm.transaction{|tx|
24
+ tx.keys.map{|k| k.to_i }.sort.map{|i| i.to_s }
25
+ }
26
+
27
+ Benchmark.bm do |x|
28
+ x.report('dbm seq read:') {
29
+ loop_count.times do |i|
30
+ dbm.transaction{|tx|
31
+ data_count.times do |j|
32
+ k = key_list[(i + j) % key_list.length]
33
+ tx[k]
34
+ end
35
+ }
36
+ end
37
+ }
38
+ end
39
+ print "\n"
40
+ }
41
+
42
+ # Local Variables:
43
+ # mode: Ruby
44
+ # indent-tabs-mode: nil
45
+ # End:
@@ -0,0 +1,44 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for ident(1)
4
+ CVS_ID = '$Id: dbm_seq_write.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ $: << File.join(File.dirname($0), '..', '..', 'lib')
7
+
8
+ require 'benchmark'
9
+ require 'higgs/dbm'
10
+
11
+ loop_count = (ARGV.shift || '100').to_i
12
+ data_count = (ARGV.shift || '10').to_i
13
+ max_dat_len = (ARGV.shift || '32768').to_i
14
+ puts "#{$0}: LOOP:#{loop_count}, DATA:#{data_count}, MAX_DAT_LEN:#{max_dat_len}"
15
+
16
+ name = File.join(File.dirname($0), 'foo')
17
+ conf_path = File.join(File.dirname($0), '.strc')
18
+
19
+ options = {}
20
+ options.update(Higgs::Storage.load_conf(conf_path)) if (File.exist? conf_path)
21
+
22
+ Higgs::DBM.open(name, options) {|dbm|
23
+ srand(0)
24
+
25
+ Benchmark.bm do |x|
26
+ x.report('dbm seq write:') {
27
+ loop_count.times do |i|
28
+ dbm.transaction{|tx|
29
+ data_count.times do |j|
30
+ k = (i * data_count + j).to_s
31
+ d = 0xFF.chr * (rand(max_dat_len))
32
+ tx[k] = d
33
+ end
34
+ }
35
+ end
36
+ }
37
+ end
38
+ print "\n"
39
+ }
40
+
41
+ # Local Variables:
42
+ # mode: Ruby
43
+ # indent-tabs-mode: nil
44
+ # End:
@@ -0,0 +1,28 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for ident(1)
4
+ CVS_ID = '$Id: st_verify.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ $: << File.join(File.dirname($0), '..', '..', 'lib')
7
+
8
+ require 'benchmark'
9
+ require 'higgs/storage'
10
+
11
+ puts $0
12
+
13
+ st = Higgs::Storage.new('foo', :read_only => true)
14
+ begin
15
+ Benchmark.bm do |x|
16
+ x.report('st verify') {
17
+ st.verify
18
+ }
19
+ end
20
+ print "\n"
21
+ ensure
22
+ st.shutdown
23
+ end
24
+
25
+ # Local Variables:
26
+ # mode: Ruby
27
+ # indent-tabs-mode: nil
28
+ # End:
@@ -0,0 +1,48 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for dient(1)
4
+ CVS_ID = '$Id: cksum_bench.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ require 'benchmark'
7
+ require 'digest/md5'
8
+ require 'digest/rmd160'
9
+ require 'digest/sha1'
10
+ require 'digest/sha2'
11
+
12
+ count = (ARGV.shift || '10000').to_i
13
+ size = (ARGV.shift || '65536').to_i
14
+ puts "#{$0}: COUNT:#{count}, SIZE:#{size}"
15
+
16
+ data = 0xFF.chr * size
17
+
18
+ task_list = [ 8, 16, 32, 64, 128 ].map{|n|
19
+ [ "String\#sum(#{n}):",
20
+ proc{
21
+ count.times do
22
+ data.sum(n)
23
+ end
24
+ }
25
+ ]
26
+ } + [
27
+ Digest::MD5, Digest::RMD160,
28
+ Digest::SHA1, Digest::SHA256, Digest::SHA384, Digest::SHA512
29
+ ].map{|d|
30
+ [ "#{d}:",
31
+ proc{
32
+ count.times do
33
+ d.digest(data)
34
+ end
35
+ }
36
+ ]
37
+ }
38
+
39
+ Benchmark.bm(task_list.map{|n, t| n.length }.max) do |x|
40
+ task_list.each do |name, task|
41
+ x.report(name) { task.call }
42
+ end
43
+ end
44
+
45
+ # Local Variables:
46
+ # mode: Ruby
47
+ # indent-tabs-mode: nil
48
+ # End:
@@ -0,0 +1,71 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for dient(1)
4
+ CVS_ID = '$Id: jlog_bench.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ $: << File.join(File.dirname($0), '..', '..', 'lib')
7
+
8
+ require 'benchmark'
9
+ require 'fileutils'
10
+ require 'higgs/jlog'
11
+
12
+ count = (ARGV.shift || '10000').to_i
13
+ log_size = (ARGV.shift || '16384').to_i
14
+ data_file = ARGV.shift || 'jlog_test.dat'
15
+
16
+ puts "#{$0}: COUNT:#{count}, LOG:#{log_size}"
17
+
18
+ class JLogWriteTask
19
+ def initialize(path, count, log_size, fsync, cksum_type)
20
+ @path = path
21
+ @count = count
22
+ @log_dat = 0xFF.chr * log_size
23
+ @fsync = fsync
24
+ @cksum_type = cksum_type
25
+ end
26
+
27
+ def open
28
+ log = Higgs::JournalLogger.open(@path, @fsync, @cksum_type)
29
+ begin
30
+ yield(log)
31
+ ensure
32
+ log.close
33
+ end
34
+ end
35
+ private :open
36
+
37
+ def call
38
+ open{|log|
39
+ @count.times do
40
+ log.write(@log_dat)
41
+ end
42
+ }
43
+ end
44
+ end
45
+
46
+ task_list = []
47
+ cksum_list = [ :SUM16, :MD5, :RMD160, :SHA1, :SHA256, :SHA384, :SHA512 ]
48
+ for cksum_type in cksum_list
49
+ task_list << [
50
+ "jlog write [#{cksum_type}]:",
51
+ JLogWriteTask.new(data_file, count, log_size, false, cksum_type)
52
+ ]
53
+ end
54
+ for cksum_type in cksum_list
55
+ task_list << [
56
+ "jlog write (fsync) [#{cksum_type}]:",
57
+ JLogWriteTask.new(data_file, count, log_size, true, cksum_type)
58
+ ]
59
+ end
60
+
61
+ Benchmark.bm(task_list.map{|n, t| n.length }.max) do |x|
62
+ FileUtils.rm_f(data_file)
63
+ task_list.each do |name, task|
64
+ x.report(name) { task.call }
65
+ end
66
+ end
67
+
68
+ # Local Variables:
69
+ # mode: Ruby
70
+ # indent-tabs-mode: nil
71
+ # End:
@@ -0,0 +1,128 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # for dient(1)
4
+ CVS_ID = '$Id: write_bench.rb 559 2007-09-25 15:20:20Z toki $'
5
+
6
+ require 'benchmark'
7
+
8
+ segment_count = (ARGV.shift || '10000').to_i
9
+ segment_size = (ARGV.shift || '16384').to_i
10
+ chunk_count = (ARGV.shift || '10').to_i
11
+ data_file = ARGV.shift || 'io_test.dat'
12
+
13
+ puts "#{$0}: COUNT:#{segment_count}, SEGMENT:#{segment_size}, CHUNK:#{chunk_count}"
14
+
15
+ class WriteTask
16
+ def initialize(path, count, size, chunk, fsync)
17
+ @path = path
18
+ @count = count
19
+ @chunk = chunk
20
+ @data = 0xFF.chr * size
21
+ @fsync = fsync
22
+ srand(0) # reset for rand
23
+ end
24
+
25
+ def open
26
+ begin
27
+ w = File.open(@path, File::WRONLY | File::CREAT | File::EXCL)
28
+ rescue Errno::EEXIST
29
+ w = File.open(@path, File::WRONLY)
30
+ end
31
+
32
+ begin
33
+ w.binmode
34
+ yield(w)
35
+ ensure
36
+ w.close
37
+ end
38
+ end
39
+ private :open
40
+
41
+ def io_sync(io)
42
+ if (@fsync) then
43
+ io.fsync
44
+ else
45
+ io.sync
46
+ end
47
+ end
48
+ private :io_sync
49
+ end
50
+
51
+ class SequentialWriteTask < WriteTask
52
+ def work
53
+ open{|w|
54
+ @count.times do |i|
55
+ w.write(@data)
56
+ if (i % @chunk == 0) then
57
+ io_sync(w)
58
+ end
59
+ end
60
+ io_sync(w)
61
+ }
62
+ end
63
+ end
64
+
65
+ class RandomWriteTask < WriteTask
66
+ def work
67
+ open{|w|
68
+ @count.times do |i|
69
+ pos = rand(@count)
70
+ w.seek(@data.size * pos)
71
+ w.write(@data)
72
+ if (i % @chunk == 0) then
73
+ io_sync(w)
74
+ end
75
+ end
76
+ io_sync(w)
77
+ }
78
+ end
79
+ end
80
+
81
+ class SortedRandomWriteTask < WriteTask
82
+ def work
83
+ open{|w|
84
+ write_list = []
85
+ @count.times do |i|
86
+ pos = rand(@count)
87
+ write_list << pos
88
+ if (i % @chunk == 0) then
89
+ write_list.sort!
90
+ for pos in write_list
91
+ w.seek(@data.size * pos)
92
+ w.write(@data)
93
+ end
94
+ write_list.clear
95
+ io_sync(w)
96
+ end
97
+ end
98
+
99
+ write_list.sort!
100
+ for pos in write_list
101
+ w.seek(@data.size * pos)
102
+ w.write(@data)
103
+ end
104
+ write_list.clear
105
+ io_sync(w)
106
+ }
107
+ end
108
+ end
109
+
110
+ task_list = [
111
+ [ 'seq write:', SequentialWriteTask.new(data_file, segment_count, segment_size, chunk_count, false) ],
112
+ [ 'seq write (fsync):', SequentialWriteTask.new(data_file, segment_count, segment_size, chunk_count, true) ],
113
+ [ 'rnd write:', RandomWriteTask.new(data_file, segment_count, segment_size, chunk_count, false) ],
114
+ [ 'rnd write (fsync):', RandomWriteTask.new(data_file, segment_count, segment_size, chunk_count, true) ],
115
+ [ 'sorted rnd write:', SortedRandomWriteTask.new(data_file, segment_count, segment_size, chunk_count, false) ],
116
+ [ 'sorted rnd write (fsync):', SortedRandomWriteTask.new(data_file, segment_count, segment_size, chunk_count, true) ]
117
+ ]
118
+
119
+ Benchmark.bm(task_list.map{|n,t| n.length }.max) do |x|
120
+ task_list.each do |name, work|
121
+ x.report(name) { work.work }
122
+ end
123
+ end
124
+
125
+ # Local Variables:
126
+ # mode: Ruby
127
+ # indent-tabs-mode: nil
128
+ # End: