Permalink
Browse files

Create PMap module instead of directly adding to Enumerable

  • Loading branch information...
1 parent 2f27ff1 commit 01d157da9f668c8cf648dfa1fd6316d1519a70a2 @shepmaster committed May 9, 2011
Showing with 42 additions and 39 deletions.
  1. +42 −39 lib/pmap.rb
View
81 lib/pmap.rb
@@ -1,47 +1,50 @@
-
-# I'd prefer to create this as a module named "Pmap" and then poke
-# "Pmap" into "Enumerable". I haven't figured out how to do it.
-# So, I directly reopen "Enumerable" and add "p" methods...
-
require 'thread' unless defined?(Mutex)
# Global variable for the default thread pool size.
$pmap_default_thread_count ||= 64
-module Enumerable
- # Parallel "map" for any Enumerable.
- # Requires a block of code to run for each Enumerable item.
- # [thread_count] is number of threads to create. Optional.
- def pmap(thread_count=nil, &proc)
- raise ArgumentError, "thread_count must be at least one." unless
- thread_count.nil? or (thread_count.respond_to?(:>=) and thread_count >= 1)
- # This seems overly fussy... (code smell)
- in_array = self.to_a # I'm not sure how expensive this is...
- size = in_array.size
- thread_count = [thread_count||$pmap_default_thread_count, size].min
- out_array = Array.new(size)
- semaphore = Mutex.new
- index = -1 # Our use of index is protected by semaphore
- threads = (0...thread_count).map {
- Thread.new {
- i = nil
- while (semaphore.synchronize {i = (index += 1)}; i < size)
- out_array[i] = yield(in_array[i])
- end
- }
- }
- threads.each {|t| t.join}
- out_array
- end
+module PMap
+ def self.included(base)
+ base.class_eval do
+ # Parallel "map" for any Enumerable.
+ # Requires a block of code to run for each Enumerable item.
+ # [thread_count] is number of threads to create. Optional.
+ def pmap(thread_count=nil, &proc)
+ raise ArgumentError, "thread_count must be at least one." unless
+ thread_count.nil? or (thread_count.respond_to?(:>=) and thread_count >= 1)
+ # This seems overly fussy... (code smell)
+ in_array = self.to_a # I'm not sure how expensive this is...
+ size = in_array.size
+ thread_count = [thread_count||$pmap_default_thread_count, size].min
+ out_array = Array.new(size)
+ semaphore = Mutex.new
+ index = -1 # Our use of index is protected by semaphore
+ threads = (0...thread_count).map {
+ Thread.new {
+ i = nil
+ while (semaphore.synchronize {i = (index += 1)}; i < size)
+ out_array[i] = yield(in_array[i])
+ end
+ }
+ }
+ threads.each {|t| t.join}
+ out_array
+ end
- # Parallel "each" for any Enumerable.
- # Requires a block of code to run for each Enumerable item.
- # [thread_count] is number of threads to create. Optional.
- def peach(thread_count=nil, &proc)
- # This is doing some extra work: building a return array that is
- # thrown away. How can I share the core code of "pmap" here and omit
- # the output array creation?
- pmap(thread_count, &proc)
- self
+ # Parallel "each" for any Enumerable.
+ # Requires a block of code to run for each Enumerable item.
+ # [thread_count] is number of threads to create. Optional.
+ def peach(thread_count=nil, &proc)
+ # This is doing some extra work: building a return array that is
+ # thrown away. How can I share the core code of "pmap" here and omit
+ # the output array creation?
+ pmap(thread_count, &proc)
+ self
+ end
+ end
end
end
+
+module Enumerable
+ include PMap
+end

0 comments on commit 01d157d

Please sign in to comment.