Skip to content

Instantly share code, notes, and snippets.

@seejohnrun
Created November 14, 2012 00:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seejohnrun/4069373 to your computer and use it in GitHub Desktop.
Save seejohnrun/4069373 to your computer and use it in GitHub Desktop.
Enumeration functions that run async (would people want to see this in a library?)
module AtOnce
extend self
def map(objects, &block)
results = Array.new(objects.count)
threads = objects.map.with_index do |object, idx|
Thread.new do
results[idx] = block.call(object)
end
end
threads.each(&:join)
results
end
def select(objects, &block)
selected_objects = []
threads = objects.map do |object|
Thread.new do
if block.call(object)
selected_objects << object
end
end
end
threads.each(&:join)
selected_objects
end
def group_by(objects, &block)
hash = Hash.new { |h, k| h[k] = [] }
threads = objects.map do |object|
Thread.new do
hash[block.call(object)] << object
end
end
threads.each(&:join)
hash
end
def any?(objects, &block)
any = false
threads = objects.map do |object|
Thread.new do
if block.call(object)
any = true
threads.each(&:kill)
end
end
end
threads.each(&:join)
any
end
def all?(objects, &block)
all = true
threads = objects.map do |object|
Thread.new do
unless block.call(object)
all = false
threads.each(&:kill)
end
end
end
threads.each(&:join)
all
end
def min(objects, &block)
min_object = nil
min_value = nil
mutex = Mutex.new
threads = objects.map do |object|
Thread.new do
val = block.call(object)
mutex.synchronize do
if min_value.nil? || val < min_value
min_object = object
min_value = val
end
end
end
end
threads.each(&:join)
min_object
end
def max(objects, &block)
max_object = nil
max_value = nil
mutex = Mutex.new
threads = objects.map do |object|
Thread.new do
val = block.call(object)
mutex.synchronize do
if max_value.nil? || val > max_value
max_object = object
max_value = val
end
end
end
end
threads.each(&:join)
max_object
end
end
require_relative 'at_once'
def inspector(res)
puts res.inspect
puts 'done.'
end
inspector AtOnce.map([1, 2, 3]) { |n| n * 2 }
inspector AtOnce.select([1, 2, 3]) { |n| n % 2 == 0 }
inspector AtOnce.min([2, 1, 3, 4]) { |n| n * 2 }
inspector AtOnce.max([2, 1, 3, 4]) { |n| n * 2 }
inspector AtOnce.all?([1, 2, 3, 4, 5, 6, 7, 8, 9]) { |n| n < 0 }
inspector AtOnce.any?([1, 2, 3]) { |n| n == 2 }
inspector AtOnce.group_by([1, 2, 3, 4]) { |n| n % 2 == 0 ? 'even' : 'odd' }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment