pacer 0.9.1.1-java
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +8 -0
- data/.document +5 -0
- data/.gitignore +26 -0
- data/.rspec +1 -0
- data/.rvmrc +0 -0
- data/CONTRIBUTORS +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +24 -0
- data/README.md +187 -0
- data/Rakefile +49 -0
- data/autotest/discover.rb +1 -0
- data/bin/autospec +16 -0
- data/bin/autotest +16 -0
- data/bin/rake +16 -0
- data/bin/rcov +16 -0
- data/bin/rspec +16 -0
- data/bin/yard +16 -0
- data/bin/yardoc +16 -0
- data/lib/pacer/blueprints/extensions.rb +77 -0
- data/lib/pacer/blueprints/multi_graph.rb +121 -0
- data/lib/pacer/blueprints/ruby_graph.rb +199 -0
- data/lib/pacer/blueprints/tg.rb +100 -0
- data/lib/pacer/blueprints.rb +4 -0
- data/lib/pacer/core/graph/edges_route.rb +92 -0
- data/lib/pacer/core/graph/element_route.rb +171 -0
- data/lib/pacer/core/graph/graph_index_route.rb +48 -0
- data/lib/pacer/core/graph/graph_route.rb +55 -0
- data/lib/pacer/core/graph/mixed_route.rb +96 -0
- data/lib/pacer/core/graph/vertices_route.rb +220 -0
- data/lib/pacer/core/graph.rb +13 -0
- data/lib/pacer/core/route.rb +502 -0
- data/lib/pacer/core/side_effect.rb +11 -0
- data/lib/pacer/core.rb +8 -0
- data/lib/pacer/exceptions.rb +11 -0
- data/lib/pacer/extensions/block_filter_element.rb +22 -0
- data/lib/pacer/extensions.rb +6 -0
- data/lib/pacer/filter/block_filter.rb +31 -0
- data/lib/pacer/filter/collection_filter.rb +109 -0
- data/lib/pacer/filter/empty_filter.rb +70 -0
- data/lib/pacer/filter/future_filter.rb +68 -0
- data/lib/pacer/filter/index_filter.rb +30 -0
- data/lib/pacer/filter/loop_filter.rb +95 -0
- data/lib/pacer/filter/object_filter.rb +55 -0
- data/lib/pacer/filter/property_filter/edge_filters.rb +93 -0
- data/lib/pacer/filter/property_filter/filters.rb +269 -0
- data/lib/pacer/filter/property_filter.rb +111 -0
- data/lib/pacer/filter/random_filter.rb +13 -0
- data/lib/pacer/filter/range_filter.rb +104 -0
- data/lib/pacer/filter/uniq_filter.rb +12 -0
- data/lib/pacer/filter/where_filter/node_visitor.rb +280 -0
- data/lib/pacer/filter/where_filter.rb +47 -0
- data/lib/pacer/filter.rb +17 -0
- data/lib/pacer/function_resolver.rb +43 -0
- data/lib/pacer/graph/edge_mixin.rb +127 -0
- data/lib/pacer/graph/element_mixin.rb +202 -0
- data/lib/pacer/graph/graph_indices_mixin.rb +93 -0
- data/lib/pacer/graph/graph_mixin.rb +361 -0
- data/lib/pacer/graph/graph_transactions_mixin.rb +207 -0
- data/lib/pacer/graph/index_mixin.rb +30 -0
- data/lib/pacer/graph/vertex_mixin.rb +119 -0
- data/lib/pacer/graph.rb +14 -0
- data/lib/pacer/pipe/blackbox_pipeline.rb +48 -0
- data/lib/pacer/pipe/block_filter_pipe.rb +38 -0
- data/lib/pacer/pipe/collection_filter_pipe.rb +10 -0
- data/lib/pacer/pipe/cross_product_transform_pipe.rb +48 -0
- data/lib/pacer/pipe/enumerable_pipe.rb +30 -0
- data/lib/pacer/pipe/expandable_pipe.rb +63 -0
- data/lib/pacer/pipe/id_collection_filter_pipe.rb +33 -0
- data/lib/pacer/pipe/is_empty_pipe.rb +30 -0
- data/lib/pacer/pipe/is_unique_pipe.rb +61 -0
- data/lib/pacer/pipe/label_collection_filter_pipe.rb +21 -0
- data/lib/pacer/pipe/label_prefix_pipe.rb +21 -0
- data/lib/pacer/pipe/loop_pipe.rb +86 -0
- data/lib/pacer/pipe/map_pipe.rb +36 -0
- data/lib/pacer/pipe/never_pipe.rb +9 -0
- data/lib/pacer/pipe/process_pipe.rb +37 -0
- data/lib/pacer/pipe/property_comparison_pipe.rb +40 -0
- data/lib/pacer/pipe/ruby_pipe.rb +25 -0
- data/lib/pacer/pipe/simple_visitor_pipe.rb +43 -0
- data/lib/pacer/pipe/stream_sort_pipe.rb +84 -0
- data/lib/pacer/pipe/stream_uniq_pipe.rb +33 -0
- data/lib/pacer/pipe/type_filter_pipe.rb +22 -0
- data/lib/pacer/pipe/unary_transform_pipe.rb +59 -0
- data/lib/pacer/pipe/variable_store_iterator_wrapper.rb +26 -0
- data/lib/pacer/pipe/visitor_pipe.rb +67 -0
- data/lib/pacer/pipes.rb +61 -0
- data/lib/pacer/route/mixin/bulk_operations.rb +52 -0
- data/lib/pacer/route/mixin/route_operations.rb +107 -0
- data/lib/pacer/route/mixin/variable_route_module.rb +26 -0
- data/lib/pacer/route/mixins.rb +3 -0
- data/lib/pacer/route.rb +228 -0
- data/lib/pacer/routes.rb +6 -0
- data/lib/pacer/side_effect/aggregate.rb +31 -0
- data/lib/pacer/side_effect/counted.rb +30 -0
- data/lib/pacer/side_effect/group_count.rb +44 -0
- data/lib/pacer/side_effect/is_unique.rb +32 -0
- data/lib/pacer/side_effect/section.rb +25 -0
- data/lib/pacer/side_effect/visitor.rb +37 -0
- data/lib/pacer/side_effect.rb +11 -0
- data/lib/pacer/support/array_list.rb +28 -0
- data/lib/pacer/support/enumerable.rb +100 -0
- data/lib/pacer/support/hash.rb +9 -0
- data/lib/pacer/support/iterator_mixins.rb +110 -0
- data/lib/pacer/support/native_exception.rb +22 -0
- data/lib/pacer/support/proc.rb +16 -0
- data/lib/pacer/support.rb +10 -0
- data/lib/pacer/transform/cap.rb +50 -0
- data/lib/pacer/transform/gather.rb +9 -0
- data/lib/pacer/transform/has_count_cap.rb +41 -0
- data/lib/pacer/transform/join.rb +181 -0
- data/lib/pacer/transform/map.rb +23 -0
- data/lib/pacer/transform/path.rb +50 -0
- data/lib/pacer/transform/process.rb +23 -0
- data/lib/pacer/transform/scatter.rb +23 -0
- data/lib/pacer/transform/sort_section.rb +103 -0
- data/lib/pacer/transform/stream_sort.rb +21 -0
- data/lib/pacer/transform/stream_uniq.rb +21 -0
- data/lib/pacer/transform.rb +16 -0
- data/lib/pacer/utils/graph_analysis.rb +112 -0
- data/lib/pacer/utils/trie.rb +93 -0
- data/lib/pacer/utils/tsort.rb +65 -0
- data/lib/pacer/utils/y_files.rb +127 -0
- data/lib/pacer/utils.rb +10 -0
- data/lib/pacer/version.rb +13 -0
- data/lib/pacer/wrappers/edge_wrapper.rb +51 -0
- data/lib/pacer/wrappers/element_wrapper.rb +78 -0
- data/lib/pacer/wrappers/new_element.rb +106 -0
- data/lib/pacer/wrappers/vertex_wrapper.rb +51 -0
- data/lib/pacer/wrappers.rb +19 -0
- data/lib/pacer-0.9.1.1-standalone.jar +0 -0
- data/lib/pacer.rb +290 -0
- data/pacer.gemspec +30 -0
- data/pom/standalone.xml +22 -0
- data/pom.xml +124 -0
- data/samples/grateful-dead.xml +26380 -0
- data/samples/grateful_dead.rb +63 -0
- data/samples/profile.rb +15 -0
- data/spec/data/grateful-dead.xml +26380 -0
- data/spec/data/pacer.graphml +319 -0
- data/spec/pacer/blueprints/dex_spec.rb +172 -0
- data/spec/pacer/blueprints/neo4j_spec.rb +177 -0
- data/spec/pacer/blueprints/tg_spec.rb +128 -0
- data/spec/pacer/core/graph/edges_route_spec.rb +52 -0
- data/spec/pacer/core/graph/element_route_spec.rb +46 -0
- data/spec/pacer/core/graph/graph_route_spec.rb +94 -0
- data/spec/pacer/core/graph/vertices_route_spec.rb +169 -0
- data/spec/pacer/core/route_spec.rb +197 -0
- data/spec/pacer/filter/collection_filter_spec.rb +19 -0
- data/spec/pacer/filter/empty_filter_spec.rb +29 -0
- data/spec/pacer/filter/future_filter_spec.rb +97 -0
- data/spec/pacer/filter/loop_filter_spec.rb +31 -0
- data/spec/pacer/filter/property_filter_spec.rb +111 -0
- data/spec/pacer/filter/random_filter_spec.rb +17 -0
- data/spec/pacer/filter/uniq_filter_spec.rb +18 -0
- data/spec/pacer/filter/where_filter_spec.rb +93 -0
- data/spec/pacer/graph/edge_mixin_spec.rb +116 -0
- data/spec/pacer/graph/element_mixin_spec.rb +297 -0
- data/spec/pacer/graph/graph_mixin_spec.rb +538 -0
- data/spec/pacer/graph/index_mixin_spec.rb +0 -0
- data/spec/pacer/graph/vertex_mixin_spec.rb +192 -0
- data/spec/pacer/pipe/block_filter_pipe_spec.rb +0 -0
- data/spec/pacer/pipe/labels_filter_pipe_spec.rb +0 -0
- data/spec/pacer/pipe/ruby_pipe_spec.rb +0 -0
- data/spec/pacer/pipe/type_filter_pipe_spec.rb +0 -0
- data/spec/pacer/route/mixin/base_spec.rb +419 -0
- data/spec/pacer/route/mixin/bulk_operations_spec.rb +30 -0
- data/spec/pacer/route/mixin/route_operations_spec.rb +127 -0
- data/spec/pacer/support/array_list_spec.rb +0 -0
- data/spec/pacer/support/enumerable_spec.rb +115 -0
- data/spec/pacer/transform/join_spec.rb +138 -0
- data/spec/pacer/transform/path_spec.rb +54 -0
- data/spec/pacer/utils/tsort_spec.rb +89 -0
- data/spec/pacer/wrapper/edge_wrapper_spec.rb +33 -0
- data/spec/pacer/wrapper/element_wrapper_spec.rb +169 -0
- data/spec/pacer/wrapper/vertex_wrapper_spec.rb +33 -0
- data/spec/pacer_spec.rb +0 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/support/contexts.rb +14 -0
- data/spec/support/graph_runner.rb +142 -0
- data/spec/support/matchers.rb +19 -0
- data/spec/support/use_transactions.rb +31 -0
- data/spec/tackle/simple_mixin.rb +21 -0
- data/spec/tackle/tinkerpop_graph_mixins.rb +60 -0
- metadata +364 -0
@@ -0,0 +1,361 @@
|
|
1
|
+
module Pacer
|
2
|
+
# Methods to be mixed into Blueprints Graph objects from any
|
3
|
+
# implementation.
|
4
|
+
#
|
5
|
+
# Adds more convenient/rubyish methods and adds support for extensions
|
6
|
+
# to some methods where needed.
|
7
|
+
module GraphMixin
|
8
|
+
def self.included(target)
|
9
|
+
target.class_eval do
|
10
|
+
protected :addVertex, :addEdge
|
11
|
+
protected :add_vertex, :add_edge rescue nil
|
12
|
+
protected :getVertex, :getEdge
|
13
|
+
protected :get_vertex, :get_edge rescue nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_accessor :in_bulk_job
|
18
|
+
|
19
|
+
def graph_id
|
20
|
+
@graph_id = Pacer.next_graph_id unless defined? @graph_id
|
21
|
+
@graph_id
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get a vertex by id.
|
25
|
+
#
|
26
|
+
# @overload vertex(id)
|
27
|
+
# @param [element id] id
|
28
|
+
# @overload vertex(id, *modules)
|
29
|
+
# @param [element id] id
|
30
|
+
# @param [Module, Class] *modules extensions to add to the returned
|
31
|
+
# vertex.
|
32
|
+
def vertex(id, *modules)
|
33
|
+
v = getVertex(id) rescue nil
|
34
|
+
if v
|
35
|
+
wrapper = modules.detect { |obj| obj.ancestors.include? Pacer::Wrappers::VertexWrapper }
|
36
|
+
if wrapper
|
37
|
+
v = wrapper.new v
|
38
|
+
modules.delete wrapper
|
39
|
+
end
|
40
|
+
v.graph = self
|
41
|
+
v.add_extensions modules
|
42
|
+
else
|
43
|
+
v
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Get an edge by id.
|
48
|
+
#
|
49
|
+
# @overload edge(id)
|
50
|
+
# @param [element id] id
|
51
|
+
# @overload edge(id, *modules)
|
52
|
+
# @param [element id] id
|
53
|
+
# @param [Module, Class] *modules extensions to add to the returned
|
54
|
+
# edge.
|
55
|
+
def edge(id, *modules)
|
56
|
+
v = getEdge(id) rescue nil
|
57
|
+
if v
|
58
|
+
wrapper = modules.detect { |obj| obj.ancestors.include? Pacer::Wrappers::EdgeWrapper }
|
59
|
+
if wrapper
|
60
|
+
v = wrapper.new v
|
61
|
+
modules.delete wrapper
|
62
|
+
end
|
63
|
+
v.graph = self
|
64
|
+
v.add_extensions modules
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Create a vertex in the graph.
|
69
|
+
#
|
70
|
+
# @overload create_vertex(*args)
|
71
|
+
# @param [extension, Hash] *args extension (Module/Class) arguments will be
|
72
|
+
# added to the current vertex. A Hash will be
|
73
|
+
# treated as element properties.
|
74
|
+
# @overload create_vertex(id, *args)
|
75
|
+
# @param [element id] id the desired element id. Some graphs
|
76
|
+
# ignore this.
|
77
|
+
# @param [extension, Hash] *args extension (Module/Class) arguments will be
|
78
|
+
# added to the current vertex. A Hash will be
|
79
|
+
# treated as element properties.
|
80
|
+
def create_vertex(*args)
|
81
|
+
id, wrapper, modules, props = id_modules_properties(args)
|
82
|
+
vertex = creating_elements { addVertex(id) }
|
83
|
+
vertex = wrapper.new vertex if wrapper
|
84
|
+
vertex.graph = self
|
85
|
+
props.each { |k, v| vertex[k.to_s] = v } if props
|
86
|
+
if modules.any?
|
87
|
+
vertex.add_extensions modules
|
88
|
+
else
|
89
|
+
vertex
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Create an edge in the graph.
|
94
|
+
#
|
95
|
+
# @param [element id] id some graphs allow you to specify your own edge id.
|
96
|
+
# @param [Pacer::VertexMixin] from_v the new edge's out_vertex
|
97
|
+
# @param [Pacer::VertexMixin] to_v the new edge's in_vertex
|
98
|
+
# @param [#to_s] label the edge label
|
99
|
+
# @param [extension, Hash] *args extension (Module/Class) arguments will be
|
100
|
+
# added to the returned edge. A Hash will be
|
101
|
+
# treated as element properties.
|
102
|
+
#
|
103
|
+
# @todo make id param optional
|
104
|
+
def create_edge(id, from_v, to_v, label, *args)
|
105
|
+
_, wrapper, modules, props = id_modules_properties(args)
|
106
|
+
edge = creating_elements { addEdge(id, from_v.element, to_v.element, label) }
|
107
|
+
edge = wrapper.new edge if wrapper
|
108
|
+
edge.graph = self
|
109
|
+
props.each { |k, v| edge[k.to_s] = v } if props
|
110
|
+
if modules.any?
|
111
|
+
edge.add_extensions modules
|
112
|
+
else
|
113
|
+
edge
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Import the data in a GraphML file.
|
118
|
+
#
|
119
|
+
# Will fail if the data already exsts in the current graph.
|
120
|
+
#
|
121
|
+
# @param [String] path
|
122
|
+
def import(path)
|
123
|
+
path = File.expand_path path
|
124
|
+
begin
|
125
|
+
stream = java.net.URL.new(path).open_stream
|
126
|
+
rescue java.net.MalformedURLException
|
127
|
+
stream = java.io.FileInputStream.new path
|
128
|
+
end
|
129
|
+
creating_elements do
|
130
|
+
com.tinkerpop.blueprints.pgm.util.graphml.GraphMLReader.input_graph self, stream
|
131
|
+
end
|
132
|
+
true
|
133
|
+
ensure
|
134
|
+
stream.close if stream
|
135
|
+
end
|
136
|
+
|
137
|
+
# Export the graph to GraphML
|
138
|
+
#
|
139
|
+
# @param [String] path will be replaced if it exists
|
140
|
+
def export(path)
|
141
|
+
path = File.expand_path path
|
142
|
+
stream = java.io.FileOutputStream.new path
|
143
|
+
com.tinkerpop.blueprints.pgm.util.graphml.GraphMLWriter.outputGraph self, stream
|
144
|
+
ensure
|
145
|
+
stream.close if stream
|
146
|
+
end
|
147
|
+
|
148
|
+
# Set how many elements should go into each transaction in a bulk
|
149
|
+
# job.
|
150
|
+
#
|
151
|
+
# @param [Fixnum] size number of elements
|
152
|
+
def bulk_job_size=(size)
|
153
|
+
@bulk_job_size = size
|
154
|
+
end
|
155
|
+
|
156
|
+
# The currently configured bulk job size.
|
157
|
+
def bulk_job_size
|
158
|
+
if defined? @bulk_job_size
|
159
|
+
@bulk_job_size
|
160
|
+
else
|
161
|
+
5000
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Are we currently in the midst of a bulk job?
|
166
|
+
def in_bulk_job?
|
167
|
+
@in_bulk_job if defined? @in_bulk_job
|
168
|
+
end
|
169
|
+
|
170
|
+
# Directly loads an array of vertices by id.
|
171
|
+
#
|
172
|
+
# @param [[vertex ids]] ids
|
173
|
+
# @return [[Pacer::VertexMixin]]
|
174
|
+
def load_vertices(ids)
|
175
|
+
ids.map do |id|
|
176
|
+
vertex id
|
177
|
+
end.compact
|
178
|
+
end
|
179
|
+
|
180
|
+
# Directly loads an array of edges by id.
|
181
|
+
#
|
182
|
+
# @param [[edge ids]] ids
|
183
|
+
# @return [[Pacer::EdgeMixin]]
|
184
|
+
def load_edges(ids)
|
185
|
+
ids.map do |id|
|
186
|
+
edge id
|
187
|
+
end.compact
|
188
|
+
end
|
189
|
+
|
190
|
+
# The current graph
|
191
|
+
#
|
192
|
+
# @return [Graph] returns self
|
193
|
+
def graph
|
194
|
+
self
|
195
|
+
end
|
196
|
+
|
197
|
+
def equals(other)
|
198
|
+
self == other
|
199
|
+
end
|
200
|
+
|
201
|
+
# The proc used to name vertices.
|
202
|
+
#
|
203
|
+
# @return [Proc]
|
204
|
+
def vertex_name
|
205
|
+
@vertex_name if defined? @vertex_name
|
206
|
+
end
|
207
|
+
|
208
|
+
# Set the proc used to name vertices.
|
209
|
+
#
|
210
|
+
# @param [Proc(vertex)] a_proc returns a string given a vertex
|
211
|
+
def vertex_name=(a_proc)
|
212
|
+
@vertex_name = a_proc
|
213
|
+
end
|
214
|
+
|
215
|
+
# The proc used to name edges.
|
216
|
+
#
|
217
|
+
# @return [Proc]
|
218
|
+
def edge_name
|
219
|
+
@edge_name if defined? @edge_name
|
220
|
+
end
|
221
|
+
|
222
|
+
# Set the proc used to name edges.
|
223
|
+
#
|
224
|
+
# @param [Proc(edge)] a_proc returns a string given an edge
|
225
|
+
def edge_name=(a_proc)
|
226
|
+
@edge_name = a_proc
|
227
|
+
end
|
228
|
+
|
229
|
+
# Is the element type given supported by this graph?
|
230
|
+
#
|
231
|
+
# @param [:edge, :vertex, :mixed, element_type, Object] et the
|
232
|
+
# object we're testing
|
233
|
+
def element_type?(et)
|
234
|
+
if [element_type(:vertex), element_type(:edge), element_type(:mixed)].include? element_type(et)
|
235
|
+
true
|
236
|
+
else
|
237
|
+
false
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# Does this graph support edges where the in_vertex and the
|
242
|
+
# out_vertex are the same?
|
243
|
+
#
|
244
|
+
# Specific graphs may override this method to return false.
|
245
|
+
def supports_circular_edges?
|
246
|
+
true
|
247
|
+
end
|
248
|
+
|
249
|
+
# When creating an element, does this graph allow me to specify the
|
250
|
+
# element_id?
|
251
|
+
#
|
252
|
+
# Specific graphs may override this method to return false.
|
253
|
+
def supports_custom_element_ids?
|
254
|
+
true
|
255
|
+
end
|
256
|
+
|
257
|
+
# Does this graph allow me to create or modify automatic indices?
|
258
|
+
#
|
259
|
+
# Specific graphs may override this method to return false.
|
260
|
+
def supports_automatic_indices?
|
261
|
+
false
|
262
|
+
end
|
263
|
+
|
264
|
+
# Does this graph allow me to create or modify manual indices?
|
265
|
+
#
|
266
|
+
# Specific graphs may override this method to return false.
|
267
|
+
def supports_manual_indices?
|
268
|
+
false
|
269
|
+
end
|
270
|
+
|
271
|
+
# Does this graph support indices on edges?
|
272
|
+
#
|
273
|
+
# Specific graphs may override this method to return false.
|
274
|
+
def supports_edge_indices?
|
275
|
+
false
|
276
|
+
end
|
277
|
+
|
278
|
+
def element_type(et = nil)
|
279
|
+
return nil unless et
|
280
|
+
result = if et == vertex_class or et == edge_class or et == element_class
|
281
|
+
et
|
282
|
+
else
|
283
|
+
case et
|
284
|
+
when :vertex, Pacer::Vertex, VertexMixin
|
285
|
+
vertex_class
|
286
|
+
when :edge, Pacer::Edge, EdgeMixin
|
287
|
+
edge_class
|
288
|
+
when :mixed, Pacer::Element, ElementMixin
|
289
|
+
element_class
|
290
|
+
when :object
|
291
|
+
Object
|
292
|
+
else
|
293
|
+
if et == Object
|
294
|
+
Object
|
295
|
+
elsif vertex_class.respond_to? :java_class
|
296
|
+
if et == vertex_class.java_class.to_java
|
297
|
+
vertex_class
|
298
|
+
elsif et == edge_class.java_class.to_java
|
299
|
+
edge_class
|
300
|
+
elsif et == Pacer::Vertex.java_class.to_java
|
301
|
+
vertex_class
|
302
|
+
elsif et == Pacer::Edge.java_class.to_java
|
303
|
+
edge_class
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
if result
|
309
|
+
result
|
310
|
+
else
|
311
|
+
raise ArgumentError, 'Element type may be one of :vertex, :edge, :mixed or :object'
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def sanitize_properties(props)
|
316
|
+
props
|
317
|
+
end
|
318
|
+
|
319
|
+
def encode_property(value)
|
320
|
+
if value.is_a? String
|
321
|
+
value = value.strip
|
322
|
+
value unless value == ''
|
323
|
+
else
|
324
|
+
value
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def decode_property(value)
|
329
|
+
value
|
330
|
+
end
|
331
|
+
|
332
|
+
def edges
|
333
|
+
getEdges
|
334
|
+
end
|
335
|
+
|
336
|
+
protected
|
337
|
+
|
338
|
+
# Helper method to wrap element creation in exception handling.
|
339
|
+
def creating_elements
|
340
|
+
begin
|
341
|
+
yield
|
342
|
+
rescue NativeException => e
|
343
|
+
if e.message =~ /already exists/
|
344
|
+
raise ElementExists, e.message
|
345
|
+
else
|
346
|
+
raise
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
def id_modules_properties(args)
|
352
|
+
props = args.last if args.last.is_a? Hash
|
353
|
+
modules = args.select { |obj| obj.is_a? Module or obj.is_a? Class }
|
354
|
+
wrapper = modules.detect { |obj| obj.is_a? Class and obj.ancestors.include? Pacer::Wrappers::ElementWrapper }
|
355
|
+
modules.delete wrapper
|
356
|
+
id = args.first
|
357
|
+
id = nil if id == props or modules.include? id or id == wrapper
|
358
|
+
[id, wrapper, modules, props]
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module Pacer
|
2
|
+
import com.tinkerpop.blueprints.pgm.TransactionalGraph
|
3
|
+
|
4
|
+
# Collect a global set of graphs that are currently in a transaction.
|
5
|
+
#
|
6
|
+
# @return [Set] graphs with an open transaction
|
7
|
+
def self.graphs_in_transaction
|
8
|
+
@graphs = Set[] unless defined? @graphs
|
9
|
+
@graphs
|
10
|
+
end
|
11
|
+
|
12
|
+
# Methods used internally to do 'managed transactions' which I define
|
13
|
+
# as transactions that are started and committed automatically
|
14
|
+
# internally, typically on operations that potentially touch a large
|
15
|
+
# number of elements.
|
16
|
+
#
|
17
|
+
# The reason for keeping track of these separately is to prevent them
|
18
|
+
# from being confused with manual transactions. Although when this was
|
19
|
+
# written, I had made manual transactions nestable. That has been
|
20
|
+
# since explicitly disallowed by Blueprints. I am not sure if this
|
21
|
+
# code is actually needed anymore (if it was refactored out).
|
22
|
+
#
|
23
|
+
# TODO: the method names in this module need to be cleaned up.
|
24
|
+
# TODO: some methods may be able to be eliminated.
|
25
|
+
module ManagedTransactionsMixin
|
26
|
+
def manage_transactions=(v)
|
27
|
+
@manage_transactions = v
|
28
|
+
end
|
29
|
+
|
30
|
+
def manage_transactions?
|
31
|
+
@manage_transactions = true unless defined? @manage_transactions
|
32
|
+
@manage_transactions
|
33
|
+
end
|
34
|
+
alias manage_transactions manage_transactions?
|
35
|
+
|
36
|
+
def unmanaged_transactions
|
37
|
+
old_value = manage_transactions
|
38
|
+
@manage_transactions = false
|
39
|
+
yield
|
40
|
+
ensure
|
41
|
+
@manage_transactions = old_value
|
42
|
+
end
|
43
|
+
|
44
|
+
def managed_transactions
|
45
|
+
if manage_transactions?
|
46
|
+
manual_transactions { yield }
|
47
|
+
else
|
48
|
+
yield
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def managed_manual_transaction
|
53
|
+
if manage_transactions?
|
54
|
+
manual_transaction { yield }
|
55
|
+
else
|
56
|
+
yield
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def managed_transaction
|
61
|
+
if manage_transactions?
|
62
|
+
transaction { yield }
|
63
|
+
else
|
64
|
+
yield
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def managed_start_transaction
|
69
|
+
begin_transaction if manage_transactions?
|
70
|
+
end
|
71
|
+
|
72
|
+
def managed_commit_transaction
|
73
|
+
commit_transaction if manage_transactions?
|
74
|
+
end
|
75
|
+
|
76
|
+
def managed_checkpoint
|
77
|
+
checkpoint if manage_transactions?
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# This is included into graphs that don't support transactions so that
|
82
|
+
# their interface is the same as for graphs that do support them.
|
83
|
+
#
|
84
|
+
# All methods in this module do nothing but yield or return values
|
85
|
+
# that match those in {GraphTransactionsMixin}
|
86
|
+
module GraphTransactionsStub
|
87
|
+
def in_transaction?
|
88
|
+
false
|
89
|
+
end
|
90
|
+
|
91
|
+
def manual_transaction
|
92
|
+
yield
|
93
|
+
end
|
94
|
+
|
95
|
+
def manual_transactions
|
96
|
+
yield
|
97
|
+
end
|
98
|
+
|
99
|
+
def transaction
|
100
|
+
yield
|
101
|
+
end
|
102
|
+
|
103
|
+
def begin_transaction
|
104
|
+
end
|
105
|
+
|
106
|
+
def commit_transaction
|
107
|
+
end
|
108
|
+
|
109
|
+
def rollback_transaction
|
110
|
+
end
|
111
|
+
|
112
|
+
def checkpoint
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Add features to transactions to allow them to be more rubyish and
|
117
|
+
# more convenient to use.
|
118
|
+
#
|
119
|
+
# TODO: the method names in this module need to be cleaned up.
|
120
|
+
# TODO: some methods may be able to be eliminated.
|
121
|
+
module GraphTransactionsMixin
|
122
|
+
def self.included(target)
|
123
|
+
target.send :protected, :startTransaction, :start_transaction
|
124
|
+
end
|
125
|
+
|
126
|
+
def in_transaction?
|
127
|
+
Pacer.graphs_in_transaction.include? self
|
128
|
+
end
|
129
|
+
|
130
|
+
def manual_transaction
|
131
|
+
manual_transactions do
|
132
|
+
transaction do
|
133
|
+
yield
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def manual_transactions
|
139
|
+
original_buffer_size = getMaxBufferSize
|
140
|
+
if original_buffer_size != 0
|
141
|
+
begin
|
142
|
+
puts "transaction buffer size reset to 0 (MANUAL)" if Pacer.verbose == :very
|
143
|
+
setMaxBufferSize 0
|
144
|
+
yield
|
145
|
+
rescue Exception
|
146
|
+
rollback_transaction if in_transaction?
|
147
|
+
raise
|
148
|
+
ensure
|
149
|
+
puts "transaction buffer size reset to #{ original_buffer_size }" if Pacer.verbose == :very
|
150
|
+
setMaxBufferSize original_buffer_size
|
151
|
+
end
|
152
|
+
else
|
153
|
+
yield
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def transaction
|
158
|
+
begin_transaction
|
159
|
+
conclusion = TransactionalGraph::Conclusion::FAILURE
|
160
|
+
begin
|
161
|
+
catch :transaction_failed do
|
162
|
+
yield
|
163
|
+
conclusion = TransactionalGraph::Conclusion::SUCCESS
|
164
|
+
end
|
165
|
+
rescue Exception
|
166
|
+
puts "transaction aborted" if Pacer.verbose == :very
|
167
|
+
raise
|
168
|
+
ensure
|
169
|
+
puts "transaction finished #{ conclusion }" if Pacer.verbose == :very
|
170
|
+
stop_transaction conclusion
|
171
|
+
Pacer.graphs_in_transaction.delete self
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def begin_transaction
|
176
|
+
r = startTransaction
|
177
|
+
Pacer.graphs_in_transaction << self
|
178
|
+
puts "transaction started" if Pacer.verbose == :very
|
179
|
+
r
|
180
|
+
end
|
181
|
+
|
182
|
+
def commit_transaction
|
183
|
+
r = stop_transaction TransactionalGraph::Conclusion::SUCCESS
|
184
|
+
Pacer.graphs_in_transaction.delete self
|
185
|
+
puts "transaction committed" if Pacer.verbose == :very
|
186
|
+
r
|
187
|
+
end
|
188
|
+
|
189
|
+
def rollback_transaction
|
190
|
+
r = stop_transaction TransactionalGraph::Conclusion::FAILURE
|
191
|
+
Pacer.graphs_in_transaction.delete self
|
192
|
+
puts "transaction rolled back" if Pacer.verbose == :very
|
193
|
+
r
|
194
|
+
end
|
195
|
+
|
196
|
+
def checkpoint(success = true)
|
197
|
+
if success
|
198
|
+
commit_transaction
|
199
|
+
else
|
200
|
+
rollback_transaction
|
201
|
+
end
|
202
|
+
begin_transaction
|
203
|
+
Pacer.graphs_in_transaction << self
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Pacer
|
2
|
+
module IndexMixin
|
3
|
+
def graph=(graph)
|
4
|
+
@graph = graph
|
5
|
+
end
|
6
|
+
|
7
|
+
def graph
|
8
|
+
@graph if defined? @graph
|
9
|
+
end
|
10
|
+
|
11
|
+
def first(key, value, extensions = nil)
|
12
|
+
e = get(key, value).first
|
13
|
+
if e and (graph or extensions)
|
14
|
+
e.graph = graph
|
15
|
+
e.add_extensions extensions
|
16
|
+
end
|
17
|
+
e
|
18
|
+
end
|
19
|
+
|
20
|
+
def all(key, value, extensions = nil)
|
21
|
+
iter = get(key, value)
|
22
|
+
if graph or extensions
|
23
|
+
iter.extend Pacer::Core::Route::IteratorExtensionsMixin
|
24
|
+
iter.graph = graph
|
25
|
+
iter.extensions = extensions
|
26
|
+
end
|
27
|
+
iter
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Pacer
|
2
|
+
# This module is mixed into the raw Blueprints Vertex class from any
|
3
|
+
# graph implementation.
|
4
|
+
#
|
5
|
+
# Adds more convenient/rubyish methods and adds support for extensions
|
6
|
+
# to some methods where needed.
|
7
|
+
module VertexMixin
|
8
|
+
# Add extensions to this vertex.
|
9
|
+
#
|
10
|
+
# If any extension has a Vertex module within it, this vertex will
|
11
|
+
# be extended with the extension's Vertex module.
|
12
|
+
#
|
13
|
+
# @see Core::Route#add_extension
|
14
|
+
#
|
15
|
+
# @param [[extensions]] exts the extensions to add
|
16
|
+
# @return [Pacer::EdgeWrapper] this vertex wrapped up and including
|
17
|
+
# the extensions
|
18
|
+
def add_extensions(exts)
|
19
|
+
if exts.any?
|
20
|
+
Wrappers::VertexWrapper.wrap(self, exts)
|
21
|
+
else
|
22
|
+
self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a human-readable representation of the vertex using the
|
27
|
+
# standard ruby console representation of an instantiated object.
|
28
|
+
# @return [String]
|
29
|
+
def inspect
|
30
|
+
"#<#{ ["V[#{element_id}]", display_name].compact.join(' ') }>"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the display name of the vertex.
|
34
|
+
# @return [String]
|
35
|
+
def display_name
|
36
|
+
graph.vertex_name.call self if graph and graph.vertex_name
|
37
|
+
end
|
38
|
+
|
39
|
+
# Deletes the vertex from its graph along with all related edges.
|
40
|
+
def delete!
|
41
|
+
graph.removeVertex element
|
42
|
+
end
|
43
|
+
|
44
|
+
# Copies including the vertex id unless a vertex with that id
|
45
|
+
# already exists.
|
46
|
+
# @param [Pacer::GraphMixin] target_graph
|
47
|
+
# @param opts for compatibility with {Pacer::EdgeMixin#clone_into}
|
48
|
+
# @yield [v] Optional block yields the vertex after it has been created.
|
49
|
+
# @return [Pacer::VertexMixin] the new vertex
|
50
|
+
def clone_into(target_graph, opts = nil)
|
51
|
+
v_idx = target_graph.index_name("tmp:v:#{graph.to_s}", :vertex, :create => true)
|
52
|
+
v = target_graph.vertex(element_id) || v_idx.get('id', element_id).first
|
53
|
+
unless v
|
54
|
+
v = target_graph.create_vertex element_id, properties
|
55
|
+
v_idx.put('id', element_id, v)
|
56
|
+
yield v if block_given?
|
57
|
+
end
|
58
|
+
v
|
59
|
+
end
|
60
|
+
|
61
|
+
# Make a new copy of the element with the next available vertex id.
|
62
|
+
#
|
63
|
+
# @param [Pacer::GraphMixin] target_graph
|
64
|
+
# @yield [v] Optional block yields the vertex after it has been created.
|
65
|
+
# @return [Pacer::VertexMixin] the new vertex
|
66
|
+
def copy_into(target_graph)
|
67
|
+
v = target_graph.create_vertex properties
|
68
|
+
yield v if block_given?
|
69
|
+
v
|
70
|
+
end
|
71
|
+
|
72
|
+
def raw_out_edges(*labels)
|
73
|
+
element.getOutEdges *labels
|
74
|
+
end
|
75
|
+
|
76
|
+
def raw_in_edges(*labels)
|
77
|
+
element.getInEdges *labels
|
78
|
+
end
|
79
|
+
|
80
|
+
def out_edges(*labels_and_extensions)
|
81
|
+
labels, exts = split_labels_and_extensions(labels_and_extensions)
|
82
|
+
edge_iterator(raw_out_edges(*labels).iterator, exts)
|
83
|
+
end
|
84
|
+
|
85
|
+
def in_edges(*labels_and_extensions)
|
86
|
+
labels, exts = split_labels_and_extensions(labels_and_extensions)
|
87
|
+
edge_iterator(raw_in_edges(*labels).iterator, exts)
|
88
|
+
end
|
89
|
+
|
90
|
+
def both_edges(*labels_and_extensions)
|
91
|
+
labels, exts = split_labels_and_extensions(labels_and_extensions)
|
92
|
+
ins = raw_in_edges(*labels).iterator
|
93
|
+
outs = raw_out_edges(*labels).iterator
|
94
|
+
edge_iterator(Pacer::Pipes::MultiIterator.new(ins, outs), exts)
|
95
|
+
end
|
96
|
+
|
97
|
+
protected
|
98
|
+
|
99
|
+
def split_labels_and_extensions(mixed)
|
100
|
+
labels = Set[]
|
101
|
+
exts = Set[]
|
102
|
+
mixed.each do |obj|
|
103
|
+
if obj.is_a? Symbol or obj.is_a? String
|
104
|
+
labels << obj
|
105
|
+
else
|
106
|
+
exts << obj
|
107
|
+
end
|
108
|
+
end
|
109
|
+
[labels, exts]
|
110
|
+
end
|
111
|
+
|
112
|
+
def edge_iterator(iter, exts)
|
113
|
+
iter.extend Pacer::Core::Route::IteratorExtensionsMixin
|
114
|
+
iter.graph = self.graph
|
115
|
+
iter.extensions = exts
|
116
|
+
iter
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|