forkjoin 1.0.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +39 -0
- data/examples/recursive/fibonacci.rb +23 -0
- data/examples/recursive/mergesort.rb +60 -0
- data/examples/wordcount.rb +17 -0
- data/forkjoin.gemspec +17 -0
- data/lib/forkjoin.jar +0 -0
- data/lib/forkjoin.rb +4 -0
- metadata +73 -0
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
forkjoin for JRuby
|
2
|
+
==================
|
3
|
+
|
4
|
+
This is a small extension that wraps the JSR166y "Fork/Join"
|
5
|
+
framework in an efficient way for JRuby.
|
6
|
+
|
7
|
+
Example
|
8
|
+
-------
|
9
|
+
|
10
|
+
```
|
11
|
+
require 'forkjoin'
|
12
|
+
|
13
|
+
pool = ForkJoin::Pool.new
|
14
|
+
|
15
|
+
# FORK
|
16
|
+
|
17
|
+
# Add a job (a proc) to the pool for each line
|
18
|
+
map_futures = pool.invoke_all(
|
19
|
+
ARGF.each_line.map{|line| ->{line.split.map{|word| [word,1]}}}
|
20
|
+
)
|
21
|
+
|
22
|
+
# Get aggregate results
|
23
|
+
counts = map_futures.map(&:get).inject({}) {|map, value|
|
24
|
+
value.each {|k,v| (map[k] ||= []) << v}
|
25
|
+
map
|
26
|
+
}
|
27
|
+
|
28
|
+
# JOIN
|
29
|
+
|
30
|
+
# Add a job to the pool for each count in the map
|
31
|
+
reduced_futures = pool.invoke_all(
|
32
|
+
counts.map{|k, vs| ->{[k, vs.size]}}
|
33
|
+
)
|
34
|
+
|
35
|
+
# Print out results (or you could "reduce" some other way)
|
36
|
+
reduced_futures.map(&:get).each{|value|
|
37
|
+
puts "%s %d\n" % value
|
38
|
+
}
|
39
|
+
```
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'forkjoin'
|
2
|
+
|
3
|
+
class Fibonacci < ForkJoin::Task
|
4
|
+
def initialize(n)
|
5
|
+
@n = n
|
6
|
+
end
|
7
|
+
|
8
|
+
def call
|
9
|
+
return @n if @n <= 1
|
10
|
+
(f = Fibonacci.new(@n - 1)).fork
|
11
|
+
Fibonacci.new(@n - 2).call + f.join
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
times = ARGV.shift.to_i
|
16
|
+
n = ARGV.shift.to_i
|
17
|
+
|
18
|
+
times.times do
|
19
|
+
start = Time.now.to_f
|
20
|
+
pool = ForkJoin::Pool.new
|
21
|
+
puts "fib(%d) = %d" % [n, pool.invoke(Fibonacci.new(n))]
|
22
|
+
puts "%f [msec]" % ((Time.now.to_f - start) * 1000)
|
23
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'forkjoin'
|
2
|
+
|
3
|
+
class MergeSort < ForkJoin::Task
|
4
|
+
def initialize(array, low, high)
|
5
|
+
@array, @low, @high = array, low, high
|
6
|
+
end
|
7
|
+
|
8
|
+
def call
|
9
|
+
size = @high - @low
|
10
|
+
if size <= 8
|
11
|
+
@array[@low, size] = @array[@low, size].sort
|
12
|
+
else
|
13
|
+
middle = @low + (size >> 1)
|
14
|
+
(f = MergeSort.new(@array, middle, @high)).fork
|
15
|
+
MergeSort.new(@array, @low, middle).call
|
16
|
+
f.join
|
17
|
+
merge(middle)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def merge(middle)
|
24
|
+
return if @array[middle - 1] < @array[middle]
|
25
|
+
copy_size = @high - @low
|
26
|
+
copy_middle = middle - @low
|
27
|
+
copy = @array[@low, copy_size]
|
28
|
+
p = 0
|
29
|
+
q = copy_middle
|
30
|
+
@low.upto(@high - 1) do |i|
|
31
|
+
if q >= copy_size || (p < copy_middle && copy[p] < copy[q])
|
32
|
+
@array[i] = copy[p]
|
33
|
+
p += 1
|
34
|
+
else
|
35
|
+
@array[i] = copy[q]
|
36
|
+
q += 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
n = ARGV.shift.to_i
|
43
|
+
|
44
|
+
array = Array.new(n)
|
45
|
+
0.upto(n - 1) do |idx|
|
46
|
+
array[idx] = rand(2**32) - 2**31
|
47
|
+
end
|
48
|
+
|
49
|
+
org = array.dup
|
50
|
+
|
51
|
+
start = Time.now.to_f
|
52
|
+
pool = ForkJoin::Pool.new
|
53
|
+
pool.submit(MergeSort.new(array, 0, array.size)).join
|
54
|
+
puts "%f [msec]" % ((Time.now.to_f - start) * 1000)
|
55
|
+
|
56
|
+
if array != org.sort
|
57
|
+
# Huh? On my 4 core machine, it *sometimes* fail.
|
58
|
+
# Runs fine on my 1 core machine.
|
59
|
+
raise "Merge-sort failed!"
|
60
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'forkjoin'
|
2
|
+
|
3
|
+
pool = ForkJoin::Pool.new
|
4
|
+
|
5
|
+
map_futures = pool.invoke_all(
|
6
|
+
ARGF.each_line.map{|line| ->{line.split.map{|word| [word,1]}}}
|
7
|
+
)
|
8
|
+
counts = map_futures.map(&:get).inject({}) {|map, value|
|
9
|
+
value.each {|k,v| (map[k] ||= []) << v}
|
10
|
+
map
|
11
|
+
}
|
12
|
+
reduced_futures = pool.invoke_all(
|
13
|
+
counts.map{|k, vs| ->{[k, vs.size]}}
|
14
|
+
)
|
15
|
+
reduced_futures.map(&:get).each{|value|
|
16
|
+
puts "%s %d\n" % value
|
17
|
+
}
|
data/forkjoin.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{forkjoin}
|
5
|
+
s.version = "1.0.0"
|
6
|
+
s.authors = ["Charles Oliver Nutter", "Nakamura Hiroshi"]
|
7
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
8
|
+
s.description = "A JRuby extension to efficiently wrap the JSR166 Fork/Join framework."
|
9
|
+
s.email = ["headius@headius.com", "nahi@ctor.org"]
|
10
|
+
s.files = Dir['lib/**/*'] + Dir['examples/**/*.rb'] + Dir['{README.md,forkjoin.gemspec}']
|
11
|
+
s.homepage = "http://github.com/headius/forkjoin.rb"
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.summary = "A JRuby wrapper around Fork/Join"
|
14
|
+
s.test_files = Dir["test/test*.rb"]
|
15
|
+
s.platform = "java"
|
16
|
+
s.add_dependency("jsr166y")
|
17
|
+
end
|
data/lib/forkjoin.jar
ADDED
Binary file
|
data/lib/forkjoin.rb
ADDED
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: forkjoin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
6
|
+
platform: java
|
7
|
+
authors:
|
8
|
+
- Charles Oliver Nutter
|
9
|
+
- Nakamura Hiroshi
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2012-02-17 00:00:00 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: jsr166y
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
description: A JRuby extension to efficiently wrap the JSR166 Fork/Join framework.
|
28
|
+
email:
|
29
|
+
- headius@headius.com
|
30
|
+
- nahi@ctor.org
|
31
|
+
executables: []
|
32
|
+
|
33
|
+
extensions: []
|
34
|
+
|
35
|
+
extra_rdoc_files: []
|
36
|
+
|
37
|
+
files:
|
38
|
+
- lib/forkjoin.jar
|
39
|
+
- lib/forkjoin.rb
|
40
|
+
- examples/wordcount.rb
|
41
|
+
- examples/recursive/fibonacci.rb
|
42
|
+
- examples/recursive/mergesort.rb
|
43
|
+
- README.md
|
44
|
+
- forkjoin.gemspec
|
45
|
+
homepage: http://github.com/headius/forkjoin.rb
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.8.15
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: A JRuby wrapper around Fork/Join
|
72
|
+
test_files: []
|
73
|
+
|