pacer 0.9.1.1-java
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.
- 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
|