rbbt-util 5.44.1 → 6.0.4
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/LICENSE +1 -1
- data/bin/rbbt +67 -90
- data/bin/rbbt_exec.rb +2 -2
- data/etc/app.d/base.rb +2 -2
- data/etc/app.d/semaphores.rb +3 -3
- data/lib/rbbt/annotations/annotated_array.rb +207 -207
- data/lib/rbbt/annotations/refactor.rb +27 -0
- data/lib/rbbt/annotations/util.rb +282 -282
- data/lib/rbbt/annotations.rb +343 -320
- data/lib/rbbt/association/database.rb +200 -225
- data/lib/rbbt/association/index.rb +294 -291
- data/lib/rbbt/association/item.rb +227 -227
- data/lib/rbbt/association/open.rb +35 -34
- data/lib/rbbt/association/util.rb +0 -169
- data/lib/rbbt/association.rb +2 -4
- data/lib/rbbt/entity/identifiers.rb +119 -118
- data/lib/rbbt/entity/refactor.rb +12 -0
- data/lib/rbbt/entity.rb +319 -315
- data/lib/rbbt/hpc/batch.rb +72 -53
- data/lib/rbbt/hpc/lsf.rb +2 -2
- data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
- data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
- data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
- data/lib/rbbt/hpc/orchestrate.rb +19 -13
- data/lib/rbbt/hpc/slurm.rb +18 -18
- data/lib/rbbt/knowledge_base/entity.rb +13 -5
- data/lib/rbbt/knowledge_base/query.rb +2 -2
- data/lib/rbbt/knowledge_base/registry.rb +32 -31
- data/lib/rbbt/knowledge_base/traverse.rb +1 -1
- data/lib/rbbt/knowledge_base.rb +1 -1
- data/lib/rbbt/monitor.rb +36 -25
- data/lib/rbbt/persist/refactor.rb +166 -0
- data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
- data/lib/rbbt/persist/tsv.rb +187 -185
- data/lib/rbbt/persist.rb +556 -551
- data/lib/rbbt/refactor.rb +20 -0
- data/lib/rbbt/resource/path/refactor.rb +178 -0
- data/lib/rbbt/resource/path.rb +317 -497
- data/lib/rbbt/resource/util.rb +0 -48
- data/lib/rbbt/resource.rb +3 -390
- data/lib/rbbt/tsv/accessor.rb +2 -838
- data/lib/rbbt/tsv/attach.rb +303 -299
- data/lib/rbbt/tsv/change_id.rb +244 -245
- data/lib/rbbt/tsv/csv.rb +87 -85
- data/lib/rbbt/tsv/dumper.rb +2 -100
- data/lib/rbbt/tsv/excel.rb +26 -24
- data/lib/rbbt/tsv/field_index.rb +4 -1
- data/lib/rbbt/tsv/filter.rb +3 -2
- data/lib/rbbt/tsv/index.rb +2 -284
- data/lib/rbbt/tsv/manipulate.rb +750 -747
- data/lib/rbbt/tsv/marshal.rb +3 -3
- data/lib/rbbt/tsv/matrix.rb +2 -2
- data/lib/rbbt/tsv/parallel/through.rb +2 -1
- data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
- data/lib/rbbt/tsv/parser.rb +678 -678
- data/lib/rbbt/tsv/refactor.rb +195 -0
- data/lib/rbbt/tsv/stream.rb +253 -251
- data/lib/rbbt/tsv/util.rb +420 -420
- data/lib/rbbt/tsv.rb +210 -208
- data/lib/rbbt/util/R/eval.rb +4 -4
- data/lib/rbbt/util/R/plot.rb +62 -166
- data/lib/rbbt/util/R.rb +21 -18
- data/lib/rbbt/util/cmd.rb +2 -318
- data/lib/rbbt/util/color.rb +269 -269
- data/lib/rbbt/util/colorize.rb +89 -89
- data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
- data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
- data/lib/rbbt/util/concurrency/processes.rb +389 -386
- data/lib/rbbt/util/config.rb +169 -167
- data/lib/rbbt/util/filecache.rb +1 -1
- data/lib/rbbt/util/iruby.rb +20 -0
- data/lib/rbbt/util/log/progress/report.rb +241 -241
- data/lib/rbbt/util/log/progress/util.rb +99 -99
- data/lib/rbbt/util/log/progress.rb +102 -102
- data/lib/rbbt/util/log/refactor.rb +49 -0
- data/lib/rbbt/util/log.rb +486 -532
- data/lib/rbbt/util/migrate.rb +2 -2
- data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
- data/lib/rbbt/util/misc/development.rb +12 -11
- data/lib/rbbt/util/misc/exceptions.rb +117 -112
- data/lib/rbbt/util/misc/format.rb +2 -230
- data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
- data/lib/rbbt/util/misc/inspect.rb +2 -476
- data/lib/rbbt/util/misc/lock.rb +109 -106
- data/lib/rbbt/util/misc/omics.rb +9 -1
- data/lib/rbbt/util/misc/pipes.rb +765 -793
- data/lib/rbbt/util/misc/refactor.rb +20 -0
- data/lib/rbbt/util/misc/ssw.rb +27 -17
- data/lib/rbbt/util/misc/system.rb +92 -105
- data/lib/rbbt/util/misc.rb +39 -20
- data/lib/rbbt/util/named_array/refactor.rb +4 -0
- data/lib/rbbt/util/named_array.rb +3 -220
- data/lib/rbbt/util/open/refactor.rb +7 -0
- data/lib/rbbt/util/open.rb +3 -857
- data/lib/rbbt/util/procpath.rb +6 -6
- data/lib/rbbt/util/python/paths.rb +27 -0
- data/lib/rbbt/util/python/run.rb +115 -0
- data/lib/rbbt/util/python/script.rb +110 -0
- data/lib/rbbt/util/python/util.rb +3 -3
- data/lib/rbbt/util/python.rb +22 -81
- data/lib/rbbt/util/semaphore.rb +152 -148
- data/lib/rbbt/util/simpleopt.rb +9 -8
- data/lib/rbbt/util/ssh/refactor.rb +19 -0
- data/lib/rbbt/util/ssh.rb +122 -118
- data/lib/rbbt/util/tar.rb +117 -115
- data/lib/rbbt/util/tmpfile.rb +69 -67
- data/lib/rbbt/util/version.rb +2 -0
- data/lib/rbbt/workflow/refactor/entity.rb +11 -0
- data/lib/rbbt/workflow/refactor/export.rb +66 -0
- data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
- data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
- data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
- data/lib/rbbt/workflow/refactor.rb +150 -0
- data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
- data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
- data/lib/rbbt/workflow/remote_workflow.rb +6 -1
- data/lib/rbbt/workflow/step/run.rb +766 -766
- data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
- data/lib/rbbt/workflow/step.rb +2 -362
- data/lib/rbbt/workflow/task.rb +118 -118
- data/lib/rbbt/workflow/usage.rb +289 -287
- data/lib/rbbt/workflow/util/archive.rb +6 -5
- data/lib/rbbt/workflow/util/data.rb +1 -1
- data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
- data/lib/rbbt/workflow/util/trace.rb +79 -44
- data/lib/rbbt/workflow.rb +4 -882
- data/lib/rbbt-util.rb +21 -13
- data/lib/rbbt.rb +16 -3
- data/python/rbbt/__init__.py +96 -4
- data/python/rbbt/workflow/remote.py +104 -0
- data/python/rbbt/workflow.py +64 -0
- data/python/test.py +10 -0
- data/share/Rlib/plot.R +37 -37
- data/share/Rlib/svg.R +22 -5
- data/share/install/software/lib/install_helpers +1 -1
- data/share/rbbt_commands/hpc/list +2 -3
- data/share/rbbt_commands/hpc/orchestrate +4 -4
- data/share/rbbt_commands/hpc/tail +2 -0
- data/share/rbbt_commands/hpc/task +10 -7
- data/share/rbbt_commands/lsf/list +2 -3
- data/share/rbbt_commands/lsf/orchestrate +4 -4
- data/share/rbbt_commands/lsf/tail +2 -0
- data/share/rbbt_commands/lsf/task +10 -7
- data/share/rbbt_commands/migrate +1 -1
- data/share/rbbt_commands/pbs/list +2 -3
- data/share/rbbt_commands/pbs/orchestrate +4 -4
- data/share/rbbt_commands/pbs/tail +2 -0
- data/share/rbbt_commands/pbs/task +10 -7
- data/share/rbbt_commands/resource/produce +8 -1
- data/share/rbbt_commands/slurm/list +2 -3
- data/share/rbbt_commands/slurm/orchestrate +4 -4
- data/share/rbbt_commands/slurm/tail +2 -0
- data/share/rbbt_commands/slurm/task +10 -7
- data/share/rbbt_commands/system/clean +5 -5
- data/share/rbbt_commands/system/status +5 -5
- data/share/rbbt_commands/tsv/get +2 -3
- data/share/rbbt_commands/tsv/info +10 -13
- data/share/rbbt_commands/tsv/keys +18 -14
- data/share/rbbt_commands/tsv/slice +2 -2
- data/share/rbbt_commands/tsv/transpose +6 -2
- data/share/rbbt_commands/workflow/info +20 -24
- data/share/rbbt_commands/workflow/list +1 -1
- data/share/rbbt_commands/workflow/prov +20 -13
- data/share/rbbt_commands/workflow/retry +43 -0
- data/share/rbbt_commands/workflow/server +12 -2
- data/share/rbbt_commands/workflow/task +80 -73
- data/share/rbbt_commands/workflow/write_info +26 -9
- data/share/software/opt/ssw/ssw.c +861 -0
- data/share/software/opt/ssw/ssw.h +130 -0
- data/share/workflow_config.ru +3 -3
- metadata +45 -6
@@ -9,7 +9,7 @@ class KnowledgeBase
|
|
9
9
|
Log.debug("Registering #{ name } from code block")
|
10
10
|
@registry[name] = [block, options]
|
11
11
|
else
|
12
|
-
Log.debug("Registering #{ name }: #{
|
12
|
+
Log.debug("Registering #{ name }: #{ Log.fingerprint file } #{Log.fingerprint options}")
|
13
13
|
@registry[name] = [file, options]
|
14
14
|
end
|
15
15
|
end
|
@@ -40,7 +40,7 @@ class KnowledgeBase
|
|
40
40
|
|
41
41
|
def get_index(name, options = {})
|
42
42
|
name = name.to_s
|
43
|
-
options[:
|
43
|
+
options[:namespace] ||= self.namespace unless self.namespace.nil?
|
44
44
|
@indices[[name, options]] ||=
|
45
45
|
begin
|
46
46
|
if options.empty?
|
@@ -49,7 +49,7 @@ class KnowledgeBase
|
|
49
49
|
key = options[:key]
|
50
50
|
key = name if key == :name
|
51
51
|
else
|
52
|
-
fp = Misc.
|
52
|
+
fp = Misc.digest(options)
|
53
53
|
key = name.to_s + "_" + fp
|
54
54
|
end
|
55
55
|
|
@@ -57,30 +57,33 @@ class KnowledgeBase
|
|
57
57
|
options = options.dup
|
58
58
|
|
59
59
|
persist_dir = dir
|
60
|
-
|
60
|
+
persist_path = persist_dir[key].find
|
61
61
|
file, registered_options = registry[name]
|
62
62
|
|
63
|
-
options =
|
64
|
-
options =
|
63
|
+
options = IndiferentHash.add_defaults options, registered_options if registered_options and registered_options.any?
|
64
|
+
options = IndiferentHash.add_defaults options, :persist_path => persist_path, :persist_dir => persist_dir, :persist => true
|
65
65
|
|
66
66
|
if entity_options
|
67
67
|
options[:entity_options] ||= {}
|
68
68
|
entity_options.each do |type, info|
|
69
69
|
options[:entity_options][type] ||= {}
|
70
|
-
options[:entity_options][type] =
|
70
|
+
options[:entity_options][type] = IndiferentHash.add_defaults options[:entity_options][type], info
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
persist_options =
|
74
|
+
persist_options = IndiferentHash.pull_keys options, :persist
|
75
|
+
persist_options = IndiferentHash.add_defaults persist_options, :path => persist_path
|
76
|
+
|
75
77
|
|
76
|
-
index = if
|
77
|
-
Log.low "Re-opening index #{ name } from #{
|
78
|
-
Association.index(file, options
|
78
|
+
index = if persist_path.exists? and persist_options[:persist] and not persist_options[:update]
|
79
|
+
Log.low "Re-opening index #{ name } from #{ Log.fingerprint persist_path }. #{options}"
|
80
|
+
Association.index(file, **options.merge(persist_options: persist_options.dup))
|
79
81
|
else
|
80
|
-
options =
|
82
|
+
options = IndiferentHash.add_defaults options, registered_options if registered_options
|
81
83
|
raise "Repo #{ name } not found and not registered" if file.nil?
|
82
|
-
Log.medium "Opening index #{ name } from #{
|
83
|
-
|
84
|
+
Log.medium "Opening index #{ name } from #{ Log.fingerprint file }. #{options}"
|
85
|
+
file = file.call if Proc === file
|
86
|
+
Association.index(file, **options.merge(persist_options: persist_options.dup))
|
84
87
|
end
|
85
88
|
|
86
89
|
index.namespace = self.namespace unless self.namespace
|
@@ -97,51 +100,49 @@ class KnowledgeBase
|
|
97
100
|
if self.namespace == options[:namespace]
|
98
101
|
options.delete(:namespace)
|
99
102
|
end
|
100
|
-
if self.namespace == options[:organism]
|
101
|
-
options.delete(:organism)
|
102
|
-
end
|
103
103
|
@databases[[name, options]] ||=
|
104
104
|
begin
|
105
|
-
fp =
|
105
|
+
fp = Log.fingerprint([name,options])
|
106
106
|
|
107
107
|
if options.empty?
|
108
108
|
key = name.to_s
|
109
109
|
else
|
110
|
-
fp = Misc.
|
110
|
+
fp = Misc.digest(options)
|
111
111
|
key = name.to_s + "_" + fp
|
112
112
|
end
|
113
113
|
|
114
|
-
options[:
|
114
|
+
options[:namespace] ||= self.namespace unless self.namespace.nil?
|
115
115
|
|
116
116
|
key += '.database'
|
117
117
|
Persist.memory("Database:" << [key, dir] * "@") do
|
118
118
|
options = options.dup
|
119
119
|
|
120
120
|
persist_dir = dir
|
121
|
-
|
121
|
+
persist_path = persist_dir[key].find
|
122
122
|
file, registered_options = registry[name]
|
123
123
|
|
124
|
-
options =
|
125
|
-
options =
|
124
|
+
options = IndiferentHash.add_defaults options, registered_options if registered_options and registered_options.any?
|
125
|
+
options = IndiferentHash.add_defaults options, :persist_path => persist_path, :persist => true
|
126
126
|
|
127
127
|
if entity_options
|
128
128
|
options[:entity_options] ||= {}
|
129
129
|
entity_options.each do |type, info|
|
130
130
|
options[:entity_options][type] ||= {}
|
131
|
-
options[:entity_options][type] =
|
131
|
+
options[:entity_options][type] = IndiferentHash.add_defaults options[:entity_options][type], info
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
persist_options =
|
135
|
+
persist_options = IndiferentHash.pull_keys options, :persist
|
136
136
|
|
137
|
-
database = if
|
138
|
-
Log.low "Re-opening database #{ name } from #{
|
139
|
-
Association.
|
137
|
+
database = if persist_path.exists? and persist_options[:persist] and not persist_options[:update]
|
138
|
+
Log.low "Re-opening database #{ name } from #{ Log.fingerprint persist_path }. #{options}"
|
139
|
+
Association.database(file, options, persist_options)
|
140
140
|
else
|
141
|
-
options =
|
141
|
+
options = IndiferentHash.add_defaults options, registered_options if registered_options
|
142
142
|
raise "Repo #{ name } not found and not registered" if file.nil?
|
143
|
-
Log.medium "Opening database #{ name } from #{
|
144
|
-
|
143
|
+
Log.medium "Opening database #{ name } from #{ Log.fingerprint file }. #{options}"
|
144
|
+
file = file.call if Proc === file
|
145
|
+
Association.database(file, **options)
|
145
146
|
end
|
146
147
|
|
147
148
|
database.namespace = self.namespace if self.namespace
|
data/lib/rbbt/knowledge_base.rb
CHANGED
data/lib/rbbt/monitor.rb
CHANGED
@@ -8,7 +8,7 @@ module Rbbt
|
|
8
8
|
LOCK_DIRS = Rbbt.tmp.tsv_open_locks.find_all + Rbbt.tmp.persist_locks.find_all + Rbbt.tmp.sensiblewrite_locks.find_all +
|
9
9
|
Rbbt.tmp.produce_locks.find_all + Rbbt.tmp.step_info_locks.find_all
|
10
10
|
|
11
|
-
SENSIBLE_WRITE_DIRS =
|
11
|
+
SENSIBLE_WRITE_DIRS = Open.sensible_write_dir.find_all
|
12
12
|
|
13
13
|
PERSIST_DIRS = Rbbt.share.find_all + Rbbt.var.cache.persistence.find_all
|
14
14
|
|
@@ -142,23 +142,28 @@ module Rbbt
|
|
142
142
|
tasks_dirs = if dir == '.'
|
143
143
|
["."]
|
144
144
|
else
|
145
|
-
workflowdirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
145
|
+
#workflowdirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
|
146
|
+
# repo_dir, sub_path = dir_sub_path
|
147
|
+
# Open.list_repo_files(*dir_sub_path).collect{|f| f.split("/").first}.uniq.collect{|f| File.join(repo_dir, f)}.uniq
|
148
|
+
# else
|
149
|
+
# dir.glob("*")
|
150
|
+
# end
|
151
|
+
|
152
|
+
workflowdirs = dir.glob("*")
|
151
153
|
|
152
154
|
workflowdirs.collect do |workflowdir|
|
153
155
|
workflow = File.basename(workflowdir)
|
154
156
|
next if workflows and not workflows.include? workflow
|
155
157
|
|
156
|
-
task_dirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
158
|
+
#task_dirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
|
159
|
+
# repo_dir, sub_path = dir_sub_path
|
160
|
+
# Open.list_repo_files(*dir_sub_path).collect{|f| f.split("/").first}.uniq.collect{|f| File.join(repo_dir, f)}.uniq
|
161
|
+
# else
|
162
|
+
# workflowdir.glob("*")
|
163
|
+
# end
|
164
|
+
|
165
|
+
task_dirs = workflowdir.glob("*")
|
166
|
+
|
162
167
|
task_dirs.each do |tasks_dir|
|
163
168
|
task_dir_workflows[tasks_dir] = workflow
|
164
169
|
end
|
@@ -170,18 +175,24 @@ module Rbbt
|
|
170
175
|
next if tasks and not tasks.include? task
|
171
176
|
|
172
177
|
|
173
|
-
files = if (dir_sub_path = Open.find_repo_dir(taskdir))
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
178
|
+
#files = if (dir_sub_path = Open.find_repo_dir(taskdir))
|
179
|
+
# repo_dir, sub_path = dir_sub_path
|
180
|
+
# Open.list_repo_files(*dir_sub_path).reject do |f|
|
181
|
+
# f.include?("/.info/") ||
|
182
|
+
# f.include?(".files/") ||
|
183
|
+
# f.include?(".pid/") ||
|
184
|
+
# File.directory?(f)
|
185
|
+
# end.collect do |f|
|
186
|
+
# File.join(repo_dir, f)
|
187
|
+
# end
|
188
|
+
# else
|
189
|
+
# #cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/*.files/*\" -prune \\) -not -name '*.pid' -not -name '*.notify' -not -name '\\.*' 2>/dev/null"
|
190
|
+
# cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/.info/*\" -prune \\) -not \\( -path \"#{taskdir}/*.files/*\" -prune \\) -not -name '*.pid' -not -name '*.md5' -not -name '*.notify' -not -name '\\.*' \\( -not -type d -o -name '*.files' \\) 2>/dev/null"
|
191
|
+
|
192
|
+
# CMD.cmd(cmd, :pipe => true).read.split("\n")
|
193
|
+
# end
|
194
|
+
|
195
|
+
files = begin
|
185
196
|
cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/.info/*\" -prune \\) -not \\( -path \"#{taskdir}/*.files/*\" -prune \\) -not -name '*.pid' -not -name '*.md5' -not -name '*.notify' -not -name '\\.*' \\( -not -type d -o -name '*.files' \\) 2>/dev/null"
|
186
197
|
|
187
198
|
CMD.cmd(cmd, :pipe => true).read.split("\n")
|
@@ -0,0 +1,166 @@
|
|
1
|
+
module Persist
|
2
|
+
TSVAdapter = Object::TSVAdapter
|
3
|
+
def self.is_persisted?(path, persist_options = {})
|
4
|
+
return true if Open.remote?(path)
|
5
|
+
return true if Open.ssh?(path)
|
6
|
+
return false if not Open.exists? path
|
7
|
+
return false if TrueClass === persist_options[:update]
|
8
|
+
|
9
|
+
expiration = persist_options[:expiration]
|
10
|
+
if expiration
|
11
|
+
seconds = Misc.timespan(expiration)
|
12
|
+
patht = Open.mtime(path)
|
13
|
+
return false if Time.now > patht + seconds
|
14
|
+
end
|
15
|
+
|
16
|
+
check = persist_options[:check]
|
17
|
+
return true if check.nil?
|
18
|
+
|
19
|
+
missing = check.reject{|file| Open.exists?(file) }
|
20
|
+
return false if missing.any?
|
21
|
+
|
22
|
+
return true unless ENV["RBBT_UPDATE"]
|
23
|
+
|
24
|
+
if Array === check
|
25
|
+
newer = check.select{|file| newer? path, file}
|
26
|
+
return true if newer.empty?
|
27
|
+
Log.medium "Persistence check for #{path} failed in: #{ Misc.fingerprint(newer)}"
|
28
|
+
return false
|
29
|
+
else
|
30
|
+
! newer?(path, check)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Is 'file' newer than 'path'? return non-true if path is newer than file
|
35
|
+
def self.newer?(path, file, by_link = false)
|
36
|
+
return true if not Open.exists?(file)
|
37
|
+
path = path.find if Path === path
|
38
|
+
file = file.find if Path === file
|
39
|
+
if by_link
|
40
|
+
patht = File.exist?(path) ? File.lstat(path).mtime : nil
|
41
|
+
filet = File.exist?(file) ? File.lstat(file).mtime : nil
|
42
|
+
else
|
43
|
+
patht = Open.mtime(path)
|
44
|
+
filet = Open.mtime(file)
|
45
|
+
end
|
46
|
+
return true if patht.nil? || filet.nil?
|
47
|
+
diff = patht - filet
|
48
|
+
return diff if diff < 0
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
|
52
|
+
#def self.persist_tsv(source, filename = nil, options = {}, persist_options = {}, &block)
|
53
|
+
# engine = IndiferentHash.process_options persist_options, :engine, engine: "HDB"
|
54
|
+
# Persist.persist(name, engine, persist_options, &block)
|
55
|
+
#end
|
56
|
+
|
57
|
+
#
|
58
|
+
# def self.persist_tsv(source, filename = nil, options = {}, persist_options = {}, &block)
|
59
|
+
# persist_options[:prefix] ||= "TSV"
|
60
|
+
#
|
61
|
+
# if data = persist_options[:data]
|
62
|
+
# Log.debug "TSV persistence creating with data: #{ Misc.fingerprint(data) }"
|
63
|
+
# yield data
|
64
|
+
# return data
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# filename ||= get_filename(source)
|
68
|
+
#
|
69
|
+
# if not persist_options[:persist]
|
70
|
+
# data = {}
|
71
|
+
#
|
72
|
+
# yield(data)
|
73
|
+
#
|
74
|
+
# return data
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# path = persistence_path(filename, options)
|
78
|
+
#
|
79
|
+
# if ENV["RBBT_UPDATE_TSV_PERSIST"] == 'true' and filename
|
80
|
+
# check_options = {:check => [filename]}
|
81
|
+
# else
|
82
|
+
# check_options = {}
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# if is_persisted?(path, check_options) and not persist_options[:update]
|
86
|
+
# path = path.find if Path === path
|
87
|
+
# Log.debug "TSV persistence up-to-date: #{ path }"
|
88
|
+
# if persist_options[:shard_function]
|
89
|
+
# return open_sharder(path, false, nil, persist_options[:engine], persist_options, &persist_options[:shard_function])
|
90
|
+
# else
|
91
|
+
# return open_database(path, false, nil, persist_options[:engine] || TokyoCabinet::HDB, persist_options)
|
92
|
+
# end
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# lock_filename = Persist.persistence_path(path, {:dir => TSV.lock_dir})
|
96
|
+
# Misc.lock lock_filename do
|
97
|
+
# begin
|
98
|
+
# if is_persisted?(path, check_options) and not persist_options[:update]
|
99
|
+
# path = path.find if Path === path
|
100
|
+
# Log.debug "TSV persistence (suddenly) up-to-date: #{ path }"
|
101
|
+
#
|
102
|
+
# if persist_options[:shard_function]
|
103
|
+
# return open_sharder(path, false, nil, persist_options[:engine], persist_options, &persist_options[:shard_function])
|
104
|
+
# else
|
105
|
+
# return open_database(path, false, nil, persist_options[:engine] || TokyoCabinet::HDB, persist_options)
|
106
|
+
# end
|
107
|
+
# end
|
108
|
+
# path = path.find if Path === path
|
109
|
+
#
|
110
|
+
# FileUtils.rm_rf path if File.exist? path
|
111
|
+
#
|
112
|
+
# Log.medium "TSV persistence creating: #{ path }"
|
113
|
+
#
|
114
|
+
# tmp_path = path + '.persist'
|
115
|
+
#
|
116
|
+
# data = if persist_options[:shard_function]
|
117
|
+
# open_sharder(tmp_path, true, persist_options[:serializer], persist_options[:engine], persist_options, &persist_options[:shard_function])
|
118
|
+
# else
|
119
|
+
# open_database(tmp_path, true, persist_options[:serializer], persist_options[:engine] || TokyoCabinet::HDB, persist_options)
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# if TSV === data and data.serializer.nil?
|
123
|
+
# data.serializer = :type
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# if persist_options[:persist] == :preload
|
127
|
+
# tmp_tsv = yield({})
|
128
|
+
# tmp_tsv.annotate data
|
129
|
+
# data.serializer = tmp_tsv.type
|
130
|
+
# data.write_and_read do
|
131
|
+
# tmp_tsv.each do |k,v|
|
132
|
+
# data[k] = v
|
133
|
+
# end
|
134
|
+
# end
|
135
|
+
# else
|
136
|
+
# data.write_and_read do
|
137
|
+
# yield data
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
#
|
141
|
+
# data.write_and_read do
|
142
|
+
# FileUtils.mv data.persistence_path, path if File.exist? data.persistence_path and not File.exist? path
|
143
|
+
# tsv = CONNECTIONS[path] = CONNECTIONS.delete tmp_path
|
144
|
+
# tsv.persistence_path = path
|
145
|
+
#
|
146
|
+
# tsv.fix_io if tsv.respond_to? :fix_io
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# data
|
150
|
+
# rescue Exception
|
151
|
+
# Log.error "Captured error during persist_tsv. Erasing: #{path}"
|
152
|
+
# FileUtils.rm_rf tmp_path if tmp_path and File.exist? tmp_path
|
153
|
+
# FileUtils.rm_rf path if path and File.exist? path
|
154
|
+
# raise $!
|
155
|
+
# end
|
156
|
+
# end
|
157
|
+
# end
|
158
|
+
end
|
159
|
+
|
160
|
+
#Persist.save_drivers[:annotations] = proc do |file,content|
|
161
|
+
# Persist.save(content, file, :)
|
162
|
+
#end
|
163
|
+
#
|
164
|
+
#Persist.load_drivers[:annotations] = proc do |file|
|
165
|
+
# Persist.load(file, :meta_extension)
|
166
|
+
#end
|
@@ -1,105 +1,105 @@
|
|
1
|
-
require 'tokyocabinet'
|
2
|
-
|
3
|
-
module Persist
|
4
|
-
|
5
|
-
module TCAdapter
|
6
|
-
include Persist::TSVAdapter
|
7
|
-
|
8
|
-
attr_accessor :tokyocabinet_class
|
9
|
-
|
10
|
-
def self.open(path, write, tokyocabinet_class = TokyoCabinet::HDB)
|
11
|
-
if String === tokyocabinet_class && tokyocabinet_class.include?(":big")
|
12
|
-
big = true
|
13
|
-
tokyocabinet_class = tokyocabinet_class.split(":").first
|
14
|
-
else
|
15
|
-
big = false
|
16
|
-
end
|
17
|
-
|
18
|
-
dir = File.dirname(File.expand_path(path))
|
19
|
-
File.mkdir(dir) unless File.exist?(dir)
|
20
|
-
|
21
|
-
tokyocabinet_class = TokyoCabinet::HDB if tokyocabinet_class == "HDB" or tokyocabinet_class.nil?
|
22
|
-
tokyocabinet_class = TokyoCabinet::BDB if tokyocabinet_class == "BDB"
|
23
|
-
|
24
|
-
database = CONNECTIONS[path] ||= Log.ignore_stderr do tokyocabinet_class.new end
|
25
|
-
|
26
|
-
if big and not Open.exists?(path)
|
27
|
-
database.tune(nil,nil,nil,tokyocabinet_class::TLARGE | tokyocabinet_class::TDEFLATE)
|
28
|
-
end
|
29
|
-
|
30
|
-
flags = (write ? tokyocabinet_class::OWRITER | tokyocabinet_class::OCREAT : tokyocabinet_class::OREADER)
|
31
|
-
database.close
|
32
|
-
|
33
|
-
if !database.open(path, flags)
|
34
|
-
ecode = database.ecode
|
35
|
-
raise "Open error: #{database.errmsg(ecode)}. Trying to open file #{path}"
|
36
|
-
end
|
37
|
-
|
38
|
-
database.extend Persist::TCAdapter unless Persist::TCAdapter === database
|
39
|
-
database.persistence_path ||= path
|
40
|
-
database.tokyocabinet_class = tokyocabinet_class
|
41
|
-
|
42
|
-
database.mutex = Mutex.new
|
43
|
-
database.read
|
44
|
-
|
45
|
-
CONNECTIONS[path] = database
|
46
|
-
|
47
|
-
database
|
48
|
-
end
|
49
|
-
|
50
|
-
def close
|
51
|
-
@closed = true
|
52
|
-
@writable = false
|
53
|
-
super
|
54
|
-
end
|
55
|
-
|
56
|
-
def read(force = false)
|
57
|
-
return if ! write? && ! closed && ! force
|
58
|
-
self.close
|
59
|
-
if !self.open(@persistence_path, tokyocabinet_class::OREADER)
|
60
|
-
ecode = self.ecode
|
61
|
-
raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
|
62
|
-
end
|
63
|
-
|
64
|
-
@writable = false
|
65
|
-
@closed = false
|
66
|
-
|
67
|
-
self
|
68
|
-
end
|
69
|
-
|
70
|
-
def write(force = true)
|
71
|
-
return if write? && ! closed && ! force
|
72
|
-
self.close
|
73
|
-
|
74
|
-
if !self.open(@persistence_path, tokyocabinet_class::OWRITER)
|
75
|
-
ecode = self.ecode
|
76
|
-
raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
|
77
|
-
end
|
78
|
-
|
79
|
-
@writable = true
|
80
|
-
@closed = false
|
81
|
-
|
82
|
-
self
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.open_tokyocabinet(path, write, serializer = nil, tokyocabinet_class = TokyoCabinet::HDB)
|
88
|
-
write = true unless File.exist? path
|
89
|
-
|
90
|
-
FileUtils.mkdir_p File.dirname(path) unless File.exist?(File.dirname(path))
|
91
|
-
|
92
|
-
database = Persist::TCAdapter.open(path, write, tokyocabinet_class)
|
93
|
-
|
94
|
-
unless serializer == :clean
|
95
|
-
TSV.setup database
|
96
|
-
database.write_and_read do
|
97
|
-
database.serializer = serializer
|
98
|
-
end if serializer && database.serializer != serializer
|
99
|
-
end
|
100
|
-
|
101
|
-
database
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
require 'rbbt/persist/tsv/tokyocabinet/marshal'
|
1
|
+
#require 'tokyocabinet'
|
2
|
+
#
|
3
|
+
#module Persist
|
4
|
+
#
|
5
|
+
# module TCAdapter
|
6
|
+
# include Persist::TSVAdapter
|
7
|
+
#
|
8
|
+
# attr_accessor :tokyocabinet_class
|
9
|
+
#
|
10
|
+
# def self.open(path, write, tokyocabinet_class = TokyoCabinet::HDB)
|
11
|
+
# if String === tokyocabinet_class && tokyocabinet_class.include?(":big")
|
12
|
+
# big = true
|
13
|
+
# tokyocabinet_class = tokyocabinet_class.split(":").first
|
14
|
+
# else
|
15
|
+
# big = false
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# dir = File.dirname(File.expand_path(path))
|
19
|
+
# File.mkdir(dir) unless File.exist?(dir)
|
20
|
+
#
|
21
|
+
# tokyocabinet_class = TokyoCabinet::HDB if tokyocabinet_class == "HDB" or tokyocabinet_class.nil?
|
22
|
+
# tokyocabinet_class = TokyoCabinet::BDB if tokyocabinet_class == "BDB"
|
23
|
+
#
|
24
|
+
# database = CONNECTIONS[path] ||= Log.ignore_stderr do tokyocabinet_class.new end
|
25
|
+
#
|
26
|
+
# if big and not Open.exists?(path)
|
27
|
+
# database.tune(nil,nil,nil,tokyocabinet_class::TLARGE | tokyocabinet_class::TDEFLATE)
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# flags = (write ? tokyocabinet_class::OWRITER | tokyocabinet_class::OCREAT : tokyocabinet_class::OREADER)
|
31
|
+
# database.close
|
32
|
+
#
|
33
|
+
# if !database.open(path, flags)
|
34
|
+
# ecode = database.ecode
|
35
|
+
# raise "Open error: #{database.errmsg(ecode)}. Trying to open file #{path}"
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# database.extend Persist::TCAdapter unless Persist::TCAdapter === database
|
39
|
+
# database.persistence_path ||= path
|
40
|
+
# database.tokyocabinet_class = tokyocabinet_class
|
41
|
+
#
|
42
|
+
# database.mutex = Mutex.new
|
43
|
+
# database.read
|
44
|
+
#
|
45
|
+
# CONNECTIONS[path] = database
|
46
|
+
#
|
47
|
+
# database
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# def close
|
51
|
+
# @closed = true
|
52
|
+
# @writable = false
|
53
|
+
# super
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# def read(force = false)
|
57
|
+
# return if ! write? && ! closed && ! force
|
58
|
+
# self.close
|
59
|
+
# if !self.open(@persistence_path, tokyocabinet_class::OREADER)
|
60
|
+
# ecode = self.ecode
|
61
|
+
# raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# @writable = false
|
65
|
+
# @closed = false
|
66
|
+
#
|
67
|
+
# self
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# def write(force = true)
|
71
|
+
# return if write? && ! closed && ! force
|
72
|
+
# self.close
|
73
|
+
#
|
74
|
+
# if !self.open(@persistence_path, tokyocabinet_class::OWRITER)
|
75
|
+
# ecode = self.ecode
|
76
|
+
# raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# @writable = true
|
80
|
+
# @closed = false
|
81
|
+
#
|
82
|
+
# self
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# def self.open_tokyocabinet(path, write, serializer = nil, tokyocabinet_class = TokyoCabinet::HDB)
|
88
|
+
# write = true unless File.exist? path
|
89
|
+
#
|
90
|
+
# FileUtils.mkdir_p File.dirname(path) unless File.exist?(File.dirname(path))
|
91
|
+
#
|
92
|
+
# database = Persist::TCAdapter.open(path, write, tokyocabinet_class)
|
93
|
+
#
|
94
|
+
# unless serializer == :clean
|
95
|
+
# TSV.setup database
|
96
|
+
# database.write_and_read do
|
97
|
+
# database.serializer = serializer
|
98
|
+
# end if serializer && database.serializer != serializer
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# database
|
102
|
+
# end
|
103
|
+
#end
|
104
|
+
#
|
105
|
+
#require 'rbbt/persist/tsv/tokyocabinet/marshal'
|