@@ -6,14 +6,6 @@ require "digest/crc32"
66require " digest/adler32"
77require " blake3"
88
9- macro gen_digest
10- {
11- {% for title, digest in Collision ::HASH_FUNCTIONS % }
12- :{{title}} => Digest ::{{digest.id}}.new,
13- {% end % }
14- }
15- end
16-
179module Collision
1810 def self.split_by_4 (hash_str : String )
1911 i = 0
@@ -32,58 +24,57 @@ module Collision
3224 class Checksum
3325 @mt_context : Fiber ::ExecutionContext ::Parallel = Fiber ::ExecutionContext ::Parallel .new(" worker-threads" , 8 )
3426 @s_context = Fiber ::ExecutionContext ::Concurrent .new(" channel-receiver" )
35- @digest = gen_digest
36- @channel = Channel (Tuple (Symbol , String )).new
37-
38- def initialize
39- end
4027
4128 def calculate (type : Symbol , filename : String ) : String
42- hash = @digest [type ]
43- hash.reset
29+ hash =
30+ {% begin % }
31+ case type
32+ {% for title, digest in Collision ::HASH_FUNCTIONS % }
33+ when :{{title}} then Digest ::{{digest.id}}.new
34+ {% end % }
35+ else
36+ raise " no digest for #{ type } " # shouldn't be reached
37+ end
38+ {% end % }
4439 hash.file(filename).hexfinal.downcase
4540 end
4641
47- def on_finished (res : Hash (Symbol , String ), & block)
48- yield res
42+ def initialize
4943 end
5044
5145 def generate (filename : String , progressbar : Gtk ::ProgressBar ? = nil , & block : Hash (Symbol , String ) - > )
5246 hash_amount = Collision ::HASH_FUNCTIONS .size
5347 progressbar.fraction = 0.0
5448 progressbar.text = sprintf(Gettext .gettext(" %d of %d hashes calculated" ), {0 , hash_amount})
5549
50+ atomic = Atomic .new(0 )
51+ step = 1 / hash_amount
52+ res = Hash (Symbol , String ).new
53+ channel = Channel (Tuple (Symbol , String )).new(hash_amount)
5654 Collision ::HASH_FUNCTIONS .each_with_index do |hash_key , hash_value , i |
57- proc = - > (fiber_no : Int32 ) do
58- @mt_context .spawn do
59- LOGGER .debug { " Spawned fiber #{ hash_value } " }
60-
61- hash_value = calculate(hash_key, filename)
62- LOGGER .debug { " Finished fiber #{ fiber_no + 1 } /#{ hash_amount } " }
63-
64- @channel .send({hash_key, hash_value})
55+ @mt_context .spawn do
56+ LOGGER .debug { " Spawned fiber #{ hash_value } " }
57+ LOGGER .debug { " Finished fiber #{ i + 1 } /#{ hash_amount } " }
58+ atomic.add(1 )
59+ GLib .idle_add do
60+ unless progressbar.nil?
61+ progressbar.fraction = Math .min(progressbar.fraction + step, 1.0 )
62+ progressbar.text = sprintf(Gettext .gettext(" %d of %d hashes calculated" ), {atomic.get, hash_amount})
63+ end
64+ false
6565 end
66+
67+ channel.send({hash_key, calculate(hash_key, filename)})
6668 end
67- proc.call(i)
6869 end
6970
7071 @s_context .spawn do
7172 res = Hash (Symbol , String ).new
72- step = 1 / hash_amount
7373 hash_amount.times do |i |
74- t_res = @ channel .receive
74+ t_res = channel.receive
7575 res[t_res[0 ]] = t_res[1 ]
76-
77- GLib .idle_add do
78- unless progressbar.nil?
79- progressbar.fraction = Math .min(progressbar.fraction + step, 1.0 )
80- progressbar.text = sprintf(Gettext .gettext(" %d of %d hashes calculated" ), {i + 1 , hash_amount})
81- end
82- false
83- end
8476 end
85-
86- on_finished(res, & block)
77+ block.call(res)
8778 end
8879 end
8980 end
0 commit comments