epo 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +19 -4
- data/Rakefile +1 -1
- data/TODO +1 -8
- data/lib/epo/core/db.rb +65 -6
- data/lib/epo/core/observer.rb +25 -26
- data/lib/epo.rb +1 -1
- metadata +5 -5
data/README
CHANGED
@@ -43,14 +43,14 @@ $ tree db/
|
|
43
43
|
db/
|
44
44
|
└── user
|
45
45
|
├── peter
|
46
|
-
| ├── resource-default.json [1a]
|
46
|
+
| ├── resource-epo-default.json [1a]
|
47
47
|
| └── picture.png [1b]
|
48
48
|
├── jon
|
49
|
-
| ├── resource-default.json [2a]
|
49
|
+
| ├── resource-epo-default.json [2a]
|
50
50
|
| ├── picture.png [2b]
|
51
51
|
| └── pubkey.rsa.txt [2c]
|
52
52
|
└── marc
|
53
|
-
├── resource-default.json [3a]
|
53
|
+
├── resource-epo-default.json [3a]
|
54
54
|
├── picture.png [3b]
|
55
55
|
└── thumbnail.dat [3c]
|
56
56
|
|
@@ -150,7 +150,22 @@ Iterates on all the DB items (as observations)
|
|
150
150
|
|
151
151
|
welo >= 0.1.0
|
152
152
|
derailleur >= 0.5.0
|
153
|
-
a JSON library if you use json formatting
|
153
|
+
a JSON library if you use json formatting (recommended)
|
154
|
+
|
155
|
+
== Benchmark
|
156
|
+
Config:
|
157
|
+
* macbook pro (2010), without SSD:
|
158
|
+
* ruby 1.9.2
|
159
|
+
* json 1.5.1
|
160
|
+
|
161
|
+
$ ruby example/benchmark.rb
|
162
|
+
0.770000 1.020000 1.790000 ( 4.563546)
|
163
|
+
5935
|
164
|
+
1.160000 0.420000 1.580000 ( 1.601897)
|
165
|
+
|
166
|
+
So, roughly 5 seconds to write 6000 records, and 2 seconds to read them back.
|
167
|
+
No sync operation nor cache flush was forced in between the results. That's maybe why
|
168
|
+
we can read back only 5935 records out of 6000.
|
154
169
|
|
155
170
|
== License
|
156
171
|
|
data/Rakefile
CHANGED
data/TODO
CHANGED
@@ -1,9 +1,2 @@
|
|
1
|
-
*
|
2
|
-
* maybe with some modifications to Derailleur:
|
3
|
-
- graceful not found case
|
4
|
-
- clever pruning when finding:
|
5
|
-
- when path is a directory and there is no node, prune
|
6
|
-
- when path is a directory but there is a node, continue
|
7
|
-
- cache observation structs somewhere in the db or in the observer
|
8
|
-
* fiber-friendly batch operations
|
1
|
+
* nesting/epitheting resources
|
9
2
|
* register on inotify events
|
data/lib/epo/core/db.rb
CHANGED
@@ -39,7 +39,7 @@ module EPO
|
|
39
39
|
# Registers a model on a derailleur node at its path_model
|
40
40
|
# Does not modify self.models
|
41
41
|
def build_route_for_model(model)
|
42
|
-
path = model.path_model(identifying_sym)
|
42
|
+
path = File.join(model.path_model(identifying_sym), ':filename')
|
43
43
|
node = build_route(path)
|
44
44
|
node.content = model
|
45
45
|
end
|
@@ -75,20 +75,79 @@ module EPO
|
|
75
75
|
extensions.find{|ext| ext == File.extname(path)}
|
76
76
|
end
|
77
77
|
|
78
|
+
# Returns the main name of a path, i.e., the basename without
|
79
|
+
# the extension
|
80
|
+
# * main_name('/a/b/c/foo.bar') #=> 'foo'
|
81
|
+
def main_name(path)
|
82
|
+
File.basename(path).sub(/\.[^\.]+$/,'')
|
83
|
+
end
|
84
|
+
|
85
|
+
def understands_filename?(path)
|
86
|
+
understands_ext?(path) and
|
87
|
+
understands_main_name?(path)
|
88
|
+
end
|
89
|
+
|
90
|
+
def understands_main_name?(path)
|
91
|
+
main_name(path) =~ resource_regexp
|
92
|
+
end
|
93
|
+
|
94
|
+
RESOURCE_REGEXP = %r{resource-epo-\w+}
|
95
|
+
|
96
|
+
def resource_regexp
|
97
|
+
RESOURCE_REGEXP
|
98
|
+
end
|
99
|
+
|
78
100
|
# Returns the perspective name and extension name (a 2 items array)
|
79
101
|
# for the given path.
|
80
102
|
# By default the blobs for resources content are stored in files named
|
81
103
|
# 'resource-<persp><ext>' with ext starting with a dot
|
82
104
|
def persp_and_ext_for_basename(path)
|
83
|
-
|
84
|
-
[base, File.extname(path)]
|
105
|
+
[main_name(path).sub('resource-epo-',''), File.extname(path)]
|
85
106
|
end
|
86
107
|
|
87
108
|
# Returns the basename of a resource blob for a perspective named persp and
|
88
109
|
# in a format with extension ext (including the leading dot).
|
89
110
|
# see also persp_and_ext_for_basename
|
90
111
|
def basename_for_persp_and_ext(persp, ext)
|
91
|
-
"resource-#{persp}#{ext}"
|
112
|
+
"resource-epo-#{persp}#{ext}"
|
113
|
+
end
|
114
|
+
|
115
|
+
# Deletes a resource by removing its identifying directory. Beware because
|
116
|
+
# this method doesn't care about other files which may coexist in the same
|
117
|
+
# filesystem branch.
|
118
|
+
def delete_completely(root, resource)
|
119
|
+
path = File.join(root, resource.path(identifying_sym))
|
120
|
+
FileUtils.rm_rf(path)
|
121
|
+
|
122
|
+
# removes the empty directories upward
|
123
|
+
(resource.identifiers(identifying_sym).size - 1).times do |t|
|
124
|
+
path = File.split(path).first
|
125
|
+
begin
|
126
|
+
FileUtils.rmdir(path)
|
127
|
+
rescue Errno::ENOTEMPTY
|
128
|
+
break
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def delete(root, resource)
|
134
|
+
remaining_path = File.join(root, resource.path(identifying_sym))
|
135
|
+
# removes the resource-epo-* files
|
136
|
+
Dir.entries(remaining_path).each do |e|
|
137
|
+
if e.start_with?('resource-epo-')
|
138
|
+
FileUtils.rm(File.join(remaining_path, e))
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# removes the empty directories upward
|
143
|
+
resource.identifiers(identifying_sym).size.times do |t|
|
144
|
+
begin
|
145
|
+
Dir.rmdir(remaining_path)
|
146
|
+
remaining_path = File.split(remaining_path).first
|
147
|
+
rescue Errno::ENOTEMPTY
|
148
|
+
break
|
149
|
+
end
|
150
|
+
end
|
92
151
|
end
|
93
152
|
|
94
153
|
# Saves one or more resource at the filesystem path given at root
|
@@ -171,7 +230,7 @@ module EPO
|
|
171
230
|
# Iterates on every resource found and understood in the filesystem
|
172
231
|
# directory root.
|
173
232
|
# If no block is given, returns an iterator.
|
174
|
-
def
|
233
|
+
def each_resource_observation(root)
|
175
234
|
if block_given?
|
176
235
|
xp = observer
|
177
236
|
models.each do |model|
|
@@ -181,7 +240,7 @@ module EPO
|
|
181
240
|
end
|
182
241
|
xp.read_tree(root)
|
183
242
|
else
|
184
|
-
Enumerator.new(self, :
|
243
|
+
Enumerator.new(self, :each_resource_observation, root)
|
185
244
|
end
|
186
245
|
end
|
187
246
|
|
data/lib/epo/core/observer.rb
CHANGED
@@ -21,6 +21,9 @@ module EPO
|
|
21
21
|
# The DB able to tell if a path is understandable or not
|
22
22
|
attr_accessor :db
|
23
23
|
|
24
|
+
# A cache for the observation structures
|
25
|
+
attr_accessor :structures
|
26
|
+
|
24
27
|
# Creates and return a new observer from a DB.
|
25
28
|
# It will take the models from the DB.
|
26
29
|
def self.for_db(db)
|
@@ -34,35 +37,26 @@ module EPO
|
|
34
37
|
def initialize(models=[])
|
35
38
|
super(models)
|
36
39
|
@db = DB.new(models)
|
40
|
+
@structures = {}
|
37
41
|
register(:observation) do |o|
|
38
42
|
dispatch(o)
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
# the root is likely to be:
|
47
|
-
# /home/crapooze/project/foobar/db
|
48
|
-
# If a successful observation happens, then it will call the relevant hooks.
|
49
|
-
def read_path(path, root=nil)
|
50
|
-
full_dirname, base = File.split(path)
|
51
|
-
dirname = if root
|
52
|
-
full_dirname.sub(root,'')
|
53
|
-
else
|
54
|
-
full_dirname
|
55
|
-
end
|
56
|
-
#XXX may raise an exception for unknown path, we should rescue this/use a
|
57
|
-
#silent method and test for nil
|
58
|
-
node = db.get_route(dirname)
|
46
|
+
def get_node_for_path(path, root=nil)
|
47
|
+
path = path.sub(root,'') if root
|
48
|
+
db.get_route_silent(path)
|
49
|
+
end
|
59
50
|
|
51
|
+
def read_path_as_resource(path, model)
|
60
52
|
persp_str = db.persp_and_ext_for_basename(path).first
|
61
|
-
persp =
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
53
|
+
persp = model.perspectives.keys.find{|k| k.to_s == persp_str}
|
54
|
+
observe_source(Source.new(db, path), structure(model, persp))
|
55
|
+
end
|
56
|
+
|
57
|
+
def structure(model, persp)
|
58
|
+
pair = [model, persp]
|
59
|
+
@structures[pair] ||= Welo::ObservationStruct.new_for_resource_in_perspective(model, persp)
|
66
60
|
end
|
67
61
|
|
68
62
|
# Recursively reads the files in the filesystem (with Find).
|
@@ -70,10 +64,15 @@ module EPO
|
|
70
64
|
# Currently, there is no pruning, or control possible.
|
71
65
|
def read_tree(root)
|
72
66
|
Find.find(root) do |path|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
67
|
+
node = get_node_for_path(path, root)
|
68
|
+
if node
|
69
|
+
if node.content #a model attached to a file in a directory
|
70
|
+
if db.understands_filename?(path)
|
71
|
+
read_path_as_resource(path, node.content)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
else #the db doesn't understand this branch, we'd rather drop now
|
75
|
+
Find.prune
|
77
76
|
end
|
78
77
|
end
|
79
78
|
end
|
data/lib/epo.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- crapooze
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-03-
|
17
|
+
date: 2011-03-27 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -28,8 +28,8 @@ dependencies:
|
|
28
28
|
segments:
|
29
29
|
- 0
|
30
30
|
- 0
|
31
|
-
-
|
32
|
-
version: 0.0.
|
31
|
+
- 6
|
32
|
+
version: 0.0.6
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|