[macruby-changes] [3545] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Feb 15 17:30:55 PST 2010


Revision: 3545
          http://trac.macosforge.org/projects/ruby/changeset/3545
Author:   ernest.prabhakar at gmail.com
Date:     2010-02-15 17:30:54 -0800 (Mon, 15 Feb 2010)
Log Message:
-----------
Dispatch enumerable currently hosed by dispatch_apply (bug?)

Modified Paths:
--------------
    MacRuby/trunk/lib/dispatch/enumerable.rb
    MacRuby/trunk/spec/macruby/library/dispatch/enumerable_spec.rb

Modified: MacRuby/trunk/lib/dispatch/enumerable.rb
===================================================================
--- MacRuby/trunk/lib/dispatch/enumerable.rb	2010-02-16 01:30:44 UTC (rev 3544)
+++ MacRuby/trunk/lib/dispatch/enumerable.rb	2010-02-16 01:30:54 UTC (rev 3545)
@@ -11,15 +11,16 @@
   #
   def p_times(stride=1, priority=nil, &block)
     n_times = self.to_int
-    puts "\np_times: n_times=#{n_times}, stride=#{stride}"
     q = Dispatch::Queue.concurrent(priority)
+    return q.apply(n_times, &block) if stride == 1
+    
     n_strides = (n_times / stride).to_int
-    q.apply(n_strides) do |i|
-      j0 = i*stride
-      stride.times { |j| block.call(j0+j); puts "\n#{i}=>#{j0}:j=#{j}" }
+    block_from = Proc.new do |j0|
+      lambda { |j| block.call(j0+j) }
     end
+    q.apply(n_strides) { |i| stride.times &block_from.call(i*stride) }
     # Runs the remainder (if any) sequentially on the current thread
-    (n_strides*stride).upto(n_times - 1) { |j| block.call(j); puts "\nj'=#{j}" }
+    (n_times % stride).times &block_from.call(n_strides*stride)
   end
 end
 
@@ -77,19 +78,15 @@
   # but it may not be the 'first'
   # Only useful if the test block is very expensive to run
   # Note: each object can only run one p_find at a time
-
   def p_find(stride=1, priority=nil,  &block)
     @find_q ||= Dispatch.queue(self)
     @find_q.sync do 
       @find_result = nil
       q = Dispatch.queue(@find_result)
       self.p_each(stride, priority) do |obj|
-        if @find_result.nil?
-          found = block.call(obj)
-          q.async { @find_result = obj if found }
-        end
+        q.async { @find_result = obj } if @find_result.nil? and block.call(obj)
       end
-      q.sync {} #if @find_result.nil?
+      q.sync {}
       return @find_result
     end
   end

Modified: MacRuby/trunk/spec/macruby/library/dispatch/enumerable_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/library/dispatch/enumerable_spec.rb	2010-02-16 01:30:44 UTC (rev 3544)
+++ MacRuby/trunk/spec/macruby/library/dispatch/enumerable_spec.rb	2010-02-16 01:30:54 UTC (rev 3545)
@@ -2,158 +2,171 @@
 require 'dispatch'
 
 if MACOSX_VERSION >= 10.6
-  
-  describe "parallel Integer#times" do
-    describe :p_times do
-      before :each do
-        @count = 4
-        @sum = 0
-      end
+  describe "parallel loop" do
+    
+    describe :Integer do
+      describe :p_times do
+        before :each do
+          @count = 4
+          @ary = Array.new
+          @p_ary = Dispatch.wrap(Array)
+        end
 
-      it "runs the block +count+ number of times" do
-        @sum = 0
-        Dispatch.upto(@count) { |j| @sum += 1 }
-        @sum.should == @count
-      end
+        it "runs the block that many times" do
+          @count.times { |j| @ary << 1 }
+          @count.p_times { |j| @p_ary << 1 }
+          @p_ary.size.should == @ary.size
+        end
 
-      it "runs the block passing the current index" do
-        Dispatch.upto(@count) { |j| @sum += j }
-        @sum.should == (@count*(@count-1)/2)
-      end
+        it "runs the block passing the current index" do
+          @count.times { |j| @ary << j }
+          @count.p_times { |j| @p_ary << j}
+          @p_ary.should == @ary
+        end
 
