tresse 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a1837779d3e8be68176eb4fb52d2cc16d411ce24
4
+ data.tar.gz: 504b3c9a5c52290d7fd49bc9ddf24d685c4ea5be
5
+ SHA512:
6
+ metadata.gz: cb7be058cf592b5ae2e0f75ce973f94acd79c7406fef6301e2b040ce19529d497013b28f95d1e029b38938fbe8c1264fdaf16b234a10d368651ea70a9f1b1a4d
7
+ data.tar.gz: 99b7ea37ef5ea2e2dac2e99a3336b137cd282f2aaa619a6d827d42d0f9e341a594022b04278a6be2e2ef8e7ce7ef39fec0487e1f12ea3b9afd48a8d24d88c19c
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+
2
+ # CHANGELOG.md
3
+
4
+
5
+ ## tresse 0.1.0 released 2019-09-15
6
+
7
+ * Initial release
8
+
data/CREDITS.md ADDED
@@ -0,0 +1,5 @@
1
+
2
+ # tresse credits
3
+
4
+ * John Mettraux https://github.com/jmettraux author and maintainer
5
+
data/LICENSE.txt ADDED
@@ -0,0 +1,24 @@
1
+
2
+ Copyright (c) 2019-2019, John Mettraux, jmettraux@gmail.com
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
22
+
23
+ Made in Japan
24
+
data/Makefile ADDED
@@ -0,0 +1,39 @@
1
+
2
+ ## gem tasks ##
3
+
4
+ NAME = \
5
+ $(shell ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.name")
6
+ VERSION = \
7
+ $(shell ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.version")
8
+
9
+ count_lines:
10
+ find lib -name "*.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
11
+ find spec -name "*_spec.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
12
+ cl: count_lines
13
+
14
+ gemspec_validate:
15
+ @echo "---"
16
+ ruby -e "s = eval(File.read(Dir['*.gemspec'].first)); p s.validate"
17
+ @echo "---"
18
+
19
+ name: gemspec_validate
20
+ @echo "$(NAME) $(VERSION)"
21
+
22
+ cw:
23
+ find lib -name "*.rb" -exec ruby -cw {} \;
24
+
25
+ build: gemspec_validate
26
+ gem build $(NAME).gemspec
27
+ mkdir -p pkg
28
+ mv $(NAME)-$(VERSION).gem pkg/
29
+
30
+ push: build
31
+ gem push pkg/$(NAME)-$(VERSION).gem
32
+
33
+ spec:
34
+ bundle exec rspec
35
+ test: spec
36
+
37
+
38
+ .PHONY: count_lines gemspec_validate name cw build push spec
39
+
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+
2
+ # tresse
3
+
4
+ A poorly thought out and stupid each+map+reduce contraption.
5
+
6
+
7
+ ## use
8
+
9
+ ```
10
+ require 'tresse'
11
+
12
+ r =
13
+ Tresse::Group.new('test0')
14
+ .append { 'b' }
15
+ .append { 'a' }
16
+ .collect { |e| e * 2 }
17
+
18
+ r
19
+ # => %[ aa bb ]
20
+ # or
21
+ # => %[ bb aa ]
22
+ ```
23
+
24
+ ```ruby
25
+ require 'tresse'
26
+
27
+ r =
28
+ Tresse::Group.new('test0')
29
+ .append { [ 'a' ] }
30
+ .append { [ 'c' ] }
31
+ .append { [ 'b' ] }
32
+ .each { |e| e[0] = e[0] * 2 }
33
+ .inject([]) { |a, e| a << e.first; a.sort }
34
+
35
+ r
36
+ # => %w[ aa bb cc ]
37
+ ```
38
+
39
+ ## license
40
+
41
+ MIT, see [LICENSE.txt](LICENSE.txt)
42
+
data/lib/tresse.rb ADDED
@@ -0,0 +1,210 @@
1
+
2
+ require 'thread'
3
+
4
+
5
+ module Tresse
6
+
7
+ VERSION = '0.1.0'
8
+
9
+ class << self
10
+
11
+ attr_accessor :max_work_threads
12
+
13
+ def init
14
+
15
+ @max_work_threads = 7
16
+ @work_queue = Queue.new
17
+ @thread_queue = Queue.new
18
+
19
+ @on_error = lambda do |where, err|
20
+ puts "-" * 80
21
+ p where
22
+ p err
23
+ puts err.backtrace
24
+ puts "-" * 80
25
+ end
26
+
27
+ run
28
+ end
29
+
30
+ def enqueue(batch)
31
+
32
+ @work_queue << batch
33
+
34
+ batch.group
35
+ end
36
+
37
+ def on_error(&block)
38
+
39
+ @on_error = block
40
+ end
41
+
42
+ protected
43
+
44
+ def run
45
+
46
+ @max_work_threads.times { |i| @thread_queue << i }
47
+
48
+ Thread.new do
49
+ loop do
50
+ begin
51
+
52
+ i = @thread_queue.pop
53
+ batch = @work_queue.pop
54
+
55
+ hand_to_worker_thread(i, batch)
56
+
57
+ rescue => err
58
+
59
+ @on_error.call(:in_loop, err)
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def hand_to_worker_thread(i, batch)
66
+
67
+ Thread.new do
68
+ begin
69
+
70
+ Thread.current[:tress] = true
71
+ Thread.current[:i] = i
72
+
73
+ batch.process
74
+
75
+ @thread_queue << i unless i >= @max_work_threads
76
+
77
+ rescue => err
78
+
79
+ @on_error.call(:in_worker_thread, err)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ #
85
+ self.init
86
+
87
+
88
+ class Batch
89
+
90
+ attr_reader :group
91
+ attr_reader :each_index, :value
92
+
93
+ def initialize(group, block_or_group)
94
+
95
+ @group = group
96
+ @bog = block_or_group
97
+
98
+ @each_index = -1
99
+ @value = nil
100
+ end
101
+
102
+ def process
103
+
104
+ @each_index += 1
105
+ @group.send(:hand, self)
106
+ end
107
+
108
+ protected
109
+
110
+ def generate
111
+
112
+ args = [ group ] + [ nil ] * 7
113
+ args = args[0, @bog.method(:call).arity]
114
+
115
+ @value = @bog.call(*args)
116
+ end
117
+ end
118
+
119
+ class Group
120
+
121
+ attr_accessor :name
122
+ attr_reader :batches
123
+
124
+ def initialize(name)
125
+
126
+ @name = name
127
+
128
+ @batches = []
129
+ @eaches = [ nil ]
130
+
131
+ @final = nil
132
+ @final_batches = []
133
+ @final_queue = Queue.new
134
+ end
135
+
136
+ #
137
+ # appending methods
138
+
139
+ def append(o=nil, &block)
140
+
141
+ batch = Tresse::Batch.new(self, o ? o : block)
142
+
143
+ @batches << batch
144
+ Tresse.enqueue(batch)
145
+ end
146
+
147
+ #
148
+ # step methods
149
+
150
+ def each(&block)
151
+
152
+ @eaches << block
153
+
154
+ self
155
+ end
156
+
157
+ #
158
+ # final methods
159
+
160
+ def inject(target, &block)
161
+
162
+ @final = [ target, block ]
163
+
164
+ @final_queue.pop
165
+ end
166
+ alias reduce inject
167
+
168
+ def collect(&block)
169
+
170
+ @final = block
171
+
172
+ @final_queue.pop
173
+ end
174
+ alias map collect
175
+
176
+ protected
177
+
178
+ def hand(batch)
179
+
180
+ if batch.each_index == 0
181
+ batch.send(:generate)
182
+ Tresse.enqueue(batch)
183
+ elsif e = @eaches[batch.each_index]
184
+ args = [ batch.value, batch ]
185
+ args = args[0, e.method(:call).arity.abs]
186
+ e.call(*args)
187
+ Tresse.enqueue(batch)
188
+ else
189
+ queue_for_final(batch)
190
+ end
191
+ end
192
+
193
+ def queue_for_final(batch)
194
+
195
+ @final_batches << batch
196
+
197
+ return if @final_batches.size < @batches.size
198
+
199
+ es = @batches.collect(&:value)
200
+
201
+ @final_queue <<
202
+ if @final.is_a?(Array)
203
+ es.inject(@final[0], &@final[1])
204
+ else
205
+ es.collect(&@final)
206
+ end
207
+ end
208
+ end
209
+ end
210
+
data/tresse.gemspec ADDED
@@ -0,0 +1,37 @@
1
+
2
+ Gem::Specification.new do |s|
3
+
4
+ s.name = 'tresse'
5
+
6
+ s.version = File.read(
7
+ File.expand_path('../lib/tresse.rb', __FILE__)
8
+ ).match(/ VERSION *= *['"]([^'"]+)/)[1]
9
+
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = [ 'John Mettraux' ]
12
+ s.email = [ 'jmettraux@gmail.com' ]
13
+ s.homepage = 'http://github.com/jmettraux/tresse'
14
+ #s.rubyforge_project = 'rufus'
15
+ s.license = 'MIT'
16
+ s.summary = 'a stupid each+map+reduce thing'
17
+
18
+ s.description = %{
19
+ a poorly thought out and stupid each+map+reduce contraption
20
+ }.strip
21
+
22
+ #s.files = `git ls-files`.split("\n")
23
+ s.files = Dir[
24
+ 'README.{md,txt}',
25
+ 'CHANGELOG.{md,txt}', 'CREDITS.{md,txt}', 'LICENSE.{md,txt}',
26
+ 'Makefile',
27
+ 'lib/**/*.rb', #'spec/**/*.rb', 'test/**/*.rb',
28
+ "#{s.name}.gemspec",
29
+ ]
30
+
31
+ #s.add_runtime_dependency 'tzinfo'
32
+
33
+ s.add_development_dependency 'rspec', '~> 3.8'
34
+
35
+ s.require_path = 'lib'
36
+ end
37
+
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tresse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - John Mettraux
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-09-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.8'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.8'
27
+ description: a poorly thought out and stupid each+map+reduce contraption
28
+ email:
29
+ - jmettraux@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - CHANGELOG.md
35
+ - CREDITS.md
36
+ - LICENSE.txt
37
+ - Makefile
38
+ - README.md
39
+ - lib/tresse.rb
40
+ - tresse.gemspec
41
+ homepage: http://github.com/jmettraux/tresse
42
+ licenses:
43
+ - MIT
44
+ metadata: {}
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 2.5.2.3
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: a stupid each+map+reduce thing
65
+ test_files: []