rbbt-util 5.5.68 → 5.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rbbt/association.rb +1 -1
- data/lib/rbbt/association/index.rb +2 -1
- data/lib/rbbt/entity.rb +2 -0
- data/lib/rbbt/persist/tsv.rb +46 -232
- data/lib/rbbt/persist/tsv/cdb.rb +139 -0
- data/lib/rbbt/persist/tsv/kyotocabinet.rb +168 -0
- data/lib/rbbt/persist/tsv/leveldb.rb +121 -0
- data/lib/rbbt/persist/tsv/lmdb.rb +148 -0
- data/lib/rbbt/persist/tsv/tokyocabinet.rb +158 -0
- data/lib/rbbt/resource/rake.rb +2 -1
- data/lib/rbbt/tsv/accessor.rb +74 -101
- data/lib/rbbt/tsv/parser.rb +2 -5
- data/lib/rbbt/tsv/serializers.rb +6 -0
- data/lib/rbbt/tsv/util.rb +8 -2
- data/lib/rbbt/util/R.rb +6 -0
- data/lib/rbbt/util/cmd.rb +7 -4
- data/lib/rbbt/util/misc.rb +10 -4
- data/lib/rbbt/util/open.rb +8 -6
- data/lib/rbbt/util/simpleopt.rb +1 -1
- data/lib/rbbt/workflow.rb +17 -3
- data/lib/rbbt/workflow/accessor.rb +5 -1
- data/lib/rbbt/workflow/definition.rb +6 -0
- data/lib/rbbt/workflow/step.rb +10 -4
- data/lib/rbbt/workflow/task.rb +1 -1
- data/share/rbbt_commands/tsv/json +37 -0
- data/share/rbbt_commands/workflow/task +8 -2
- data/test/rbbt/persist/test_tsv.rb +77 -0
- data/test/rbbt/persist/tsv/test_cdb.rb +23 -0
- data/test/rbbt/persist/tsv/test_kyotocabinet.rb +33 -0
- data/test/rbbt/persist/tsv/test_leveldb.rb +22 -0
- data/test/rbbt/persist/tsv/test_lmdb.rb +22 -0
- data/test/rbbt/persist/tsv/test_tokyocabinet.rb +242 -0
- data/test/rbbt/test_persist.rb +1 -225
- data/test/rbbt/test_workflow.rb +0 -1
- data/test/rbbt/workflow/test_step.rb +14 -12
- data/test/test_helper.rb +4 -2
- metadata +20 -4
- data/test/rbbt/workflow/test_soap.rb +0 -105
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'kyotocabinet'
|
2
|
+
|
3
|
+
module Persist
|
4
|
+
|
5
|
+
module KCAdapter
|
6
|
+
attr_accessor :persistence_path, :kyotocabinet_class, :closed, :writable
|
7
|
+
|
8
|
+
def self.open(path, write, kyotocabinet_class = "kch")
|
9
|
+
real_path = path + ".#{kyotocabinet_class}"
|
10
|
+
|
11
|
+
@persistence_path = real_path
|
12
|
+
|
13
|
+
flags = (write ? KyotoCabinet::DB::OWRITER | KyotoCabinet::DB::OCREATE : nil)
|
14
|
+
database =
|
15
|
+
CONNECTIONS[path] ||= begin
|
16
|
+
db = KyotoCabinet::DB.new
|
17
|
+
db.open(real_path, flags)
|
18
|
+
db
|
19
|
+
end
|
20
|
+
|
21
|
+
database.extend KCAdapter
|
22
|
+
database.persistence_path ||= real_path
|
23
|
+
|
24
|
+
database
|
25
|
+
end
|
26
|
+
|
27
|
+
def keys
|
28
|
+
keys = []
|
29
|
+
each_key{|k| keys.concat k}
|
30
|
+
keys
|
31
|
+
end
|
32
|
+
|
33
|
+
def prefix(key)
|
34
|
+
range(key, 1, key + 255.chr, 1)
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_prefix(key)
|
38
|
+
keys = prefix(key)
|
39
|
+
select(:key => keys)
|
40
|
+
end
|
41
|
+
|
42
|
+
def include?(key)
|
43
|
+
value = get(key)
|
44
|
+
! value.nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
def closed?
|
48
|
+
@closed
|
49
|
+
end
|
50
|
+
|
51
|
+
def close
|
52
|
+
@closed = true
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
def read(force = false)
|
57
|
+
return if not write? and not closed and not force
|
58
|
+
self.close
|
59
|
+
if !self.open(@persistence_path, KyotoCabinet::DB::OREADER)
|
60
|
+
raise "Open error #{ res }. Trying to open file #{@persistence_path}"
|
61
|
+
end
|
62
|
+
@writable = false
|
63
|
+
@closed = false
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def write(force = true)
|
68
|
+
return if write? and not closed and not force
|
69
|
+
self.close
|
70
|
+
|
71
|
+
if !self.open(@persistence_path, KyotoCabinet::DB::OWRITER)
|
72
|
+
raise "Open error. Trying to open file #{@persistence_path}"
|
73
|
+
end
|
74
|
+
|
75
|
+
@writable = true
|
76
|
+
@closed = false
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
def write?
|
81
|
+
@writable
|
82
|
+
end
|
83
|
+
|
84
|
+
def collect
|
85
|
+
res = []
|
86
|
+
each do |key, value|
|
87
|
+
res << if block_given?
|
88
|
+
yield key, value
|
89
|
+
else
|
90
|
+
[key, value]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
res
|
94
|
+
end
|
95
|
+
|
96
|
+
def delete(key)
|
97
|
+
out(key)
|
98
|
+
end
|
99
|
+
|
100
|
+
def write_and_read
|
101
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
|
102
|
+
Misc.lock(lock_filename) do
|
103
|
+
write if @closed or not write?
|
104
|
+
res = begin
|
105
|
+
yield
|
106
|
+
ensure
|
107
|
+
read
|
108
|
+
end
|
109
|
+
res
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def write_and_close
|
114
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
|
115
|
+
Misc.lock(lock_filename) do
|
116
|
+
write if @closed or not write?
|
117
|
+
res = begin
|
118
|
+
yield
|
119
|
+
ensure
|
120
|
+
close
|
121
|
+
end
|
122
|
+
res
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def read_and_close
|
127
|
+
read if @closed or write?
|
128
|
+
res = begin
|
129
|
+
yield
|
130
|
+
ensure
|
131
|
+
close
|
132
|
+
end
|
133
|
+
res
|
134
|
+
end
|
135
|
+
|
136
|
+
def merge!(hash)
|
137
|
+
hash.each do |key,values|
|
138
|
+
self[key] = values
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
#def []=(key,value)
|
143
|
+
# super(key,value)
|
144
|
+
# self.synchronize
|
145
|
+
#end
|
146
|
+
|
147
|
+
|
148
|
+
def range(*args)
|
149
|
+
super(*args) - TSV::ENTRY_KEYS.to_a
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def self.open_kyotocabinet(path, write, serializer = nil, kyotocabinet_class= 'kch')
|
155
|
+
write = true unless File.exists? path
|
156
|
+
|
157
|
+
FileUtils.mkdir_p File.dirname(path) unless File.exists?(File.dirname(path))
|
158
|
+
|
159
|
+
database = Persist::KCAdapter.open(path, write, kyotocabinet_class)
|
160
|
+
|
161
|
+
unless serializer == :clean
|
162
|
+
TSV.setup database
|
163
|
+
database.serializer = serializer || database.serializer
|
164
|
+
end
|
165
|
+
|
166
|
+
database
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'leveldb'
|
2
|
+
|
3
|
+
module Persist
|
4
|
+
|
5
|
+
module LevelDBAdapter
|
6
|
+
attr_accessor :persistence_path, :closed, :writable
|
7
|
+
|
8
|
+
def self.open(path, write)
|
9
|
+
|
10
|
+
database = CONNECTIONS[path] ||= begin
|
11
|
+
LevelDB::DB.new path
|
12
|
+
end
|
13
|
+
|
14
|
+
database.extend Persist::LevelDBAdapter unless Persist::LevelDBAdapter === database
|
15
|
+
database.persistence_path ||= path
|
16
|
+
ddd database
|
17
|
+
|
18
|
+
database
|
19
|
+
end
|
20
|
+
|
21
|
+
def prefix(key)
|
22
|
+
range(key, 1, key + 255.chr, 1)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_prefix(key)
|
26
|
+
keys = prefix(key)
|
27
|
+
select(:key => keys)
|
28
|
+
end
|
29
|
+
|
30
|
+
def include?(key)
|
31
|
+
includes?(key)
|
32
|
+
end
|
33
|
+
|
34
|
+
def closed?
|
35
|
+
@closed
|
36
|
+
end
|
37
|
+
|
38
|
+
def close
|
39
|
+
@closed = true
|
40
|
+
end
|
41
|
+
|
42
|
+
def read(force = false)
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def write(force = true)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def write?
|
51
|
+
@writable
|
52
|
+
end
|
53
|
+
|
54
|
+
def delete(key)
|
55
|
+
out(key)
|
56
|
+
end
|
57
|
+
|
58
|
+
def write_and_read
|
59
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
|
60
|
+
Misc.lock(lock_filename) do
|
61
|
+
write if @closed or not write?
|
62
|
+
res = begin
|
63
|
+
yield
|
64
|
+
ensure
|
65
|
+
read
|
66
|
+
end
|
67
|
+
res
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def write_and_close
|
72
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
|
73
|
+
Misc.lock(lock_filename) do
|
74
|
+
write if @closed or not write?
|
75
|
+
res = begin
|
76
|
+
yield
|
77
|
+
ensure
|
78
|
+
close
|
79
|
+
end
|
80
|
+
res
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def read_and_close
|
85
|
+
read if @closed or write?
|
86
|
+
res = begin
|
87
|
+
yield
|
88
|
+
ensure
|
89
|
+
close
|
90
|
+
end
|
91
|
+
res
|
92
|
+
end
|
93
|
+
|
94
|
+
def merge!(hash)
|
95
|
+
hash.each do |key,values|
|
96
|
+
self[key] = values
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def range(*args)
|
102
|
+
super(*args) - TSV::ENTRY_KEYS.to_a
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
def self.open_leveldb(path, write, serializer = nil)
|
108
|
+
write = true unless File.exists? path
|
109
|
+
|
110
|
+
FileUtils.mkdir_p File.dirname(path) unless File.exists?(File.dirname(path))
|
111
|
+
|
112
|
+
database = Persist::LevelDBAdapter.open(path, write)
|
113
|
+
|
114
|
+
unless serializer == :clean
|
115
|
+
TSV.setup database
|
116
|
+
database.serializer = serializer || database.serializer
|
117
|
+
end
|
118
|
+
|
119
|
+
database
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'lmdb'
|
2
|
+
|
3
|
+
module Persist
|
4
|
+
|
5
|
+
module LMDBAdapter
|
6
|
+
attr_accessor :persistence_path, :closed
|
7
|
+
|
8
|
+
def self.open(path, write)
|
9
|
+
|
10
|
+
database = CONNECTIONS[path] ||= begin
|
11
|
+
dir = File.dirname(File.expand_path(path))
|
12
|
+
file = File.basename(path)
|
13
|
+
env = LMDB.new(dir, :mapsize => 1024 * 10000)
|
14
|
+
database = env.database file, :create => write
|
15
|
+
database
|
16
|
+
end
|
17
|
+
|
18
|
+
database.extend Persist::LMDBAdapter unless Persist::LMDBAdapter === database
|
19
|
+
database.persistence_path ||= path
|
20
|
+
|
21
|
+
database
|
22
|
+
end
|
23
|
+
|
24
|
+
def keys
|
25
|
+
keys = []
|
26
|
+
cursor do |cursor|
|
27
|
+
while p = cursor.next
|
28
|
+
keys << p.first
|
29
|
+
end
|
30
|
+
end
|
31
|
+
keys
|
32
|
+
end
|
33
|
+
|
34
|
+
def include?(key)
|
35
|
+
self.send(:[], key, true)
|
36
|
+
end
|
37
|
+
|
38
|
+
def closed?
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
def close
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def read(force = false)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def write(force = true)
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def write?
|
55
|
+
@writable
|
56
|
+
end
|
57
|
+
|
58
|
+
def each
|
59
|
+
cursor do |cursor|
|
60
|
+
while pair = cursor.next
|
61
|
+
yield *pair
|
62
|
+
end
|
63
|
+
end
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def collect
|
68
|
+
res = []
|
69
|
+
cursor do |cursor|
|
70
|
+
while pair = cursor.next
|
71
|
+
res = if block_given?
|
72
|
+
yield *pair
|
73
|
+
else
|
74
|
+
pair
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
res
|
79
|
+
end
|
80
|
+
|
81
|
+
def delete(key)
|
82
|
+
out(key)
|
83
|
+
end
|
84
|
+
|
85
|
+
def write_and_read
|
86
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
|
87
|
+
Misc.lock(lock_filename) do
|
88
|
+
write if @closed or not write?
|
89
|
+
res = begin
|
90
|
+
yield
|
91
|
+
ensure
|
92
|
+
read
|
93
|
+
end
|
94
|
+
res
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def write_and_close
|
99
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
|
100
|
+
Misc.lock(lock_filename) do
|
101
|
+
write if @closed or not write?
|
102
|
+
res = begin
|
103
|
+
yield
|
104
|
+
ensure
|
105
|
+
close
|
106
|
+
end
|
107
|
+
res
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def read_and_close
|
112
|
+
read if @closed or write?
|
113
|
+
res = begin
|
114
|
+
yield
|
115
|
+
ensure
|
116
|
+
close
|
117
|
+
end
|
118
|
+
res
|
119
|
+
end
|
120
|
+
|
121
|
+
def merge!(hash)
|
122
|
+
hash.each do |key,values|
|
123
|
+
self[key] = values
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
def range(*args)
|
129
|
+
super(*args) - TSV::ENTRY_KEYS.to_a
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def self.open_lmdb(path, write, serializer = nil)
|
135
|
+
write = true unless File.exists? path
|
136
|
+
|
137
|
+
FileUtils.mkdir_p File.dirname(path) unless File.exists?(File.dirname(path))
|
138
|
+
|
139
|
+
database = Persist::LMDBAdapter.open(path, write)
|
140
|
+
|
141
|
+
unless serializer == :clean
|
142
|
+
TSV.setup database
|
143
|
+
database.serializer = serializer || database.serializer
|
144
|
+
end
|
145
|
+
|
146
|
+
database
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'tokyocabinet'
|
2
|
+
|
3
|
+
module Persist
|
4
|
+
|
5
|
+
module TCAdapter
|
6
|
+
attr_accessor :persistence_path, :tokyocabinet_class, :closed, :writable
|
7
|
+
|
8
|
+
def self.open(path, write, tokyocabinet_class = TokyoCabinet::HDB)
|
9
|
+
tokyocabinet_class = TokyoCabinet::HDB if tokyocabinet_class == "HDB"
|
10
|
+
tokyocabinet_class = TokyoCabinet::BDB if tokyocabinet_class == "BDB"
|
11
|
+
|
12
|
+
database = CONNECTIONS[path] ||= tokyocabinet_class.new
|
13
|
+
|
14
|
+
flags = (write ? tokyocabinet_class::OWRITER | tokyocabinet_class::OCREAT : tokyocabinet_class::OREADER)
|
15
|
+
database.close
|
16
|
+
|
17
|
+
if !database.open(path, flags)
|
18
|
+
ecode = database.ecode
|
19
|
+
raise "Open error: #{database.errmsg(ecode)}. Trying to open file #{path}"
|
20
|
+
end
|
21
|
+
|
22
|
+
database.extend Persist::TCAdapter unless Persist::TCAdapter === database
|
23
|
+
database.persistence_path ||= path
|
24
|
+
database.tokyocabinet_class = tokyocabinet_class
|
25
|
+
|
26
|
+
database
|
27
|
+
end
|
28
|
+
|
29
|
+
MAX_CHAR = 255.chr
|
30
|
+
|
31
|
+
def prefix(key)
|
32
|
+
range(key, 1, key + MAX_CHAR, 1)
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_prefix(key)
|
36
|
+
keys = prefix(key)
|
37
|
+
select(:key => keys)
|
38
|
+
end
|
39
|
+
|
40
|
+
def closed?
|
41
|
+
@closed
|
42
|
+
end
|
43
|
+
|
44
|
+
def close
|
45
|
+
@closed = true
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
49
|
+
def read(force = false)
|
50
|
+
return if not write? and not closed and not force
|
51
|
+
self.close
|
52
|
+
if !self.open(@persistence_path, tokyocabinet_class::OREADER)
|
53
|
+
ecode = self.ecode
|
54
|
+
raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
|
55
|
+
end
|
56
|
+
@writable = false
|
57
|
+
@closed = false
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def write(force = true)
|
62
|
+
return if write? and not closed and not force
|
63
|
+
self.close
|
64
|
+
|
65
|
+
if !self.open(@persistence_path, tokyocabinet_class::OWRITER)
|
66
|
+
ecode = self.ecode
|
67
|
+
raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
|
68
|
+
end
|
69
|
+
|
70
|
+
@writable = true
|
71
|
+
@closed = false
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def write?
|
76
|
+
@writable
|
77
|
+
end
|
78
|
+
|
79
|
+
def collect
|
80
|
+
res = []
|
81
|
+
each do |key, value|
|
82
|
+
res << if block_given?
|
83
|
+
yield key, value
|
84
|
+
else
|
85
|
+
[key, value]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
res
|
89
|
+
end
|
90
|
+
|
91
|
+
def delete(key)
|
92
|
+
out(key)
|
93
|
+
end
|
94
|
+
|
95
|
+
def write_and_read
|
96
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
|
97
|
+
Misc.lock(lock_filename) do
|
98
|
+
write if @closed or not write?
|
99
|
+
res = begin
|
100
|
+
yield
|
101
|
+
ensure
|
102
|
+
read
|
103
|
+
end
|
104
|
+
res
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def write_and_close
|
109
|
+
lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
|
110
|
+
Misc.lock(lock_filename) do
|
111
|
+
write if @closed or not write?
|
112
|
+
res = begin
|
113
|
+
yield
|
114
|
+
ensure
|
115
|
+
close
|
116
|
+
end
|
117
|
+
res
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def read_and_close
|
122
|
+
read if @closed or write?
|
123
|
+
res = begin
|
124
|
+
yield
|
125
|
+
ensure
|
126
|
+
close
|
127
|
+
end
|
128
|
+
res
|
129
|
+
end
|
130
|
+
|
131
|
+
def merge!(hash)
|
132
|
+
hash.each do |key,values|
|
133
|
+
self[key] = values
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def range(*args)
|
139
|
+
super(*args) #- TSV::ENTRY_KEYS.to_a
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
def self.open_tokyocabinet(path, write, serializer = nil, tokyocabinet_class = TokyoCabinet::HDB)
|
145
|
+
write = true unless File.exists? path
|
146
|
+
|
147
|
+
FileUtils.mkdir_p File.dirname(path) unless File.exists?(File.dirname(path))
|
148
|
+
|
149
|
+
database = Persist::TCAdapter.open(path, write, tokyocabinet_class)
|
150
|
+
|
151
|
+
unless serializer == :clean
|
152
|
+
TSV.setup database
|
153
|
+
database.serializer = serializer || database.serializer
|
154
|
+
end
|
155
|
+
|
156
|
+
database
|
157
|
+
end
|
158
|
+
end
|