tresse 0.1.0 → 1.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +46 -15
- data/lib/tresse.rb +114 -85
- data/tresse.gemspec +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07e2b40e7224b8da9af9768fb077d0a9552b04ba
|
4
|
+
data.tar.gz: d5e471d9d944580185fe2aa97e53fec105f87ae8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e69445a655dc2d80002b087ff8355d1e344a052919be4944b52c94bef65f4065b3d8eb0cf090a0f0e8276cebc028f002399a8b638d892584b51eaefa2cc881fa
|
7
|
+
data.tar.gz: e812e89f78b44ad82726bc978bd36c780957c645b4fc55278279b770f87ed219c5995ea4ed02a16d5196c78b6d0ebeb87e43ba313d847d0789cff2bb2ff63c2b
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,41 +1,72 @@
|
|
1
1
|
|
2
2
|
# tresse
|
3
3
|
|
4
|
-
A poorly thought out and stupid
|
4
|
+
A poorly thought out and stupid source+map+reduce contraption.
|
5
5
|
|
6
|
+
You source one or more pieces of data, map them a couple of times then reduce them.
|
7
|
+
|
8
|
+
By default, the whole of Tresse uses 8 work threads, it can be changed:
|
9
|
+
```ruby
|
10
|
+
Tresse.max_work_thread_count # => 8
|
11
|
+
|
12
|
+
Tresse.max_work_thread_count = 10
|
13
|
+
|
14
|
+
Tresse.max_work_thread_count # => 10
|
15
|
+
```
|
6
16
|
|
7
17
|
## use
|
8
18
|
|
19
|
+
Two sources flattened together
|
20
|
+
```ruby
|
21
|
+
r =
|
22
|
+
Tresse::Group.new('test0')
|
23
|
+
.source { (0..3).to_a }
|
24
|
+
.source { (4..9).to_a }
|
25
|
+
.values # or .flatten
|
26
|
+
.sort
|
27
|
+
|
28
|
+
r #=> (0..9).to_a
|
9
29
|
```
|
10
|
-
require 'tresse'
|
11
30
|
|
31
|
+
Combining two sources again
|
32
|
+
```ruby
|
12
33
|
r =
|
13
34
|
Tresse::Group.new('test0')
|
14
|
-
.
|
15
|
-
.
|
16
|
-
.collect { |e| e * 2 }
|
35
|
+
.source { (0..3).to_a }
|
36
|
+
.source { ('a'..'c').to_a }
|
37
|
+
.map { |e| e.collect { |e| e * 2 } }
|
38
|
+
.values # or .flatten
|
17
39
|
|
18
40
|
r
|
19
|
-
# =>
|
20
|
-
#
|
21
|
-
# =>
|
41
|
+
# => [ 0, 2, 4, 6, 'aa', 'bb', 'cc' ]
|
42
|
+
# or
|
43
|
+
# => [ 'aa', 'bb', 'cc', 0, 2, 4, 6 ]
|
22
44
|
```
|
23
45
|
|
46
|
+
Each can be used, the outcome of its block is discarded
|
24
47
|
```ruby
|
25
|
-
|
48
|
+
t = []
|
49
|
+
# collecting on the side
|
26
50
|
|
27
51
|
r =
|
28
52
|
Tresse::Group.new('test0')
|
29
|
-
.
|
30
|
-
.
|
31
|
-
.
|
32
|
-
.
|
33
|
-
.inject([]) { |a, e| a << e.first; a.sort }
|
53
|
+
.source { (0..3).to_a }
|
54
|
+
.source { ('a'..'c').to_a }
|
55
|
+
.each { |e| t << e.collect { |e| e * 2 } }
|
56
|
+
.values
|
34
57
|
|
35
58
|
r
|
36
|
-
# =>
|
59
|
+
# => [ 0, 1, 2, 3, 'a', 'b', 'c' ]
|
60
|
+
# or
|
61
|
+
# => [ 'a', 'b', 'c', 0, 1, 2, 3 ]
|
62
|
+
|
63
|
+
t
|
64
|
+
# => [ [ 0, 2, 4, 6 ], [ 'aa', 'bb', 'cc' ] ]
|
65
|
+
# or
|
66
|
+
# => [ [ 'aa', 'bb', 'cc' ], [ 0, 2, 4, 6 ] ]
|
37
67
|
```
|
38
68
|
|
69
|
+
|
39
70
|
## license
|
40
71
|
|
41
72
|
MIT, see [LICENSE.txt](LICENSE.txt)
|
data/lib/tresse.rb
CHANGED
@@ -4,27 +4,23 @@ require 'thread'
|
|
4
4
|
|
5
5
|
module Tresse
|
6
6
|
|
7
|
-
VERSION = '
|
7
|
+
VERSION = '1.0.0'
|
8
8
|
|
9
9
|
class << self
|
10
10
|
|
11
|
-
attr_accessor :max_work_threads
|
12
|
-
|
13
11
|
def init
|
14
12
|
|
15
|
-
@max_work_threads = 7
|
16
13
|
@work_queue = Queue.new
|
17
|
-
@
|
18
|
-
|
19
|
-
@on_error =
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
run
|
14
|
+
@work_threads = 8.times.collect { |i| make_work_thread }
|
15
|
+
|
16
|
+
@on_error =
|
17
|
+
lambda do |where, err|
|
18
|
+
puts "-" * 80
|
19
|
+
p where
|
20
|
+
p err
|
21
|
+
puts err.backtrace
|
22
|
+
puts "-" * 80
|
23
|
+
end
|
28
24
|
end
|
29
25
|
|
30
26
|
def enqueue(batch)
|
@@ -39,44 +35,46 @@ module Tresse
|
|
39
35
|
@on_error = block
|
40
36
|
end
|
41
37
|
|
42
|
-
|
43
|
-
|
44
|
-
def run
|
45
|
-
|
46
|
-
@max_work_threads.times { |i| @thread_queue << i }
|
38
|
+
def max_work_thread_count
|
47
39
|
|
48
|
-
|
49
|
-
|
50
|
-
begin
|
40
|
+
@work_threads.size
|
41
|
+
end
|
51
42
|
|
52
|
-
|
53
|
-
batch = @work_queue.pop
|
43
|
+
def max_work_thread_count=(i)
|
54
44
|
|
55
|
-
|
45
|
+
i0 = @work_threads.size
|
56
46
|
|
57
|
-
|
47
|
+
@work_threads << make_work_thread while @work_threads.size < i
|
48
|
+
@work_threads.pop while @work_threads.size > i
|
58
49
|
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
50
|
+
i
|
63
51
|
end
|
64
52
|
|
65
|
-
|
53
|
+
protected
|
54
|
+
|
55
|
+
def make_work_thread
|
66
56
|
|
67
57
|
Thread.new do
|
68
|
-
begin
|
69
58
|
|
70
|
-
|
71
|
-
|
59
|
+
t = Thread.current
|
60
|
+
t[:tresse] = true
|
72
61
|
|
73
|
-
|
62
|
+
loop do
|
63
|
+
begin
|
74
64
|
|
75
|
-
|
65
|
+
batch = @work_queue.pop
|
76
66
|
|
77
|
-
|
67
|
+
unless @work_threads.include?(t)
|
68
|
+
@work_queue << batch
|
69
|
+
break
|
70
|
+
end
|
78
71
|
|
79
|
-
|
72
|
+
batch.process
|
73
|
+
|
74
|
+
rescue => err
|
75
|
+
|
76
|
+
@on_error.call(:in_worker_thread, err)
|
77
|
+
end
|
80
78
|
end
|
81
79
|
end
|
82
80
|
end
|
@@ -88,122 +86,153 @@ module Tresse
|
|
88
86
|
class Batch
|
89
87
|
|
90
88
|
attr_reader :group
|
91
|
-
attr_reader :
|
89
|
+
attr_reader :map_index
|
90
|
+
attr_accessor :value
|
92
91
|
|
93
92
|
def initialize(group, block_or_group)
|
94
93
|
|
95
94
|
@group = group
|
96
95
|
@bog = block_or_group
|
97
96
|
|
98
|
-
@
|
97
|
+
@map_index = -1
|
99
98
|
@value = nil
|
100
99
|
end
|
101
100
|
|
102
101
|
def process
|
103
102
|
|
104
|
-
@
|
105
|
-
@group.send(:
|
103
|
+
@map_index += 1
|
104
|
+
@group.send(:receive, self)
|
106
105
|
end
|
107
106
|
|
108
|
-
|
109
|
-
|
110
|
-
def generate
|
107
|
+
def source
|
111
108
|
|
112
109
|
args = [ group ] + [ nil ] * 7
|
113
110
|
args = args[0, @bog.method(:call).arity]
|
114
111
|
|
115
112
|
@value = @bog.call(*args)
|
116
113
|
end
|
114
|
+
|
115
|
+
def map(type, block)
|
116
|
+
|
117
|
+
args = [ @value, self ]
|
118
|
+
args = args[0, block.method(:call).arity.abs]
|
119
|
+
|
120
|
+
r = block.call(*args)
|
121
|
+
|
122
|
+
@value = r if type == :map
|
123
|
+
end
|
117
124
|
end
|
118
125
|
|
119
126
|
class Group
|
120
127
|
|
121
128
|
attr_accessor :name
|
122
|
-
attr_reader :batches
|
129
|
+
#attr_reader :batches
|
123
130
|
|
124
|
-
def initialize(name)
|
131
|
+
def initialize(name=nil)
|
125
132
|
|
126
133
|
@name = name
|
127
134
|
|
128
135
|
@batches = []
|
129
|
-
@
|
136
|
+
@launched = false
|
137
|
+
@maps = [ nil ]
|
130
138
|
|
131
|
-
@
|
132
|
-
@
|
133
|
-
@
|
139
|
+
@reduce = nil
|
140
|
+
@reduce_batches = []
|
141
|
+
@reduction_queue = Queue.new
|
134
142
|
end
|
135
143
|
|
136
144
|
#
|
137
|
-
#
|
145
|
+
# sourcing methods
|
138
146
|
|
139
|
-
def
|
147
|
+
def source(o=nil, &block)
|
140
148
|
|
141
149
|
batch = Tresse::Batch.new(self, o ? o : block)
|
142
150
|
|
143
151
|
@batches << batch
|
144
|
-
|
152
|
+
|
153
|
+
self
|
145
154
|
end
|
146
155
|
|
147
156
|
#
|
148
|
-
#
|
157
|
+
# mapping
|
149
158
|
|
150
159
|
def each(&block)
|
151
160
|
|
152
|
-
|
161
|
+
do_map(:each, block)
|
162
|
+
end
|
153
163
|
|
154
|
-
|
164
|
+
def map(&block)
|
165
|
+
|
166
|
+
do_map(:map, block)
|
155
167
|
end
|
156
168
|
|
157
169
|
#
|
158
|
-
#
|
170
|
+
# reducing
|
171
|
+
|
172
|
+
def reduce(target, &block)
|
173
|
+
|
174
|
+
do_reduce(target, block)
|
175
|
+
end
|
176
|
+
alias inject reduce
|
159
177
|
|
160
|
-
def
|
178
|
+
def flatten
|
161
179
|
|
162
|
-
|
180
|
+
do_reduce([], lambda { |a, e| a.concat(e) })
|
181
|
+
end
|
182
|
+
alias values flatten
|
183
|
+
|
184
|
+
protected
|
185
|
+
|
186
|
+
def do_map(type, block)
|
163
187
|
|
164
|
-
@
|
188
|
+
@maps << [ type, block ]
|
189
|
+
|
190
|
+
launch
|
191
|
+
|
192
|
+
self
|
165
193
|
end
|
166
|
-
alias reduce inject
|
167
194
|
|
168
|
-
def
|
195
|
+
def do_reduce(target, block)
|
169
196
|
|
170
|
-
@
|
197
|
+
@reduce = [ target, block ]
|
171
198
|
|
172
|
-
|
199
|
+
launch
|
200
|
+
|
201
|
+
@reduction_queue.pop
|
173
202
|
end
|
174
|
-
alias map collect
|
175
203
|
|
176
|
-
|
204
|
+
def launch
|
205
|
+
|
206
|
+
return if @launched == true
|
207
|
+
@launched = true
|
177
208
|
|
178
|
-
|
209
|
+
@batches.each { |b| Tresse.enqueue(b) }
|
210
|
+
end
|
211
|
+
|
212
|
+
def receive(batch)
|
179
213
|
|
180
|
-
if batch.
|
181
|
-
batch.
|
214
|
+
if batch.map_index == 0
|
215
|
+
batch.source
|
182
216
|
Tresse.enqueue(batch)
|
183
|
-
elsif
|
184
|
-
|
185
|
-
args = args[0, e.method(:call).arity.abs]
|
186
|
-
e.call(*args)
|
217
|
+
elsif m = @maps[batch.map_index]
|
218
|
+
batch.map(*m)
|
187
219
|
Tresse.enqueue(batch)
|
188
220
|
else
|
189
|
-
|
221
|
+
queue_for_reduction(batch)
|
190
222
|
end
|
191
223
|
end
|
192
224
|
|
193
|
-
def
|
225
|
+
def queue_for_reduction(batch)
|
194
226
|
|
195
|
-
@
|
227
|
+
@reduce_batches << batch
|
196
228
|
|
197
|
-
return if @
|
229
|
+
return if @reduce_batches.size < @batches.size
|
230
|
+
return unless @reduce
|
198
231
|
|
199
232
|
es = @batches.collect(&:value)
|
233
|
+
target, block = @reduce
|
200
234
|
|
201
|
-
@
|
202
|
-
if @final.is_a?(Array)
|
203
|
-
es.inject(@final[0], &@final[1])
|
204
|
-
else
|
205
|
-
es.collect(&@final)
|
206
|
-
end
|
235
|
+
@reduction_queue << es.inject(target, &block)
|
207
236
|
end
|
208
237
|
end
|
209
238
|
end
|
data/tresse.gemspec
CHANGED
@@ -13,10 +13,10 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.homepage = 'http://github.com/jmettraux/tresse'
|
14
14
|
#s.rubyforge_project = 'rufus'
|
15
15
|
s.license = 'MIT'
|
16
|
-
s.summary = 'a stupid
|
16
|
+
s.summary = 'a stupid source+map+reduce thing'
|
17
17
|
|
18
18
|
s.description = %{
|
19
|
-
a poorly thought out and stupid
|
19
|
+
a poorly thought out and stupid source+map+reduce contraption
|
20
20
|
}.strip
|
21
21
|
|
22
22
|
#s.files = `git ls-files`.split("\n")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tresse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.8'
|
27
|
-
description: a poorly thought out and stupid
|
27
|
+
description: a poorly thought out and stupid source+map+reduce contraption
|
28
28
|
email:
|
29
29
|
- jmettraux@gmail.com
|
30
30
|
executables: []
|
@@ -61,5 +61,5 @@ rubyforge_project:
|
|
61
61
|
rubygems_version: 2.5.2.3
|
62
62
|
signing_key:
|
63
63
|
specification_version: 4
|
64
|
-
summary: a stupid
|
64
|
+
summary: a stupid source+map+reduce thing
|
65
65
|
test_files: []
|