-      it "does not run the block if the count is zero" do
-        Dispatch.upto(0) { |j| @sum += 1 }
-        @sum.should == 0
-      end
-    
-      it "properly combines blocks with even stride > 1" do
-        Dispatch.upto(@count, 2) { |j| @sum += j }
-        @sum.should == (@count*(@count-1)/2)
-      end
+        it "does not run the block if the count is zero" do
+          0.p_times { |j| @ary << 1 }
+          @ary.size.should == 0
+        end
 
-      it "properly combines blocks with uneven stride > 1" do
-        Dispatch.upto(@count, 3) { |j| @sum += j }
-        @sum.should == (@count*(@count-1)/2)
-      end
+        it "properly combines blocks with even stride > 1" do
+          @count.times { |j| @ary << j }
+          @count.p_times(2) { |j| @p_ary << j}
+          @p_ary.should == @ary
+        end
 
-      it "properly rounds stride fractions > 0.5" do
-        Dispatch.upto(7, 4) { |j| @sum += j }
-        @sum.should == (7*(7-1)/2)
-      end
-    end
-  end
+        it "properly combines blocks with uneven stride" do
+          @count.times { |j| @ary << j }
+          @count.p_times(3) { |j| @p_ary << j}
+          @p_ary.should == @ary
+        end
 
-  describe "parallel Enumerable" do
-    before :each do
-      @ary = (1..3).to_a
-    end
+        it "properly rounds stride fraction of 0.5" do
+          6.times { |j| @ary << j }
+          6.p_times(4) { |j| @p_ary << j}
+          @p_ary.should == @ary
+        end
 
-    describe :p_each do
-      it "exists on objects that support Enumerable" do
-        @ary.respond_to?(:p_each).should == true
+        it "properly rounds stride fraction > 0.5" do
+          7.times { |j| @ary << j }
+          7.p_times(4) { |j| @p_ary << j}
+          @p_ary.should == @ary
+        end
       end
+    end
 
-      it "should behave like each" do
-        @sum1 = 0
-        @ary.each {|v| @sum1 += v*v}
-        @sum2 = 0
-        @q = Dispatch.queue(@sum2)
-        @ary.p_each {|v| temp = v*v; @q.sync {@sum2 += temp} }
-        @sum2.should == @sum1
+    describe "Enumerable" do
+      before :each do
+        @ary = (1..3).to_a
       end
-      
-      it "should execute concurrently" do
-        t0 = Time.now
-        @ary.p_each {|v| sleep v/100.0}
-        t1 = Time.now
-        t_total = @ary.inject(0) {|a,b| a + b/100.0}
-        (t1-t0).to_f.should < t_total
-      end
-    end
-    
-    describe :p_each_with_index do
-      it "exists on objects that support Enumerable" do
-        @ary.respond_to?(:p_each).should == true
-      end
-      
-      it "should behave like each_with_index" do
-        @sum1 = 0
-        @ary.each_with_index {|v, i| @sum1 += v**i}
-        @sum2 = 0
-        @q = Dispatch.queue(@sum2)
-        @ary.p_each_with_index {|v, i| temp = v**i; @q.sync {@sum2 += temp} }
-        @sum2.should == @sum1
-      end
-    end
-    
-    describe :p_map do
-      it "exists on objects that support Enumerable" do
-        @ary.respond_to?(:p_map).should == true
-      end
-      
-      it "should behave like map" do
-        map1 = @ary.map {|v| v*v}
-        map2 = @ary.p_map {|v| v*v}
-        map2.should == map1
-      end
-    end
 
-    describe :p_mapreduce do
-      it "exists on objects that support Enumerable" do
-        @ary.respond_to?(:p_mapreduce).should == true
+      describe :p_each do
+        it "exists on objects that support Enumerable" do
+          @ary.respond_to?(:p_each).should == true
+        end
+
+        it "should behave like each" do
+          @ary1 = 0
+          @ary.each {|v| @ary1 << v*v}
+          @ary2 = 0
+          @q = Dispatch.queue(@ary2)
+          @ary.p_each {|v| temp = v*v; @q.sync {@ary2 << temp} }
+          @ary2.should == @ary1
+        end
+
+        it "should execute concurrently" do
+          t0 = Time.now
+          @ary.p_each {|v| sleep v/100.0}
+          t1 = Time.now
+          t_total = @ary.inject(0) {|a,b| a + b/100.0}
+          (t1-t0).to_f.should < t_total
+        end
       end
