forkjoin 1.0.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|