scout-gear 7.2.0 → 8.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/.vimproject +51 -6
- data/VERSION +1 -1
- data/bin/scout +6 -3
- data/lib/rbbt-scout.rb +1 -0
- data/lib/scout/cmd.rb +1 -1
- data/lib/scout/concurrent_stream.rb +33 -29
- data/lib/scout/config.rb +1 -1
- data/lib/scout/exceptions.rb +1 -0
- data/lib/scout/log/color.rb +4 -2
- data/lib/scout/log/progress/report.rb +1 -1
- data/lib/scout/log/progress/util.rb +71 -2
- data/lib/scout/log/progress.rb +1 -1
- data/lib/scout/log/trap.rb +107 -0
- data/lib/scout/log.rb +56 -21
- data/lib/scout/meta_extension.rb +13 -6
- data/lib/scout/misc/digest.rb +1 -1
- data/lib/scout/misc/format.rb +12 -0
- data/lib/scout/misc/helper.rb +31 -0
- data/lib/scout/misc/insist.rb +1 -1
- data/lib/scout/misc/monitor.rb +12 -1
- data/lib/scout/misc/system.rb +10 -0
- data/lib/scout/misc.rb +1 -0
- data/lib/scout/named_array.rb +65 -3
- data/lib/scout/open/lock/lockfile.rb +587 -0
- data/lib/scout/open/lock.rb +28 -2
- data/lib/scout/open/remote.rb +4 -0
- data/lib/scout/open/stream.rb +111 -42
- data/lib/scout/open/util.rb +13 -3
- data/lib/scout/path/find.rb +9 -1
- data/lib/scout/path/util.rb +35 -0
- data/lib/scout/persist/serialize.rb +18 -5
- data/lib/scout/persist.rb +60 -30
- data/lib/scout/resource/path.rb +53 -0
- data/lib/scout/resource/produce.rb +0 -8
- data/lib/scout/resource/util.rb +2 -1
- data/lib/scout/semaphore.rb +8 -1
- data/lib/scout/tmpfile.rb +7 -8
- data/lib/scout/tsv/attach.rb +177 -0
- data/lib/scout/tsv/change_id.rb +40 -0
- data/lib/scout/tsv/dumper.rb +85 -54
- data/lib/scout/tsv/index.rb +188 -20
- data/lib/scout/tsv/open.rb +182 -0
- data/lib/scout/tsv/parser.rb +200 -118
- data/lib/scout/tsv/path.rb +5 -6
- data/lib/scout/tsv/persist/adapter.rb +26 -37
- data/lib/scout/tsv/persist/fix_width_table.rb +327 -0
- data/lib/scout/tsv/persist/serialize.rb +117 -0
- data/lib/scout/tsv/persist/tokyocabinet.rb +6 -3
- data/lib/scout/tsv/persist.rb +4 -2
- data/lib/scout/tsv/transformer.rb +141 -0
- data/lib/scout/tsv/traverse.rb +136 -37
- data/lib/scout/tsv/util/filter.rb +312 -0
- data/lib/scout/tsv/util/process.rb +73 -0
- data/lib/scout/tsv/util/reorder.rb +81 -0
- data/lib/scout/tsv/util/select.rb +265 -0
- data/lib/scout/tsv/util/unzip.rb +86 -0
- data/lib/scout/tsv/util.rb +126 -19
- data/lib/scout/tsv.rb +28 -5
- data/lib/scout/work_queue/socket.rb +6 -1
- data/lib/scout/work_queue/worker.rb +5 -2
- data/lib/scout/work_queue.rb +15 -8
- data/lib/scout/workflow/definition.rb +29 -2
- data/lib/scout/workflow/step/dependencies.rb +24 -4
- data/lib/scout/workflow/step/info.rb +40 -5
- data/lib/scout/workflow/step/progress.rb +14 -0
- data/lib/scout/workflow/step/provenance.rb +8 -7
- data/lib/scout/workflow/step/status.rb +45 -0
- data/lib/scout/workflow/step.rb +104 -33
- data/lib/scout/workflow/task/inputs.rb +14 -20
- data/lib/scout/workflow/task.rb +86 -47
- data/lib/scout/workflow/usage.rb +10 -6
- data/scout-gear.gemspec +30 -3
- data/scout_commands/workflow/task +37 -9
- data/scout_commands/workflow/task_old +2 -2
- data/test/scout/open/test_stream.rb +61 -59
- data/test/scout/path/test_find.rb +10 -1
- data/test/scout/resource/test_produce.rb +15 -0
- data/test/scout/test_meta_extension.rb +25 -0
- data/test/scout/test_named_array.rb +18 -0
- data/test/scout/test_persist.rb +67 -0
- data/test/scout/test_tmpfile.rb +1 -1
- data/test/scout/test_tsv.rb +222 -3
- data/test/scout/test_work_queue.rb +21 -18
- data/test/scout/tsv/persist/test_adapter.rb +11 -1
- data/test/scout/tsv/persist/test_fix_width_table.rb +134 -0
- data/test/scout/tsv/persist/test_tokyocabinet.rb +29 -1
- data/test/scout/tsv/test_attach.rb +227 -0
- data/test/scout/tsv/test_change_id.rb +98 -0
- data/test/scout/tsv/test_dumper.rb +1 -1
- data/test/scout/tsv/test_index.rb +127 -3
- data/test/scout/tsv/test_open.rb +167 -0
- data/test/scout/tsv/test_parser.rb +45 -3
- data/test/scout/tsv/test_persist.rb +9 -0
- data/test/scout/tsv/test_transformer.rb +108 -0
- data/test/scout/tsv/test_traverse.rb +195 -3
- data/test/scout/tsv/test_util.rb +24 -0
- data/test/scout/tsv/util/test_filter.rb +188 -0
- data/test/scout/tsv/util/test_process.rb +47 -0
- data/test/scout/tsv/util/test_reorder.rb +94 -0
- data/test/scout/tsv/util/test_select.rb +58 -0
- data/test/scout/tsv/util/test_unzip.rb +112 -0
- data/test/scout/work_queue/test_socket.rb +0 -1
- data/test/scout/work_queue/test_worker.rb +63 -6
- data/test/scout/workflow/step/test_load.rb +3 -3
- data/test/scout/workflow/step/test_status.rb +31 -0
- data/test/scout/workflow/task/test_inputs.rb +14 -14
- data/test/scout/workflow/test_step.rb +13 -13
- data/test/scout/workflow/test_task.rb +168 -32
- data/test/scout/workflow/test_usage.rb +33 -6
- data/test/test_helper.rb +3 -1
- metadata +29 -2
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
|
3
|
+
module TSV
|
4
|
+
def reorder(key_field = nil, fields = nil, merge: true, one2one: true, **kwargs)
|
5
|
+
res = self.annotate({})
|
6
|
+
res.type = kwargs[:type] if kwargs.include?(:type)
|
7
|
+
kwargs[:one2one] = one2one
|
8
|
+
key_field_name, field_names = traverse key_field, fields, **kwargs do |k,v|
|
9
|
+
if @type == :double && merge && res.include?(k)
|
10
|
+
current = res[k]
|
11
|
+
if merge == :concat
|
12
|
+
v.each_with_index do |new,i|
|
13
|
+
next if new.empty?
|
14
|
+
current[i].concat(new)
|
15
|
+
end
|
16
|
+
else
|
17
|
+
merged = []
|
18
|
+
v.each_with_index do |new,i|
|
19
|
+
next if new.empty?
|
20
|
+
merged[i] = current[i] + new
|
21
|
+
end
|
22
|
+
res[k] = merged
|
23
|
+
end
|
24
|
+
else
|
25
|
+
res[k] = v
|
26
|
+
end
|
27
|
+
end
|
28
|
+
res.key_field = key_field_name
|
29
|
+
res.fields = field_names
|
30
|
+
res
|
31
|
+
end
|
32
|
+
|
33
|
+
def slice(fields, **kwargs)
|
34
|
+
reorder :key, fields, **kwargs
|
35
|
+
end
|
36
|
+
|
37
|
+
def column(field, **kwargs)
|
38
|
+
new_type = case type
|
39
|
+
when :double, :flat
|
40
|
+
:flat
|
41
|
+
else
|
42
|
+
:single
|
43
|
+
end
|
44
|
+
|
45
|
+
kwargs[:type] = new_type
|
46
|
+
slice(field, **kwargs)
|
47
|
+
end
|
48
|
+
|
49
|
+
def transpose_list(key_field="Unkown ID")
|
50
|
+
new_fields = keys.dup
|
51
|
+
new = self.annotate({})
|
52
|
+
TSV.setup(new, :key_field => key_field, :fields => new_fields, :type => type, :filename => filename, :identifiers => identifiers)
|
53
|
+
|
54
|
+
m = Matrix.rows values
|
55
|
+
new_rows = m.transpose.to_a
|
56
|
+
|
57
|
+
fields.zip(new_rows) do |key,row|
|
58
|
+
new[key] = row
|
59
|
+
end
|
60
|
+
|
61
|
+
new
|
62
|
+
end
|
63
|
+
|
64
|
+
def transpose_double(key_field = "Unkown ID")
|
65
|
+
sep = "-!SEP--#{rand 10000}!-"
|
66
|
+
tmp = self.to_list{|v| v * sep}
|
67
|
+
new = tmp.transpose_list(key_field)
|
68
|
+
new.to_double{|v| v.split(sep)}
|
69
|
+
end
|
70
|
+
|
71
|
+
def transpose(key_field = "Unkown ID")
|
72
|
+
case type
|
73
|
+
when :single, :flat
|
74
|
+
self.to_list.transpose_list key_field
|
75
|
+
when :list
|
76
|
+
transpose_list key_field
|
77
|
+
when :double
|
78
|
+
transpose_double key_field
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
module TSV
|
2
|
+
def self.select(key, values, method, fields: nil, field: nil, invert: false, type: nil, sep: nil, &block)
|
3
|
+
return ! select(key, values, method, field: field, invert: false, type: type, sep: sep, &block) if invert
|
4
|
+
|
5
|
+
return yield(key, values) if method.nil? && block_given
|
6
|
+
|
7
|
+
if Hash === method
|
8
|
+
if method.include?(:invert)
|
9
|
+
method = method.dup
|
10
|
+
invert = method.delete(:invert)
|
11
|
+
return select(key, values, method, fields: fields, field: field, invert: invert, type: type, sep: sep, &block)
|
12
|
+
end
|
13
|
+
field = method.keys.first
|
14
|
+
value = method[field]
|
15
|
+
return select(key, values, value, fields: fields, field: field, invert: invert, type: type, sep: sep, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
if field
|
19
|
+
field = fields.index(field) if fields && String === field
|
20
|
+
set = field == :key ? [key] : (type == :double ? values[field].split(sep) : values[field])
|
21
|
+
else
|
22
|
+
set = [key, (type == :double ? values.collect{|v| v.split(sep) } : values)]
|
23
|
+
end
|
24
|
+
|
25
|
+
if Array === set
|
26
|
+
set.flatten!
|
27
|
+
else
|
28
|
+
set = [set]
|
29
|
+
end
|
30
|
+
|
31
|
+
case method
|
32
|
+
when Array
|
33
|
+
(method & set).any?
|
34
|
+
when Regexp
|
35
|
+
set.select{|v| v =~ method }.any?
|
36
|
+
when Symbol
|
37
|
+
set.first.send(method)
|
38
|
+
when Numeric
|
39
|
+
set.size > method
|
40
|
+
when String
|
41
|
+
if block_given?
|
42
|
+
field = method
|
43
|
+
field = fields.index?(field) if fields && String === field
|
44
|
+
case
|
45
|
+
when block.arity == 1
|
46
|
+
if (method == key_field or method == :key)
|
47
|
+
yield(key)
|
48
|
+
else
|
49
|
+
yield(values[method])
|
50
|
+
end
|
51
|
+
when block.arity == 2
|
52
|
+
if (method == key_field or method == :key)
|
53
|
+
yield(key, key)
|
54
|
+
else
|
55
|
+
yield(key, values[method])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
elsif m = method.match(/^([<>]=?)(.*)/)
|
59
|
+
set.select{|v| v.to_f.send($1, $2.to_f) }.any?
|
60
|
+
else
|
61
|
+
set.select{|v| v == method }.any?
|
62
|
+
end
|
63
|
+
when Proc
|
64
|
+
set.select{|v| method.call(v) }.any?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def select(method = nil, invert = false, &block)
|
69
|
+
new = TSV.setup({}, :key_field => key_field, :fields => fields, :type => type, :filename => filename, :identifiers => identifiers)
|
70
|
+
|
71
|
+
self.annotate(new)
|
72
|
+
|
73
|
+
case
|
74
|
+
when (method.nil? and block_given?)
|
75
|
+
through do |key, values|
|
76
|
+
new[key] = values if invert ^ (yield key, values)
|
77
|
+
end
|
78
|
+
when Array === method
|
79
|
+
method = Set.new method
|
80
|
+
with_unnamed do
|
81
|
+
case type
|
82
|
+
when :single
|
83
|
+
through do |key, value|
|
84
|
+
new[key] = value if invert ^ (method.include? key or method.include? value)
|
85
|
+
end
|
86
|
+
when :list, :flat
|
87
|
+
through do |key, values|
|
88
|
+
new[key] = values if invert ^ (method.include? key or (method & values).length > 0)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
through do |key, values|
|
92
|
+
new[key] = values if invert ^ (method.include? key or (method & values.flatten).length > 0)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
when Regexp === method
|
97
|
+
with_unnamed do
|
98
|
+
through do |key, values|
|
99
|
+
new[key] = values if invert ^ ([key,values].flatten.select{|v| v =~ method}.any?)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
when ((String === method) || (Symbol === method))
|
103
|
+
if block_given?
|
104
|
+
case
|
105
|
+
when block.arity == 1
|
106
|
+
with_unnamed do
|
107
|
+
case
|
108
|
+
when (method == key_field or method == :key)
|
109
|
+
through do |key, values|
|
110
|
+
new[key] = values if invert ^ (yield(key))
|
111
|
+
end
|
112
|
+
when (type == :single or type == :flat)
|
113
|
+
through do |key, value|
|
114
|
+
new[key] = value if invert ^ (yield(value))
|
115
|
+
end
|
116
|
+
else
|
117
|
+
pos = identify_field method
|
118
|
+
raise "Field #{ method } not identified. Available: #{ fields * ", " }" if pos.nil?
|
119
|
+
|
120
|
+
through do |key, values|
|
121
|
+
new[key] = values if invert ^ (yield(values[pos]))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
when block.arity == 2
|
126
|
+
with_unnamed do
|
127
|
+
case
|
128
|
+
when (method == key_field or method == :key)
|
129
|
+
through do |key, values|
|
130
|
+
new[key] = values if invert ^ (yield(key, key))
|
131
|
+
end
|
132
|
+
when (type == :single or type == :flat)
|
133
|
+
through do |key, value|
|
134
|
+
new[key] = value if invert ^ (yield(key, value))
|
135
|
+
end
|
136
|
+
else
|
137
|
+
pos = identify_field method
|
138
|
+
through do |key, values|
|
139
|
+
new[key] = values if invert ^ (yield(key, values[pos]))
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
else
|
147
|
+
with_unnamed do
|
148
|
+
through do |key, values|
|
149
|
+
new[key] = values if invert ^ ([key,values].flatten.select{|v| v == method}.any?)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
when Hash === method
|
154
|
+
key = method.keys.first
|
155
|
+
method = method.values.first
|
156
|
+
case
|
157
|
+
when ((Array === method) and (key == :key or key_field == key))
|
158
|
+
with_unnamed do
|
159
|
+
keys.each do |key|
|
160
|
+
new[key] = self[key] if invert ^ (method.include? key)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
when Array === method
|
164
|
+
with_unnamed do
|
165
|
+
method = Set.new method unless Set === method
|
166
|
+
case type
|
167
|
+
when :single
|
168
|
+
through :key, key do |key, value|
|
169
|
+
new[key] = self[key] if invert ^ (method.include? value)
|
170
|
+
end
|
171
|
+
when :list
|
172
|
+
through :key, key do |key, values|
|
173
|
+
new[key] = self[key] if invert ^ (method.include? values.first)
|
174
|
+
end
|
175
|
+
when :flat #untested
|
176
|
+
through :key, key do |key, values|
|
177
|
+
new[key] = self[key] if invert ^ ((method & values.flatten).any?)
|
178
|
+
end
|
179
|
+
else
|
180
|
+
through :key, key do |key, values|
|
181
|
+
new[key] = self[key] if invert ^ ((method & values.flatten).any?)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
when Regexp === method
|
187
|
+
with_unnamed do
|
188
|
+
through :key, key do |key, values|
|
189
|
+
values = [values] if type == :single
|
190
|
+
new[key] = self[key] if invert ^ (values.flatten.select{|v| v =~ method}.any?)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
when ((String === method) and (method =~ /name:(.*)/))
|
195
|
+
name = $1
|
196
|
+
old_unnamed = self.unnamed
|
197
|
+
self.unnamed = false
|
198
|
+
if name.strip =~ /^\/(.*)\/$/
|
199
|
+
regexp = Regexp.new $1
|
200
|
+
through :key, key do |key, values|
|
201
|
+
case type
|
202
|
+
when :single
|
203
|
+
values = values.annotate([values])
|
204
|
+
when :double
|
205
|
+
values = values[0]
|
206
|
+
end
|
207
|
+
new[key] = self[key] if invert ^ (values.select{|v| v.name =~ regexp}.any?)
|
208
|
+
end
|
209
|
+
else
|
210
|
+
through :key, key do |key, values|
|
211
|
+
case type
|
212
|
+
when :single
|
213
|
+
values = values.annotate([values])
|
214
|
+
when :double
|
215
|
+
values = values[0]
|
216
|
+
end
|
217
|
+
new[key] = self[key] if invert ^ (values.select{|v| v.name == name}.any?)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
self.unnamed = old_unnamed
|
221
|
+
|
222
|
+
when String === method
|
223
|
+
if method =~ /^([<>]=?)(.*)/
|
224
|
+
with_unnamed do
|
225
|
+
through :key, key do |key, values|
|
226
|
+
value = Array === values ? values.flatten.first : values
|
227
|
+
new[key] = self[key] if value.to_f.send($1, $2.to_f)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
else
|
231
|
+
with_unnamed do
|
232
|
+
through :key, key do |key, values|
|
233
|
+
values = [values] if type == :single
|
234
|
+
new[key] = self[key] if invert ^ (values.flatten.select{|v| v == method}.length > 0)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
when Numeric === method
|
239
|
+
with_unnamed do
|
240
|
+
through :key, key do |key, values|
|
241
|
+
new[key] = self[key] if invert ^ (values.flatten.length >= method)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
when Proc === method
|
245
|
+
with_unnamed do
|
246
|
+
through :key, key do |key, values|
|
247
|
+
values = [values] if type == :single
|
248
|
+
new[key] = self[key] if invert ^ (values.flatten.select{|v| method.call(v)}.length > 0)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
new
|
254
|
+
end
|
255
|
+
|
256
|
+
def subset(keys)
|
257
|
+
new = self.annotate({})
|
258
|
+
self.with_unnamed do
|
259
|
+
keys.each do |k|
|
260
|
+
new[k] = self[k] if self.include?(k)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
new
|
264
|
+
end
|
265
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module TSV
|
2
|
+
|
3
|
+
def self.unzip(source, field, target: nil, sep: ":", delete: true, type: :list, merge: false, one2one: true, bar: nil)
|
4
|
+
source = TSV::Parser.new source if String === source
|
5
|
+
|
6
|
+
field_pos = source.identify_field(field)
|
7
|
+
new_fields = source.fields.dup
|
8
|
+
field_name = new_fields[field_pos]
|
9
|
+
new_fields.delete_at(field_pos) if delete
|
10
|
+
new_key_field = [source.key_field, field_name] * sep
|
11
|
+
type = :double if merge
|
12
|
+
|
13
|
+
stream = target == :stream
|
14
|
+
|
15
|
+
target = case target
|
16
|
+
when :stream
|
17
|
+
TSV::Dumper.new(source.options.merge(sep: "\t"))
|
18
|
+
when nil
|
19
|
+
TSV.setup({})
|
20
|
+
else
|
21
|
+
target
|
22
|
+
end
|
23
|
+
|
24
|
+
target.fields = new_fields
|
25
|
+
target.key_field = new_key_field
|
26
|
+
target.type = type
|
27
|
+
|
28
|
+
transformer = TSV::Transformer.new source, target, unnamed: true
|
29
|
+
|
30
|
+
bar = "Unzip #{new_key_field}" if TrueClass === bar
|
31
|
+
|
32
|
+
transformer.traverse unnamed: true, one2one: one2one, bar: bar do |k,v|
|
33
|
+
if source.type == :double
|
34
|
+
if one2one
|
35
|
+
res = NamedArray.zip_fields(v).collect do |_v|
|
36
|
+
field_value = _v[field_pos]
|
37
|
+
|
38
|
+
if delete
|
39
|
+
new_values = _v.dup
|
40
|
+
new_values.delete_at field_pos
|
41
|
+
else
|
42
|
+
new_values = _v
|
43
|
+
end
|
44
|
+
|
45
|
+
new_key = [k,field_value] * sep
|
46
|
+
new_values = new_values.collect{|e| [e] } if transformer.type == :double
|
47
|
+
[new_key, new_values]
|
48
|
+
end
|
49
|
+
else
|
50
|
+
all_values = v.collect{|e| e.dup }
|
51
|
+
all_values.delete_at field_pos if delete
|
52
|
+
res = NamedArray.zip_fields(v).collect do |_v|
|
53
|
+
field_value = _v[field_pos]
|
54
|
+
|
55
|
+
new_key = [k,field_value] * sep
|
56
|
+
new_values = all_values if transformer.type == :double
|
57
|
+
[new_key, new_values]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
MultipleResult.setup(res)
|
62
|
+
else
|
63
|
+
field_value = v[field_pos]
|
64
|
+
|
65
|
+
if delete
|
66
|
+
new_values = v.dup
|
67
|
+
new_values.delete_at field_pos
|
68
|
+
else
|
69
|
+
new_values = v
|
70
|
+
end
|
71
|
+
|
72
|
+
new_key = [k,field_value] * sep
|
73
|
+
|
74
|
+
new_values = new_values.collect{|e| [e] } if transformer.type == :double
|
75
|
+
|
76
|
+
[new_key, new_values]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
stream ? transformer : transformer.tsv(merge: merge)
|
81
|
+
end
|
82
|
+
|
83
|
+
def unzip(*args, **kwargs)
|
84
|
+
TSV.unzip(self, *args, **kwargs)
|
85
|
+
end
|
86
|
+
end
|
data/lib/scout/tsv/util.rb
CHANGED
@@ -1,24 +1,131 @@
|
|
1
1
|
#require_relative '../../../modules/rbbt-util/lib/rbbt/tsv/manipulate'
|
2
2
|
#Log.warn "USING OLD RBBT CODE: #{__FILE__}"
|
3
|
+
require_relative 'traverse'
|
4
|
+
require_relative 'util/filter'
|
5
|
+
require_relative 'util/process'
|
6
|
+
require_relative 'util/select'
|
7
|
+
require_relative 'util/reorder'
|
8
|
+
require_relative 'util/unzip'
|
3
9
|
module TSV
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# end
|
10
|
-
# end
|
11
|
-
#end
|
12
|
-
|
13
|
-
#[:select, :reject].each do |method|
|
14
|
-
# define_method(method) do |*args,&block|
|
15
|
-
# res = super(*args) do |k,v|
|
16
|
-
# NamedArray.setup(v, @fields) unless @unnamed
|
17
|
-
# block.call k, v
|
18
|
-
# end
|
19
|
-
# self.annotate(res)
|
20
|
-
# res
|
21
|
-
# end
|
22
|
-
#end
|
10
|
+
def self.identify_field(key_field, fields, name, strict: nil)
|
11
|
+
return :key if name == :key || (! strict && NamedArray.field_match(key_field, name))
|
12
|
+
name.collect!{|n| key_field == n ? :key : n } if Array === name
|
13
|
+
NamedArray.identify_name(fields, name, strict: strict)
|
14
|
+
end
|
23
15
|
|
16
|
+
def identify_field(name, strict: nil)
|
17
|
+
TSV.identify_field(@key_field, @fields, name, strict: strict)
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](key, *rest)
|
21
|
+
v = super(key, *rest)
|
22
|
+
NamedArray.setup(v, @fields, key) unless @unnamed || ! (Array === v)
|
23
|
+
v
|
24
|
+
end
|
25
|
+
|
26
|
+
def options
|
27
|
+
extension_attr_hash
|
28
|
+
end
|
29
|
+
|
30
|
+
def zip_new(key, values, insitu: :lax)
|
31
|
+
values = values.collect{|v| Array === v ? v : [v] } unless Array === values.first
|
32
|
+
if current_values = self[key]
|
33
|
+
if insitu == :lax
|
34
|
+
self[key] = NamedArray.add_zipped(current_values, values)
|
35
|
+
elsif insitu
|
36
|
+
NamedArray.add_zipped(current_values, values)
|
37
|
+
else
|
38
|
+
self[key] = NamedArray.add_zipped(current_values.dup, values)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
if insitu && insitu != :lax
|
42
|
+
self[key] = values.dup
|
43
|
+
else
|
44
|
+
self[key] = values
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def each(*args, &block)
|
50
|
+
if block_given?
|
51
|
+
super(*args) do |k,v|
|
52
|
+
NamedArray.setup(v, @fields) unless @unnamed || ! (Array === v)
|
53
|
+
block.call(k, v)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
super(*args)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def collect(*args, &block)
|
61
|
+
if block_given?
|
62
|
+
res = []
|
63
|
+
each do |k,v|
|
64
|
+
res << yield(k, v)
|
65
|
+
end
|
66
|
+
res
|
67
|
+
else
|
68
|
+
super(*args)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def with_unnamed(unnamed = true)
|
73
|
+
begin
|
74
|
+
old_unnamed = @unnamed
|
75
|
+
@unnamed = unnamed
|
76
|
+
yield
|
77
|
+
ensure
|
78
|
+
@unnamed = old_unnamed
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def summary
|
83
|
+
key = nil
|
84
|
+
values = nil
|
85
|
+
self.each do |k, v|
|
86
|
+
key = k
|
87
|
+
values = v
|
88
|
+
break
|
89
|
+
end
|
90
|
+
|
91
|
+
filename = @filename
|
92
|
+
filename = "No filename" if filename.nil? || String === filename && filename.empty?
|
93
|
+
filename.find if Path === filename
|
94
|
+
filename = File.basename(filename) + " [" + File.basename(persistence_path) + "]" if respond_to?(:persistence_path) and persistence_path
|
95
|
+
|
96
|
+
with_unnamed do
|
97
|
+
<<-EOF
|
98
|
+
Filename = #{filename}
|
99
|
+
Key field = #{key_field || "*No key field*"}
|
100
|
+
Fields = #{fields ? Log.fingerprint(fields) : "*No field info*"}
|
101
|
+
Type = #{type}
|
102
|
+
Size = #{size}
|
103
|
+
namespace = #{Log.fingerprint namespace}
|
104
|
+
identifiers = #{Log.fingerprint identifiers}
|
105
|
+
Example:
|
106
|
+
- #{key} -- #{Log.fingerprint values }
|
107
|
+
EOF
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def all_fields
|
112
|
+
return [] if @fields.nil?
|
113
|
+
[@key_field] + @fields
|
114
|
+
end
|
115
|
+
|
116
|
+
def options
|
117
|
+
self.extension_attr_hash
|
118
|
+
end
|
119
|
+
|
120
|
+
def fingerprint
|
121
|
+
"TSV:{"<< Log.fingerprint(self.all_fields|| []) << ";" << Log.fingerprint(self.keys) << "}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def digest_str
|
125
|
+
fingerprint
|
126
|
+
end
|
127
|
+
|
128
|
+
def inspect
|
129
|
+
fingerprint
|
130
|
+
end
|
24
131
|
end
|
data/lib/scout/tsv.rb
CHANGED
@@ -2,26 +2,49 @@ require_relative 'meta_extension'
|
|
2
2
|
require_relative 'tsv/util'
|
3
3
|
require_relative 'tsv/parser'
|
4
4
|
require_relative 'tsv/dumper'
|
5
|
+
require_relative 'tsv/transformer'
|
5
6
|
require_relative 'tsv/persist'
|
6
7
|
require_relative 'tsv/index'
|
7
8
|
require_relative 'tsv/path'
|
8
9
|
require_relative 'tsv/traverse'
|
10
|
+
require_relative 'tsv/open'
|
11
|
+
require_relative 'tsv/attach'
|
12
|
+
require_relative 'tsv/change_id'
|
9
13
|
|
10
14
|
module TSV
|
11
15
|
extend MetaExtension
|
12
|
-
extension_attr :key_field, :fields, :type, :filename, :namespace, :unnamed
|
16
|
+
extension_attr :key_field, :fields, :type, :filename, :namespace, :unnamed, :identifiers
|
17
|
+
|
18
|
+
def self.str2options(str)
|
19
|
+
field_options,_sep, rest = str.partition("#")
|
20
|
+
key, fields_str = field_options.split("~")
|
21
|
+
|
22
|
+
fields = fields_str.nil? ? [] : fields_str.split(/,\s*/)
|
23
|
+
|
24
|
+
rest = ":type=" << rest if rest =~ /^:?\w+$/
|
25
|
+
rest_options = rest.nil? ? {} : IndiferentHash.string2hash(rest)
|
26
|
+
|
27
|
+
{:key_field => key, :fields => fields}.merge(rest_options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.str_setup(option_str, obj)
|
31
|
+
options = TSV.str2options(option_str)
|
32
|
+
setup(obj, options)
|
33
|
+
end
|
13
34
|
|
14
35
|
def self.open(file, options = {})
|
15
|
-
persist, type = IndiferentHash.process_options options, :persist, :persist_type, :persist => false, :persist_type => "HDB"
|
16
|
-
|
36
|
+
persist, type, grep, invert_grep = IndiferentHash.process_options options, :persist, :persist_type, :grep, :invert_grep, :persist => false, :persist_type => "HDB"
|
37
|
+
type = type.to_sym if type
|
38
|
+
file = StringIO.new file if String === file && ! (Path === file) && file.index("\n")
|
39
|
+
Persist.persist(file, type, options.merge(:persist => persist, :prefix => "Tsv", :other_options => options)) do |filename|
|
17
40
|
data = filename ? ScoutCabinet.open(filename, true, type) : nil
|
18
41
|
options[:data] = data if data
|
19
42
|
options[:filename] = file
|
20
|
-
|
43
|
+
Log.debug "TSV open #{Log.fingerprint file}"
|
44
|
+
Open.open(file, grep: grep, invert_grep: invert_grep) do |f|
|
21
45
|
TSV.parse(f, **options)
|
22
46
|
end
|
23
47
|
end
|
24
48
|
end
|
25
|
-
|
26
49
|
end
|
27
50
|
|
@@ -3,7 +3,7 @@ require 'scout/semaphore'
|
|
3
3
|
require 'scout/exceptions'
|
4
4
|
class WorkQueue
|
5
5
|
class Socket
|
6
|
-
attr_accessor :sread, :swrite, :write_sem, :read_sem, :cleaned
|
6
|
+
attr_accessor :sread, :swrite, :write_sem, :read_sem, :cleaned, :exception
|
7
7
|
def initialize(serializer = nil)
|
8
8
|
@sread, @swrite = Open.pipe
|
9
9
|
|
@@ -112,6 +112,11 @@ class WorkQueue
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
+
def abort(exception)
|
116
|
+
@exception = exception
|
117
|
+
@swrite.close unless closed_write?
|
118
|
+
end
|
119
|
+
|
115
120
|
alias write push
|
116
121
|
|
117
122
|
alias read pop
|
@@ -27,8 +27,10 @@ class WorkQueue
|
|
27
27
|
rescue Interrupt
|
28
28
|
rescue Exception
|
29
29
|
output.write WorkerException.new($!, Process.pid)
|
30
|
-
exit -1
|
30
|
+
Process.exit! -1
|
31
|
+
ensure
|
31
32
|
end
|
33
|
+
Process.exit! 0
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
@@ -36,7 +38,8 @@ class WorkQueue
|
|
36
38
|
begin
|
37
39
|
Log.debug "Aborting worker #{@pid}"
|
38
40
|
Process.kill "INT", @pid
|
39
|
-
rescue Errno::ECHILD
|
41
|
+
rescue Errno::ECHILD
|
42
|
+
rescue Errno::ESRCH
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|