-      
-      it "should behave like an unordered map" do
-        map1 = @ary.map {|v| v*v}
-        map2 = @ary.p_mapreduce([]) {|v| [v*v]}
-        map2.sort.should == map1
-      end
 
-      it "should accumulate any object that takes :<< " do
-        map1 = @ary.map {|v| "%x" % (10+v)}
-        map2 = @ary.p_mapreduce("") {|v| "%x" % (10+v)}   
-        map1.each do |s|
-          map2.index(s).should_not == nil
+      describe :p_each_with_index do
+        it "exists on objects that support Enumerable" do
+          @ary.respond_to?(:p_each).should == true
         end
+
+        it "should behave like each_with_index" do
+          @ary1 = 0
+          @ary.each_with_index {|v, i| @ary1 << v**i}
+          @ary2 = 0
+          @q = Dispatch.queue(@ary2)
+          @ary.p_each_with_index {|v, i| temp = v**i; @q.sync {@ary2 << temp} }
+          @ary2.should == @ary1
+        end
       end
 
-      it "should allow custom accumulator methods" do
-        map1 = @ary.map {|v| v**2}
-        sum1 = map1.inject(0) {|s,v| s | v}
-        sum2 = @ary.p_mapreduce(0, :|) {|v| v**2}   
-        sum2.should == sum1
+      describe :p_map do
+        it "exists on objects that support Enumerable" do
+          @ary.respond_to?(:p_map).should == true
+        end
+
+        it "should behave like map" do
+          map1 = @ary.map {|v| v*v}
+          map2 = @ary.p_map {|v| v*v}
+          map2.should == map1
+        end
       end
-    end
 
-    describe :p_find_all do
-      it "exists on objects that support Enumerable" do
-        @ary.respond_to?(:p_find_all).should == true
-      end  
+      describe :p_mapreduce do
+        it "exists on objects that support Enumerable" do
+          @ary.respond_to?(:p_mapreduce).should == true
+        end
 
-      it "should behave like find_all" do
-        found1 = @ary.find_all {|v| v.odd?}
-        found2 = @ary.p_find_all {|v| v.odd?}
-        found2.sort.should == found1
+        it "should behave like an unordered map" do
+          map1 = @ary.map {|v| v*v}
+          map2 = @ary.p_mapreduce([]) {|v| [v*v]}
+          map2.sort.should == map1
+        end
+
+        it "should accumulate any object that takes :<< " do
+          map1 = @ary.map {|v| "%x" % (10+v)}
+          map2 = @ary.p_mapreduce("") {|v| "%x" % (10+v)}   
+          map1.each do |s|
+            map2.index(s).should_not == nil
+          end
+        end
+
+        it "should allow custom accumulator methods" do
+          map1 = @ary.map {|v| v**2}
+          sum1 = map1.inject(0) {|s,v| s | v}
+          sum2 = @ary.p_mapreduce(0, :|) {|v| v**2}   
+          sum2.should == sum1
+        end
       end
-    end
 
-    describe :p_find do
-      it "exists on objects that support Enumerable" do
-        @ary.respond_to?(:p_find).should == true
-      end  
+      describe :p_find_all do
+        it "exists on objects that support Enumerable" do
+          @ary.respond_to?(:p_find_all).should == true
+        end  
 
-      it "returns nil if nothing found" do
-        found2 = @ary.p_find {|v| false}
-        found2.should.nil?
+        it "should behave like find_all" do
+          found1 = @ary.find_all {|v| v.odd?}
+          found2 = @ary.p_find_all {|v| v.odd?}
+          found2.sort.should == found1
+        end
       end
 
-      it "returns one element that matches the condition" do
-        found1 = @ary.find_all {|v| v.odd?}
-        found2 = @ary.p_find {|v| v.odd?}
-        found2.should_not.nil?
-        found1.include? found2
+      describe :p_find do
+        it "exists on objects that support Enumerable" do
+          @ary.respond_to?(:p_find).should == true
+        end  
+
+        it "returns nil if nothing found" do
+          found2 = @ary.p_find {|v| false}
+          found2.should.nil?
+        end
+
+        it "returns one element that matches the condition" do
+          found1 = @ary.find_all {|v| v.odd?}
+          found2 = @ary.p_find {|v| v.odd?}
+          found2.should_not.nil?
+          found1.include? found2
+        end
       end
     end
-    
+
   end
 end
\ No newline at end of file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100215/fceb2160/attachment-0001.html>


More information about the macruby-changes mailing list