scout-gear 7.1.0 → 7.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.vimproject +65 -2
- data/VERSION +1 -1
- data/bin/scout +5 -1
- data/lib/rbbt-scout.rb +5 -0
- data/lib/scout/concurrent_stream.rb +13 -8
- data/lib/scout/config.rb +168 -0
- data/lib/scout/exceptions.rb +5 -3
- data/lib/scout/indiferent_hash/options.rb +1 -0
- data/lib/scout/indiferent_hash.rb +4 -2
- data/lib/scout/log/color.rb +3 -2
- data/lib/scout/log/progress/report.rb +1 -0
- data/lib/scout/log/progress/util.rb +66 -1
- data/lib/scout/log/progress.rb +5 -3
- data/lib/scout/log.rb +3 -2
- data/lib/scout/misc/helper.rb +31 -0
- data/lib/scout/misc/monitor.rb +4 -1
- data/lib/scout/misc/system.rb +15 -0
- data/lib/scout/misc.rb +2 -0
- data/lib/scout/named_array.rb +68 -0
- data/lib/scout/open/stream.rb +58 -33
- data/lib/scout/path/find.rb +27 -3
- data/lib/scout/path/util.rb +7 -4
- data/lib/scout/persist/serialize.rb +7 -14
- data/lib/scout/persist.rb +46 -12
- data/lib/scout/resource/produce.rb +7 -94
- data/lib/scout/resource/software.rb +176 -0
- data/lib/scout/semaphore.rb +8 -1
- data/lib/scout/tsv/dumper.rb +112 -0
- data/lib/scout/tsv/index.rb +161 -0
- data/lib/scout/tsv/open.rb +128 -0
- data/lib/scout/tsv/parser.rb +230 -30
- data/lib/scout/tsv/path.rb +13 -0
- data/lib/scout/tsv/persist/adapter.rb +367 -0
- data/lib/scout/tsv/persist/fix_width_table.rb +324 -0
- data/lib/scout/tsv/persist/serialize.rb +117 -0
- data/lib/scout/tsv/persist/tokyocabinet.rb +113 -0
- data/lib/scout/tsv/persist.rb +13 -0
- data/lib/scout/tsv/traverse.rb +143 -0
- data/lib/scout/tsv/util/filter.rb +303 -0
- data/lib/scout/tsv/util/process.rb +73 -0
- data/lib/scout/tsv/util/select.rb +220 -0
- data/lib/scout/tsv/util.rb +82 -0
- data/lib/scout/tsv.rb +16 -3
- data/lib/scout/work_queue/worker.rb +4 -4
- data/lib/scout/work_queue.rb +22 -7
- data/lib/scout/workflow/definition.rb +101 -4
- data/lib/scout/workflow/step/config.rb +18 -0
- data/lib/scout/workflow/step/dependencies.rb +40 -0
- data/lib/scout/workflow/step/file.rb +15 -0
- data/lib/scout/workflow/step/info.rb +35 -4
- data/lib/scout/workflow/step/progress.rb +14 -0
- data/lib/scout/workflow/step/provenance.rb +148 -0
- data/lib/scout/workflow/step.rb +71 -17
- data/lib/scout/workflow/task.rb +10 -5
- data/lib/scout/workflow/usage.rb +3 -1
- data/lib/scout/workflow.rb +11 -3
- data/lib/scout-gear.rb +1 -0
- data/lib/scout.rb +1 -0
- data/scout-gear.gemspec +64 -10
- data/scout_commands/find +1 -1
- data/scout_commands/workflow/task +16 -9
- data/scout_commands/workflow/task_old +2 -2
- data/share/software/install_helpers +523 -0
- data/test/scout/log/test_progress.rb +0 -2
- data/test/scout/misc/test_system.rb +21 -0
- data/test/scout/open/test_stream.rb +160 -1
- data/test/scout/path/test_find.rb +14 -7
- data/test/scout/resource/test_software.rb +24 -0
- data/test/scout/test_config.rb +66 -0
- data/test/scout/test_meta_extension.rb +10 -0
- data/test/scout/test_named_array.rb +19 -0
- data/test/scout/test_persist.rb +96 -0
- data/test/scout/test_tmpfile.rb +1 -1
- data/test/scout/test_tsv.rb +50 -1
- data/test/scout/test_work_queue.rb +41 -13
- data/test/scout/tsv/persist/test_adapter.rb +44 -0
- data/test/scout/tsv/persist/test_fix_width_table.rb +134 -0
- data/test/scout/tsv/persist/test_tokyocabinet.rb +92 -0
- data/test/scout/tsv/test_dumper.rb +44 -0
- data/test/scout/tsv/test_index.rb +156 -0
- data/test/scout/tsv/test_open.rb +9 -0
- data/test/scout/tsv/test_parser.rb +114 -3
- data/test/scout/tsv/test_persist.rb +43 -0
- data/test/scout/tsv/test_traverse.rb +116 -0
- data/test/scout/tsv/test_util.rb +23 -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_select.rb +44 -0
- data/test/scout/work_queue/test_worker.rb +66 -9
- data/test/scout/workflow/step/test_dependencies.rb +25 -0
- data/test/scout/workflow/step/test_info.rb +15 -17
- data/test/scout/workflow/step/test_load.rb +19 -21
- data/test/scout/workflow/step/test_provenance.rb +25 -0
- data/test/scout/workflow/test_step.rb +206 -10
- data/test/scout/workflow/test_task.rb +0 -3
- data/test/test_helper.rb +9 -1
- metadata +50 -6
data/lib/scout/tsv/parser.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
+
require_relative '../named_array'
|
1
2
|
module TSV
|
2
3
|
def self.cast_value(value, cast)
|
3
4
|
if Array === value
|
4
5
|
value.collect{|e| cast_value(e, cast) }
|
5
6
|
else
|
6
|
-
|
7
|
+
if Proc === cast
|
8
|
+
cast.call value
|
9
|
+
else
|
10
|
+
value.send(cast)
|
11
|
+
end
|
7
12
|
end
|
8
13
|
end
|
9
14
|
|
@@ -13,9 +18,11 @@ module TSV
|
|
13
18
|
if positions.nil? && key == 0
|
14
19
|
key = items.shift
|
15
20
|
elsif positions.nil?
|
16
|
-
key = items.
|
21
|
+
key = items.delete_at(key)
|
22
|
+
key = key.split(sep2) if type == :double
|
17
23
|
else
|
18
24
|
key, items = items[key], items.values_at(*positions)
|
25
|
+
key = key.split(sep2) if type == :double
|
19
26
|
end
|
20
27
|
|
21
28
|
items = case type
|
@@ -29,7 +36,6 @@ module TSV
|
|
29
36
|
items.collect{|i| i.split(sep2, -1) }
|
30
37
|
end
|
31
38
|
|
32
|
-
key = key.partition(sep2).first if type == :double
|
33
39
|
|
34
40
|
if cast
|
35
41
|
items = cast_value(items, cast)
|
@@ -38,10 +44,12 @@ module TSV
|
|
38
44
|
[key, items]
|
39
45
|
end
|
40
46
|
|
41
|
-
def self.parse_stream(stream, data: nil,
|
47
|
+
def self.parse_stream(stream, data: nil, source_type: nil, type: :list, merge: true, one2one: false, fix: true, bar: false, first_line: nil, **kargs, &block)
|
42
48
|
begin
|
43
49
|
bar = Log::ProgressBar.new_bar(bar) if bar
|
44
50
|
|
51
|
+
source_type = type if source_type.nil?
|
52
|
+
|
45
53
|
data = {} if data.nil?
|
46
54
|
merge = false if type != :double
|
47
55
|
line = first_line || stream.gets
|
@@ -50,30 +58,86 @@ module TSV
|
|
50
58
|
line.strip!
|
51
59
|
line = Misc.fixutf8(line) if fix
|
52
60
|
bar.tick if bar
|
53
|
-
key, items = parse_line(line, type:
|
61
|
+
key, items = parse_line(line, type: source_type, **kargs)
|
54
62
|
|
55
|
-
if
|
56
|
-
|
57
|
-
|
58
|
-
|
63
|
+
if Array === key
|
64
|
+
keys = key
|
65
|
+
if one2one
|
66
|
+
key_items = keys.length.times.collect{|i| items.collect{|list| [list[i] || list[0]] } }
|
67
|
+
else
|
68
|
+
key_items = false
|
69
|
+
end
|
70
|
+
else
|
71
|
+
keys = [key]
|
72
|
+
key_items = false
|
59
73
|
end
|
60
74
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
75
|
+
keys.each_with_index do |key,i|
|
76
|
+
if key_items
|
77
|
+
these_items = key_items[i]
|
78
|
+
else
|
79
|
+
these_items = items
|
80
|
+
end
|
81
|
+
|
82
|
+
these_items =
|
83
|
+
case [source_type, type]
|
84
|
+
when [:single, :single]
|
85
|
+
these_items
|
86
|
+
when [:list, :single]
|
87
|
+
these_items.first
|
88
|
+
when [:flat, :single]
|
89
|
+
these_items.first
|
90
|
+
when [:double, :single]
|
91
|
+
these_items.first.first
|
92
|
+
when [:single, :list]
|
93
|
+
[these_items]
|
94
|
+
when [:list, :list]
|
95
|
+
these_items
|
96
|
+
when [:flat, :list]
|
97
|
+
these_items
|
98
|
+
when [:double, :list]
|
99
|
+
these_items.collect{|l| l.first }
|
100
|
+
when [:single, :flat]
|
101
|
+
[these_items]
|
102
|
+
when [:list, :flat]
|
103
|
+
these_items
|
104
|
+
when [:flat, :flat]
|
105
|
+
these_items
|
106
|
+
when [:double, :flat]
|
107
|
+
these_items.flatten
|
108
|
+
when [:single, :double]
|
109
|
+
[[these_items]]
|
110
|
+
when [:list, :double]
|
111
|
+
these_items.collect{|l| [l] }
|
112
|
+
when [:flat, :double]
|
113
|
+
[these_items]
|
114
|
+
when [:double, :double]
|
115
|
+
these_items
|
69
116
|
end
|
117
|
+
|
118
|
+
if block_given?
|
119
|
+
res = block.call(key, these_items)
|
120
|
+
data[key] = res unless res.nil? || FalseClass === data
|
121
|
+
next
|
122
|
+
end
|
123
|
+
|
124
|
+
if ! merge || ! data.include?(key)
|
125
|
+
data[key] = these_items
|
70
126
|
else
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
127
|
+
current = data[key]
|
128
|
+
if merge == :concat
|
129
|
+
these_items.each_with_index do |new,i|
|
130
|
+
next if new.empty?
|
131
|
+
current[i].concat(new)
|
132
|
+
end
|
133
|
+
else
|
134
|
+
merged = []
|
135
|
+
these_items.each_with_index do |new,i|
|
136
|
+
next if new.empty?
|
137
|
+
merged[i] = current[i] + new
|
138
|
+
end
|
139
|
+
data[key] = merged
|
75
140
|
end
|
76
|
-
data[key] = merged
|
77
141
|
end
|
78
142
|
end
|
79
143
|
ensure
|
@@ -86,7 +150,7 @@ module TSV
|
|
86
150
|
end
|
87
151
|
end
|
88
152
|
|
89
|
-
def self.parse_header(stream, fix: true, header_hash: '#', sep: "\
|
153
|
+
def self.parse_header(stream, fix: true, header_hash: '#', sep: "\t")
|
90
154
|
raise "Closed stream" if IO === stream && stream.closed?
|
91
155
|
|
92
156
|
options = {}
|
@@ -131,14 +195,150 @@ module TSV
|
|
131
195
|
[options, key_field, fields, first_line, preamble]
|
132
196
|
end
|
133
197
|
|
134
|
-
|
135
|
-
|
198
|
+
KEY_PARAMETERS = begin
|
199
|
+
params = []
|
200
|
+
(method(:parse_line).parameters + method(:parse_stream).parameters).each do |type, name|
|
201
|
+
params << name if type == :key
|
202
|
+
end
|
203
|
+
params
|
204
|
+
end
|
136
205
|
|
137
|
-
|
138
|
-
|
139
|
-
|
206
|
+
class Parser
|
207
|
+
attr_accessor :stream, :options, :key_field, :fields, :first_line, :preamble
|
208
|
+
def initialize(file, fix: true, header_hash: "#", sep: "\t")
|
209
|
+
if IO === file
|
210
|
+
@stream = file
|
211
|
+
else
|
212
|
+
@stream = Open.open(file)
|
213
|
+
end
|
214
|
+
@options, @key_field, @fields, @first_line, @preamble = TSV.parse_header(@stream, fix:fix, header_hash:header_hash, sep:sep)
|
215
|
+
@options[:sep] = sep if @options[:sep].nil?
|
216
|
+
end
|
217
|
+
|
218
|
+
def all_fields
|
219
|
+
[@key_field] + @fields
|
140
220
|
end
|
141
|
-
|
142
|
-
|
221
|
+
|
222
|
+
def traverse(key_field: nil, fields: nil, filename: nil, namespace: nil, **kwargs, &block)
|
223
|
+
if fields
|
224
|
+
all_field_names ||= [@key_field] + @fields
|
225
|
+
positions = NamedArray.identify_name(all_field_names, fields)
|
226
|
+
kwargs[:positions] = positions
|
227
|
+
field_names = all_field_names.values_at *positions
|
228
|
+
else
|
229
|
+
field_names = @fields
|
230
|
+
end
|
231
|
+
|
232
|
+
if key_field
|
233
|
+
all_field_names ||= [@key_field] + @fields
|
234
|
+
key = NamedArray.identify_name(all_field_names, key_field)
|
235
|
+
kwargs[:key] = key == :key ? 0 : key
|
236
|
+
key_field_name = key === :key ? @key_field : all_field_names[key]
|
237
|
+
if fields.nil?
|
238
|
+
field_names = all_field_names - [@key_field]
|
239
|
+
end
|
240
|
+
else
|
241
|
+
key_field_name = @key_field
|
242
|
+
end
|
243
|
+
|
244
|
+
@options.each do |option,value|
|
245
|
+
option = option.to_sym
|
246
|
+
next unless KEY_PARAMETERS.include? option
|
247
|
+
kwargs[option] = value unless kwargs.include?(option)
|
248
|
+
end
|
249
|
+
|
250
|
+
kwargs[:source_type] = @options[:type]
|
251
|
+
kwargs[:data] = false if kwargs[:data].nil?
|
252
|
+
|
253
|
+
data = TSV.parse_stream(@stream, first_line: @first_line, **kwargs, &block)
|
254
|
+
|
255
|
+
if data
|
256
|
+
TSV.setup(data, :key_field => key_field_name, :fields => field_names, :type => @type)
|
257
|
+
else
|
258
|
+
self
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
143
262
|
end
|
263
|
+
|
264
|
+
def self.parse(stream, fix: true, header_hash: "#", sep: "\t", filename: nil, namespace: nil, unnamed: false, serializer: nil, **kwargs, &block)
|
265
|
+
parser = TSV::Parser.new stream, fix: fix, header_hash: header_hash, sep: sep
|
266
|
+
|
267
|
+
cast = parser.options[:cast] || kwargs[:cast]
|
268
|
+
type = kwargs[:type] ||= parser.options[:type] ||= :double
|
269
|
+
if (data = kwargs[:data]) && data.respond_to?(:persistence_class)
|
270
|
+
TSV.setup(data, type: type)
|
271
|
+
data.extend TSVAdapter
|
272
|
+
if serializer
|
273
|
+
data.serializer = serializer
|
274
|
+
elsif cast
|
275
|
+
data.serializer =
|
276
|
+
case [cast, type]
|
277
|
+
when [:to_i, :single]
|
278
|
+
:integer
|
279
|
+
when [:to_i, :list], [:to_i, :flat]
|
280
|
+
:integer_array
|
281
|
+
when [:to_f, :single]
|
282
|
+
:float
|
283
|
+
when [:to_f, :list], [:to_f, :flat]
|
284
|
+
:float_array
|
285
|
+
else
|
286
|
+
type
|
287
|
+
end
|
288
|
+
else
|
289
|
+
data.serializer = type
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
kwargs[:data] = {} if kwargs[:data].nil?
|
294
|
+
|
295
|
+
data = parser.traverse **kwargs, &block
|
296
|
+
data.type = type
|
297
|
+
data.filename = filename
|
298
|
+
data.namespace = namespace
|
299
|
+
data.unnamed = unnamed
|
300
|
+
data
|
301
|
+
end
|
302
|
+
|
303
|
+
#def self.parse_alt(stream, key_field: nil, fields: nil, filename: nil, namespace: nil, **kwargs, &block)
|
304
|
+
# options, key_field_name, field_names, first_line, preamble = parse_header(stream)
|
305
|
+
|
306
|
+
# if fields
|
307
|
+
# all_field_names ||= [key_field_name] + field_names
|
308
|
+
# positions = NamedArray.identify_name(all_field_names, fields)
|
309
|
+
# kwargs[:positions] = positions
|
310
|
+
# field_names = all_field_names.values_at *positions
|
311
|
+
# end
|
312
|
+
|
313
|
+
# if key_field
|
314
|
+
# all_field_names ||= [key_field_name] + field_names
|
315
|
+
# key = NamedArray.identify_name(all_field_names, key_field)
|
316
|
+
# kwargs[:key] = key
|
317
|
+
# key_field_name = all_field_names[key]
|
318
|
+
# if fields.nil?
|
319
|
+
# field_names = all_field_names - [key_field_name]
|
320
|
+
# end
|
321
|
+
# end
|
322
|
+
|
323
|
+
# options.each do |option,value|
|
324
|
+
# option = option.to_sym
|
325
|
+
# next unless KEY_PARAMETERS.include? option
|
326
|
+
# kwargs[option] = value unless kwargs.include?(option)
|
327
|
+
# end
|
328
|
+
|
329
|
+
# kwargs[:source_type] = options[:type]
|
330
|
+
|
331
|
+
# type = kwargs[:type] ||= :double
|
332
|
+
# if (data = kwargs[:data]) && data.respond_to?(:persistence_class)
|
333
|
+
# TSV.setup(data, type: type, key_field: key_field_name, fields: field_names)
|
334
|
+
# data.extend TSVAdapter
|
335
|
+
# end
|
336
|
+
|
337
|
+
# data = parse_stream(stream, first_line: first_line, **kwargs, &block)
|
338
|
+
|
339
|
+
# TSV.setup(data, :key_field => key_field_name, :fields => field_names, :type => type, filename: filename, namespace: namespace)
|
340
|
+
|
341
|
+
# data
|
342
|
+
#end
|
343
|
+
|
144
344
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Path
|
2
|
+
def tsv(*args, **kwargs, &block)
|
3
|
+
found = self.find
|
4
|
+
found = self.set_extension('tsv').find unless found.exists?
|
5
|
+
TSV.open(found, *args, **kwargs, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def index(*args, **kwargs, &block)
|
9
|
+
found = self.find
|
10
|
+
found = self.set_extension('tsv').find unless found.exists?
|
11
|
+
TSV.index(found, *args, **kwargs, &block)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,367 @@
|
|
1
|
+
require_relative '../../open/lock'
|
2
|
+
require_relative 'serialize'
|
3
|
+
|
4
|
+
module TSVAdapter
|
5
|
+
attr_accessor :persistence_path, :persistence_class, :serializer, :closed, :writable
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :lock_dir
|
9
|
+
def lock_dir
|
10
|
+
@lock_dir ||= Path.setup('tmp/tsv_locks')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
EXTENSION_ATTR_HASH_KEY = "__extension_attr_hash__"
|
15
|
+
EXTENSION_ATTR_HASH_SERIALIZER = Marshal
|
16
|
+
|
17
|
+
def serializer=(serializer)
|
18
|
+
@serializer = Symbol === serializer ? SERIALIZER_ALIAS[serializer] : serializer
|
19
|
+
end
|
20
|
+
|
21
|
+
def load_extension_attr_hash
|
22
|
+
EXTENSION_ATTR_HASH_SERIALIZER.load(StringIO.new(self[EXTENSION_ATTR_HASH_KEY]))
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_extension_attr_hash
|
26
|
+
self[EXTENSION_ATTR_HASH_KEY]= EXTENSION_ATTR_HASH_SERIALIZER.dump(self.extension_attr_hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.extended(base)
|
30
|
+
if ! TSVAdapter === base
|
31
|
+
if (! TSVAdapter === base) && base.include?(EXTENSION_ATTR_HASH_KEY)
|
32
|
+
TSV.setup(base, base.load_extension_attr_hash)
|
33
|
+
elsif TSV === base
|
34
|
+
base[EXTENSION_ATTR_HASH_KEY] = EXTENSION_ATTR_HASH_SERIALIZER.dump(base.extension_attr_hash)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
base.serializer = SERIALIZER_ALIAS[base.type]
|
39
|
+
|
40
|
+
class << base
|
41
|
+
alias orig_set []=
|
42
|
+
alias orig_get []
|
43
|
+
|
44
|
+
def [](key)
|
45
|
+
self.read_lock do
|
46
|
+
load_value(super(key))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def []=(key, value)
|
51
|
+
self.write_lock do
|
52
|
+
super(key, save_value(value))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def load_value(str)
|
57
|
+
serializer.load(str)
|
58
|
+
end
|
59
|
+
|
60
|
+
def save_value(value)
|
61
|
+
serializer.dump(value)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
#case base.type
|
68
|
+
#when :single
|
69
|
+
# class << base
|
70
|
+
# def load_value(value)
|
71
|
+
# value
|
72
|
+
# end
|
73
|
+
# def save_value(value)
|
74
|
+
# value
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
#when :list, :flat
|
78
|
+
# class << base
|
79
|
+
# def load_value(value)
|
80
|
+
# value.nil? ? nil : value.split("\t")
|
81
|
+
# end
|
82
|
+
# def save_value(value)
|
83
|
+
# value * "\t"
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
#when :double
|
87
|
+
# class << base
|
88
|
+
# def load_value(value)
|
89
|
+
# value.nil? ? nil : value.split("\t").collect{|v| v.split("|") }
|
90
|
+
# end
|
91
|
+
# def save_value(value)
|
92
|
+
# value.collect{|v| v * "|" } * "\t"
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
#end
|
96
|
+
end
|
97
|
+
|
98
|
+
def keys(*args)
|
99
|
+
k = self.read_lock do
|
100
|
+
super(*args)
|
101
|
+
end
|
102
|
+
|
103
|
+
if k[0] == EXTENSION_ATTR_HASH_KEY
|
104
|
+
k.slice(1,k.length-1)
|
105
|
+
elsif k[-1] == EXTENSION_ATTR_HASH_KEY
|
106
|
+
k.slice(0,k.length-2)
|
107
|
+
else
|
108
|
+
k - [EXTENSION_ATTR_HASH_KEY]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def each(&block)
|
113
|
+
self.read_lock do
|
114
|
+
super do |k,v|
|
115
|
+
next if k == EXTENSION_ATTR_HASH_KEY
|
116
|
+
yield(k, load_value(v))
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def collect(&block)
|
122
|
+
res = []
|
123
|
+
if block_given?
|
124
|
+
each do |k,v|
|
125
|
+
res << yield(k, v)
|
126
|
+
end
|
127
|
+
else
|
128
|
+
each do |k,v|
|
129
|
+
res << [k, v]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
res
|
133
|
+
end
|
134
|
+
|
135
|
+
def values
|
136
|
+
collect{|k,v| v }
|
137
|
+
end
|
138
|
+
|
139
|
+
alias map collect
|
140
|
+
|
141
|
+
def closed?
|
142
|
+
@closed
|
143
|
+
end
|
144
|
+
|
145
|
+
def write?
|
146
|
+
@writable
|
147
|
+
end
|
148
|
+
|
149
|
+
def read?
|
150
|
+
! (write? || closed?)
|
151
|
+
end
|
152
|
+
|
153
|
+
def write(*args)
|
154
|
+
begin
|
155
|
+
super(*args)
|
156
|
+
@writable = true
|
157
|
+
rescue NoMethodError
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def close(*args)
|
162
|
+
begin
|
163
|
+
super(*args)
|
164
|
+
@closed = true
|
165
|
+
rescue NoMethodError
|
166
|
+
end
|
167
|
+
self
|
168
|
+
end
|
169
|
+
|
170
|
+
def read(*args)
|
171
|
+
begin
|
172
|
+
super(*args)
|
173
|
+
rescue NoMethodError
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def delete(key)
|
178
|
+
self.write_lock do
|
179
|
+
out(key)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def lock
|
184
|
+
return yield if @locked
|
185
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSVAdapter.lock_dir})
|
186
|
+
Open.lock(lock_filename) do
|
187
|
+
begin
|
188
|
+
@locked = true
|
189
|
+
yield
|
190
|
+
ensure
|
191
|
+
@locked = false
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def lock_and_close
|
197
|
+
lock do
|
198
|
+
begin
|
199
|
+
yield
|
200
|
+
ensure
|
201
|
+
close
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def write_and_read
|
207
|
+
if write?
|
208
|
+
begin
|
209
|
+
return yield
|
210
|
+
ensure
|
211
|
+
read
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
lock do
|
216
|
+
write(true) if closed? || !write?
|
217
|
+
begin
|
218
|
+
yield
|
219
|
+
ensure
|
220
|
+
read
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def write_and_close
|
226
|
+
if write?
|
227
|
+
begin
|
228
|
+
return yield
|
229
|
+
ensure
|
230
|
+
close unless @locked
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
lock do
|
235
|
+
write(true) if closed? || ! write?
|
236
|
+
res = begin
|
237
|
+
yield
|
238
|
+
ensure
|
239
|
+
close
|
240
|
+
end
|
241
|
+
res
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def with_read(&block)
|
246
|
+
if read? || write?
|
247
|
+
return yield
|
248
|
+
else
|
249
|
+
read_and_close &block
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def with_write(&block)
|
254
|
+
if write?
|
255
|
+
return yield
|
256
|
+
else
|
257
|
+
if self.read?
|
258
|
+
self.write_and_read do
|
259
|
+
return yield
|
260
|
+
end
|
261
|
+
else
|
262
|
+
self.write_and_close do
|
263
|
+
return yield
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
def read_and_close
|
271
|
+
if read? || write?
|
272
|
+
begin
|
273
|
+
return yield
|
274
|
+
ensure
|
275
|
+
close unless @locked
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
lock do
|
280
|
+
read true if closed? || ! read?
|
281
|
+
begin
|
282
|
+
yield
|
283
|
+
ensure
|
284
|
+
close
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def read_lock
|
290
|
+
read if closed?
|
291
|
+
if read? || write?
|
292
|
+
return yield
|
293
|
+
end
|
294
|
+
|
295
|
+
lock do
|
296
|
+
close
|
297
|
+
read true
|
298
|
+
begin
|
299
|
+
yield
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def write_lock
|
305
|
+
write if closed?
|
306
|
+
if write?
|
307
|
+
return yield
|
308
|
+
end
|
309
|
+
|
310
|
+
lock do
|
311
|
+
close
|
312
|
+
write true
|
313
|
+
begin
|
314
|
+
yield
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def merge!(hash)
|
320
|
+
hash.each do |key,values|
|
321
|
+
self[key] = values
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def range(*args)
|
326
|
+
begin
|
327
|
+
self.read_lock do
|
328
|
+
super(*args)
|
329
|
+
end
|
330
|
+
rescue
|
331
|
+
[]
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
def include?(*args)
|
336
|
+
self.read_lock do
|
337
|
+
super(*args) #- TSV::ENTRY_KEYS.to_a
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
MAX_CHAR = 255.chr
|
342
|
+
|
343
|
+
def prefix(key)
|
344
|
+
self.read_lock do
|
345
|
+
range(key, 1, key + MAX_CHAR, 1)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def get_prefix(key)
|
350
|
+
keys = prefix(key)
|
351
|
+
select(:key => keys)
|
352
|
+
end
|
353
|
+
|
354
|
+
def size(*args)
|
355
|
+
self.read_lock do
|
356
|
+
super(*args)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
def values_at(*keys)
|
361
|
+
self.read_lock do
|
362
|
+
keys.collect do |k|
|
363
|
+
self[k]
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|