scout-gear 7.2.0 → 8.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|