pacer 0.9.1.1-java → 1.0.0-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 +4 -1
- data/.gitignore +4 -0
- data/.rspec +1 -1
- data/Gemfile-dev +33 -0
- data/Gemfile-release +4 -0
- data/README.md +27 -9
- data/Rakefile +26 -8
- data/bin/autotest +1 -1
- data/lib/pacer/blueprints/multi_graph.rb +7 -19
- data/lib/pacer/blueprints/ruby_graph.rb +77 -52
- data/lib/pacer/blueprints/tg.rb +6 -93
- data/lib/pacer/blueprints.rb +0 -1
- data/lib/pacer/core/graph/edges_route.rb +10 -12
- data/lib/pacer/core/graph/element_route.rb +14 -21
- data/lib/pacer/core/graph/graph_index_route.rb +12 -8
- data/lib/pacer/core/graph/graph_route.rb +2 -5
- data/lib/pacer/core/graph/mixed_route.rb +3 -5
- data/lib/pacer/core/graph/vertices_route.rb +26 -27
- data/lib/pacer/core/route.rb +35 -66
- data/lib/pacer/exceptions.rb +13 -6
- data/lib/pacer/extensions/block_filter_element.rb +0 -5
- data/lib/pacer/filter/collection_filter.rb +9 -2
- data/lib/pacer/filter/empty_filter.rb +12 -3
- data/lib/pacer/filter/future_filter.rb +5 -5
- data/lib/pacer/filter/loop_filter.rb +7 -13
- data/lib/pacer/filter/object_filter.rb +10 -16
- data/lib/pacer/filter/property_filter/filters.rb +134 -93
- data/lib/pacer/filter/property_filter.rb +22 -19
- data/lib/pacer/filter/where_filter/node_visitor.rb +47 -26
- data/lib/pacer/filter/where_filter.rb +24 -3
- data/lib/pacer/function_resolver.rb +7 -2
- data/lib/pacer/graph/graph_ml.rb +39 -0
- data/lib/pacer/graph/graph_transactions_mixin.rb +107 -175
- data/lib/pacer/graph/pacer_graph.rb +438 -0
- data/lib/pacer/graph/simple_encoder.rb +20 -0
- data/lib/pacer/graph/yaml_encoder.rb +81 -0
- data/lib/pacer/graph.rb +8 -10
- data/lib/pacer/pipe/blackbox_pipeline.rb +11 -4
- data/lib/pacer/pipe/block_filter_pipe.rb +5 -22
- data/lib/pacer/pipe/cross_product_transform_pipe.rb +5 -7
- data/lib/pacer/pipe/edges_pipe.rb +22 -0
- data/lib/pacer/pipe/enumerable_pipe.rb +3 -9
- data/lib/pacer/pipe/expandable_pipe.rb +2 -14
- data/lib/pacer/pipe/id_collection_filter_pipe.rb +2 -8
- data/lib/pacer/pipe/is_empty_pipe.rb +5 -12
- data/lib/pacer/pipe/is_unique_pipe.rb +3 -13
- data/lib/pacer/pipe/label_collection_filter_pipe.rb +1 -7
- data/lib/pacer/pipe/label_prefix_pipe.rb +0 -6
- data/lib/pacer/pipe/loop_pipe.rb +27 -25
- data/lib/pacer/pipe/never_pipe.rb +1 -1
- data/lib/pacer/pipe/path_wrapping_pipe.rb +40 -0
- data/lib/pacer/pipe/process_pipe.rb +2 -20
- data/lib/pacer/pipe/property_comparison_pipe.rb +0 -6
- data/lib/pacer/pipe/ruby_pipe.rb +10 -3
- data/lib/pacer/pipe/simple_visitor_pipe.rb +12 -11
- data/lib/pacer/pipe/stream_sort_pipe.rb +1 -7
- data/lib/pacer/pipe/stream_uniq_pipe.rb +0 -6
- data/lib/pacer/pipe/type_filter_pipe.rb +1 -7
- data/lib/pacer/pipe/unary_transform_pipe.rb +6 -8
- data/lib/pacer/pipe/unwrapping_pipe.rb +13 -0
- data/lib/pacer/pipe/vertices_pipe.rb +22 -0
- data/lib/pacer/pipe/visitor_pipe.rb +3 -7
- data/lib/pacer/pipe/wrapping_pipe.rb +37 -0
- data/lib/pacer/pipes.rb +17 -12
- data/lib/pacer/route/mixin/bulk_operations.rb +8 -9
- data/lib/pacer/route/mixin/route_operations.rb +17 -11
- data/lib/pacer/route/mixins.rb +0 -1
- data/lib/pacer/route.rb +198 -121
- data/lib/pacer/side_effect/aggregate.rb +22 -2
- data/lib/pacer/side_effect/as.rb +73 -0
- data/lib/pacer/side_effect/group_count.rb +0 -3
- data/lib/pacer/side_effect/is_unique.rb +7 -6
- data/lib/pacer/side_effect.rb +1 -1
- data/lib/pacer/support/enumerable.rb +14 -12
- data/lib/pacer/support/nil_class.rb +5 -0
- data/lib/pacer/support/proc.rb +2 -2
- data/lib/pacer/support.rb +1 -1
- data/lib/pacer/transform/cap.rb +1 -1
- data/lib/pacer/transform/has_count_cap.rb +1 -1
- data/lib/pacer/transform/join.rb +20 -16
- data/lib/pacer/transform/map.rb +6 -2
- data/lib/pacer/transform/path.rb +44 -20
- data/lib/pacer/transform/sort_section.rb +58 -51
- data/lib/pacer/utils/tsort.rb +7 -2
- data/lib/pacer/utils.rb +0 -1
- data/lib/pacer/version.rb +4 -3
- data/lib/pacer/visitors/section.rb +42 -0
- data/lib/pacer/visitors/visits_section.rb +32 -0
- data/lib/pacer/visitors.rb +7 -0
- data/lib/pacer/wrappers/edge_wrapper.rb +164 -11
- data/lib/pacer/wrappers/element_wrapper.rb +133 -8
- data/lib/pacer/wrappers/index_wrapper.rb +47 -0
- data/lib/pacer/wrappers/vertex_wrapper.rb +175 -12
- data/lib/pacer/wrappers/wrapper_selector.rb +40 -0
- data/lib/pacer/wrappers/wrapping_pipe_function.rb +90 -0
- data/lib/pacer/wrappers.rb +3 -1
- data/lib/pacer-1.0.0-standalone.jar +0 -0
- data/lib/pacer.rb +13 -47
- data/pacer.gemspec +0 -8
- data/pom.xml +10 -3
- data/spec/pacer/blueprints/dex_spec.rb +12 -26
- data/spec/pacer/blueprints/neo4j_spec.rb +14 -28
- data/spec/pacer/blueprints/tg_spec.rb +6 -54
- data/spec/pacer/core/graph/edges_route_spec.rb +1 -1
- data/spec/pacer/core/graph/element_route_spec.rb +2 -2
- data/spec/pacer/core/graph/graph_route_spec.rb +2 -2
- data/spec/pacer/core/graph/vertices_route_spec.rb +10 -3
- data/spec/pacer/core/route_spec.rb +35 -58
- data/spec/pacer/filter/empty_filter_spec.rb +5 -6
- data/spec/pacer/filter/future_filter_spec.rb +8 -8
- data/spec/pacer/filter/loop_filter_spec.rb +120 -6
- data/spec/pacer/filter/object_filter_spec.rb +15 -0
- data/spec/pacer/filter/property_filter/filters_spec.rb +169 -0
- data/spec/pacer/filter/property_filter_spec.rb +15 -12
- data/spec/pacer/filter/uniq_filter_spec.rb +1 -1
- data/spec/pacer/filter/where_filter_spec.rb +55 -7
- data/spec/pacer/graph/{graph_mixin_spec.rb → pacer_graph_spec.rb} +114 -185
- data/spec/pacer/route/mixin/base_spec.rb +36 -35
- data/spec/pacer/route/mixin/route_operations_spec.rb +4 -46
- data/spec/pacer/side_effect/as_spec.rb +34 -0
- data/spec/pacer/support/enumerable_spec.rb +6 -6
- data/spec/pacer/transform/join_spec.rb +7 -5
- data/spec/pacer/transform/map_spec.rb +55 -0
- data/spec/pacer/transform/path_spec.rb +30 -15
- data/spec/pacer/transform/process_spec.rb +42 -0
- data/spec/pacer/transform/sort_section_spec.rb +82 -0
- data/spec/pacer/wrapper/edge_wrapper_spec.rb +122 -2
- data/spec/pacer/wrapper/element_wrapper_spec.rb +289 -3
- data/spec/pacer/wrapper/vertex_wrapper_spec.rb +289 -2
- data/spec/spec_helper.rb +16 -7
- data/spec/support/graph_runner.rb +80 -29
- data/tags +1165 -0
- metadata +46 -107
- data/.rvmrc +0 -0
- data/lib/pacer/blueprints/extensions.rb +0 -77
- data/lib/pacer/graph/edge_mixin.rb +0 -127
- data/lib/pacer/graph/element_mixin.rb +0 -202
- data/lib/pacer/graph/graph_indices_mixin.rb +0 -93
- data/lib/pacer/graph/graph_mixin.rb +0 -361
- data/lib/pacer/graph/index_mixin.rb +0 -30
- data/lib/pacer/graph/vertex_mixin.rb +0 -119
- data/lib/pacer/pipe/map_pipe.rb +0 -36
- data/lib/pacer/pipe/variable_store_iterator_wrapper.rb +0 -26
- data/lib/pacer/route/mixin/variable_route_module.rb +0 -26
- data/lib/pacer/side_effect/section.rb +0 -25
- data/lib/pacer/support/iterator_mixins.rb +0 -110
- data/lib/pacer/wrappers/new_element.rb +0 -106
- data/lib/pacer-0.9.1.1-standalone.jar +0 -0
- data/spec/pacer/graph/edge_mixin_spec.rb +0 -116
- data/spec/pacer/graph/element_mixin_spec.rb +0 -297
- data/spec/pacer/graph/index_mixin_spec.rb +0 -0
- data/spec/pacer/graph/vertex_mixin_spec.rb +0 -192
@@ -0,0 +1,438 @@
|
|
1
|
+
module Pacer
|
2
|
+
class PacerGraph
|
3
|
+
include GraphTransactionsMixin
|
4
|
+
|
5
|
+
include Pacer::Core::Route
|
6
|
+
include Pacer::Core::Graph::GraphRoute
|
7
|
+
include Pacer::Core::Graph::GraphIndexRoute
|
8
|
+
|
9
|
+
attr_reader :blueprints_graph, :encoder
|
10
|
+
|
11
|
+
def initialize(encoder, open, shutdown = nil)
|
12
|
+
@reopen = open
|
13
|
+
@shutdown = shutdown
|
14
|
+
reopen
|
15
|
+
@encoder = encoder
|
16
|
+
end
|
17
|
+
|
18
|
+
# The current graph
|
19
|
+
#
|
20
|
+
# @return [PacerGraph] returns self
|
21
|
+
def graph
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def reopen
|
26
|
+
graph = @reopen.call
|
27
|
+
if graph.is_a? PacerGraph
|
28
|
+
@blueprints_graph = graph.blueprints_graph
|
29
|
+
else
|
30
|
+
@blueprints_graph = graph
|
31
|
+
end
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def shutdown
|
36
|
+
@shutdown.call self if @shutdown
|
37
|
+
@blueprints_graph = nil
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def graph_id
|
42
|
+
blueprints_graph.object_id
|
43
|
+
end
|
44
|
+
|
45
|
+
def equals(other)
|
46
|
+
other.class == self.class and graph_id == other.graph_id
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get a vertex by id.
|
50
|
+
#
|
51
|
+
# @overload vertex(id)
|
52
|
+
# @param [element id] id
|
53
|
+
# @overload vertex(id, *modules)
|
54
|
+
# @param [element id] id
|
55
|
+
# @param [Module, Class] *modules extensions to add to the returned
|
56
|
+
# vertex.
|
57
|
+
def vertex(id, *modules)
|
58
|
+
begin
|
59
|
+
v = blueprints_graph.getVertex(id)
|
60
|
+
rescue java.lang.RuntimeException
|
61
|
+
end
|
62
|
+
if v
|
63
|
+
wrapper = modules.detect { |obj| obj.ancestors.include? Pacer::Wrappers::VertexWrapper }
|
64
|
+
if wrapper
|
65
|
+
v = wrapper.new v
|
66
|
+
modules.delete wrapper
|
67
|
+
else
|
68
|
+
v = Pacer::Wrappers::VertexWrapper.new v
|
69
|
+
end
|
70
|
+
v.graph = self
|
71
|
+
v.add_extensions modules
|
72
|
+
else
|
73
|
+
v
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Get an edge by id.
|
78
|
+
#
|
79
|
+
# @overload edge(id)
|
80
|
+
# @param [element id] id
|
81
|
+
# @overload edge(id, *modules)
|
82
|
+
# @param [element id] id
|
83
|
+
# @param [Module, Class] *modules extensions to add to the returned
|
84
|
+
# edge.
|
85
|
+
def edge(id, *modules)
|
86
|
+
begin
|
87
|
+
v = blueprints_graph.getEdge(id)
|
88
|
+
rescue Java::JavaLang::RuntimeException
|
89
|
+
end
|
90
|
+
if v
|
91
|
+
wrapper = modules.detect { |obj| obj.ancestors.include? Pacer::Wrappers::EdgeWrapper }
|
92
|
+
if wrapper
|
93
|
+
v = wrapper.new v
|
94
|
+
modules.delete wrapper
|
95
|
+
else
|
96
|
+
v = Pacer::Wrappers::EdgeWrapper.new v
|
97
|
+
end
|
98
|
+
v.graph = self
|
99
|
+
v.add_extensions modules
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Create a vertex in the graph.
|
104
|
+
#
|
105
|
+
# @overload create_vertex(*args)
|
106
|
+
# @param [extension, Hash] *args extension (Module/Class) arguments will be
|
107
|
+
# added to the current vertex. A Hash will be
|
108
|
+
# treated as element properties.
|
109
|
+
# @overload create_vertex(id, *args)
|
110
|
+
# @param [element id] id the desired element id. Some graphs
|
111
|
+
# ignore this.
|
112
|
+
# @param [extension, Hash] *args extension (Module/Class) arguments will be
|
113
|
+
# added to the current vertex. A Hash will be
|
114
|
+
# treated as element properties.
|
115
|
+
def create_vertex(*args)
|
116
|
+
id, wrapper, modules, props = id_modules_properties(args)
|
117
|
+
raw_vertex = creating_elements { blueprints_graph.addVertex(id) }
|
118
|
+
if wrapper
|
119
|
+
vertex = wrapper.new raw_vertex
|
120
|
+
else
|
121
|
+
vertex = Pacer::Wrappers::VertexWrapper.new raw_vertex
|
122
|
+
end
|
123
|
+
if modules.any?
|
124
|
+
vertex = vertex.add_extensions modules
|
125
|
+
end
|
126
|
+
vertex.graph = self
|
127
|
+
props.each { |k, v| vertex[k.to_s] = v } if props
|
128
|
+
vertex
|
129
|
+
end
|
130
|
+
|
131
|
+
# Create an edge in the graph.
|
132
|
+
#
|
133
|
+
# @param [element id] id some graphs allow you to specify your own edge id.
|
134
|
+
# @param [Pacer::Wrappers::VertexWrapper] from_v the new edge's out_vertex
|
135
|
+
# @param [Pacer::Wrappers::VertexWrapper] to_v the new edge's in_vertex
|
136
|
+
# @param [#to_s] label the edge label
|
137
|
+
# @param [extension, Hash] *args extension (Module/Class) arguments will be
|
138
|
+
# added to the returned edge. A Hash will be
|
139
|
+
# treated as element properties.
|
140
|
+
#
|
141
|
+
# @todo make id param optional
|
142
|
+
def create_edge(id, from_v, to_v, label, *args)
|
143
|
+
_, wrapper, modules, props = id_modules_properties(args)
|
144
|
+
raw_edge = creating_elements { blueprints_graph.addEdge(id, from_v.element, to_v.element, label.to_s) }
|
145
|
+
if wrapper
|
146
|
+
edge = wrapper.new raw_edge
|
147
|
+
else
|
148
|
+
edge = Pacer::Wrappers::EdgeWrapper.new raw_edge
|
149
|
+
end
|
150
|
+
if modules.any?
|
151
|
+
edge = edge.add_extensions modules
|
152
|
+
end
|
153
|
+
edge.graph = self
|
154
|
+
props.each { |k, v| edge[k.to_s] = v } if props
|
155
|
+
edge
|
156
|
+
end
|
157
|
+
|
158
|
+
def remove_vertex(vertex)
|
159
|
+
blueprints_graph.removeVertex vertex
|
160
|
+
end
|
161
|
+
|
162
|
+
def remove_edge(edge)
|
163
|
+
blueprints_graph.removeEdge edge
|
164
|
+
end
|
165
|
+
|
166
|
+
# Directly loads an array of vertices by id.
|
167
|
+
#
|
168
|
+
# @param [[vertex ids]] ids
|
169
|
+
# @return [[Pacer::Wrappers::VertexWrapper]]
|
170
|
+
def load_vertices(ids)
|
171
|
+
ids.map do |id|
|
172
|
+
vertex id
|
173
|
+
end.compact
|
174
|
+
end
|
175
|
+
|
176
|
+
# Directly loads an array of edges by id.
|
177
|
+
#
|
178
|
+
# @param [[edge ids]] ids
|
179
|
+
# @return [[Pacer::Wrappers::EdgeWrapper]]
|
180
|
+
def load_edges(ids)
|
181
|
+
ids.map do |id|
|
182
|
+
edge id
|
183
|
+
end.compact
|
184
|
+
end
|
185
|
+
|
186
|
+
def features
|
187
|
+
blueprints_graph.features
|
188
|
+
end
|
189
|
+
|
190
|
+
module Encoding
|
191
|
+
def sanitize_properties(props)
|
192
|
+
encoder.sanitize_properties props
|
193
|
+
end
|
194
|
+
|
195
|
+
def encode_property(value)
|
196
|
+
encoder.encode_property value
|
197
|
+
end
|
198
|
+
|
199
|
+
def decode_property(value)
|
200
|
+
encoder.decode_property value
|
201
|
+
end
|
202
|
+
end
|
203
|
+
include Encoding
|
204
|
+
|
205
|
+
module Naming
|
206
|
+
# The proc used to name vertices.
|
207
|
+
#
|
208
|
+
# @return [Proc]
|
209
|
+
def vertex_name
|
210
|
+
@vertex_name if defined? @vertex_name
|
211
|
+
end
|
212
|
+
|
213
|
+
# Set the proc used to name vertices.
|
214
|
+
#
|
215
|
+
# @param [Proc(vertex)] a_proc returns a string given a vertex
|
216
|
+
def vertex_name=(a_proc)
|
217
|
+
@vertex_name = a_proc
|
218
|
+
end
|
219
|
+
|
220
|
+
# The proc used to name edges.
|
221
|
+
#
|
222
|
+
# @return [Proc]
|
223
|
+
def edge_name
|
224
|
+
@edge_name if defined? @edge_name
|
225
|
+
end
|
226
|
+
|
227
|
+
# Set the proc used to name edges.
|
228
|
+
#
|
229
|
+
# @param [Proc(edge)] a_proc returns a string given an edge
|
230
|
+
def edge_name=(a_proc)
|
231
|
+
@edge_name = a_proc
|
232
|
+
end
|
233
|
+
end
|
234
|
+
include Naming
|
235
|
+
|
236
|
+
|
237
|
+
module BulkJob
|
238
|
+
attr_accessor :in_bulk_job
|
239
|
+
|
240
|
+
# Set how many elements should go into each transaction in a bulk
|
241
|
+
# job.
|
242
|
+
#
|
243
|
+
# @param [Fixnum] size number of elements
|
244
|
+
def bulk_job_size=(size)
|
245
|
+
@bulk_job_size = size
|
246
|
+
end
|
247
|
+
|
248
|
+
# The currently configured bulk job size.
|
249
|
+
def bulk_job_size
|
250
|
+
if defined? @bulk_job_size
|
251
|
+
@bulk_job_size
|
252
|
+
else
|
253
|
+
5000
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Are we currently in the midst of a bulk job?
|
258
|
+
def in_bulk_job?
|
259
|
+
@in_bulk_job if defined? @in_bulk_job
|
260
|
+
end
|
261
|
+
end
|
262
|
+
include BulkJob
|
263
|
+
|
264
|
+
module Indices
|
265
|
+
# Return an index by name.
|
266
|
+
#
|
267
|
+
# @param [#to_s] name of the index
|
268
|
+
# @param [:vertex, :edge, element type] type guarantees that the index returned is of the type specified.
|
269
|
+
# @param [Hash] opts
|
270
|
+
# @option opts [true] :create create the index if it doesn't exist
|
271
|
+
# @return [Pacer::IndexMixin]
|
272
|
+
def index(name, type = nil, opts = {})
|
273
|
+
return unless features.supportsIndices
|
274
|
+
name = name.to_s
|
275
|
+
if type
|
276
|
+
type = index_class element_type type
|
277
|
+
idx = blueprints_graph.getIndices.detect { |i| i.index_name == name }
|
278
|
+
if idx.nil? and opts[:create]
|
279
|
+
idx = blueprints_graph.createIndex name, type
|
280
|
+
end
|
281
|
+
else
|
282
|
+
idx = blueprints_graph.getIndices.detect { |i| i.index_name == name }
|
283
|
+
end
|
284
|
+
Pacer::Wrappers::IndexWrapper.new self, idx, type if idx
|
285
|
+
end
|
286
|
+
|
287
|
+
def drop_index(idx)
|
288
|
+
return unless features.supportsIndices
|
289
|
+
if idx.is_a? String or idx.is_a? Symbol
|
290
|
+
blueprints_graph.dropIndex idx
|
291
|
+
else
|
292
|
+
blueprints_graph.dropIndex idx.indexName
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# Return an object that can be compared to the return value of
|
297
|
+
# Index#index_class.
|
298
|
+
def index_class(et)
|
299
|
+
type = case et
|
300
|
+
when :vertex
|
301
|
+
Pacer::Vertex
|
302
|
+
when :edge
|
303
|
+
Pacer::Edge
|
304
|
+
else
|
305
|
+
fail InternalError, "Unable to determine index class from #{ et.inspect }"
|
306
|
+
end
|
307
|
+
type.java_class.to_java
|
308
|
+
end
|
309
|
+
|
310
|
+
def index_class?(et, thing)
|
311
|
+
if thing.interface?
|
312
|
+
index_class(et) == thing
|
313
|
+
else
|
314
|
+
thing.interfaces.include? index_class(et)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def indices
|
319
|
+
if features.supportsIndices
|
320
|
+
blueprints_graph.getIndices
|
321
|
+
else
|
322
|
+
[]
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
include Indices
|
327
|
+
|
328
|
+
module KeyIndices
|
329
|
+
def create_key_index(name, type)
|
330
|
+
if features.supportsKeyIndices
|
331
|
+
if element_type(type) == :vertex and features.supportsVertexKeyIndex
|
332
|
+
blueprints_graph.createKeyIndex name, index_class(:vertex)
|
333
|
+
elsif element_type(type) == :edge and features.supportsEdgeKeyIndex
|
334
|
+
blueprints_graph.createKeyIndex name, index_class(:edge)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def key_indices(type = nil)
|
340
|
+
if features.supportsKeyIndices
|
341
|
+
if type
|
342
|
+
blueprints_graph.getIndexedKeys(index_class(type)).to_set
|
343
|
+
else
|
344
|
+
blueprints_graph.getIndexedKeys(index_class(:vertex)).to_set +
|
345
|
+
blueprints_graph.getIndexedKeys(index_class(:vertex))
|
346
|
+
end
|
347
|
+
else
|
348
|
+
[]
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
include KeyIndices
|
353
|
+
|
354
|
+
module ElementType
|
355
|
+
# Is the element type given supported by this graph?
|
356
|
+
#
|
357
|
+
# @param [:edge, :vertex, :mixed, element_type, Object] et the
|
358
|
+
# object we're testing
|
359
|
+
def element_type?(et)
|
360
|
+
[:vertex, :edge, :mixed].include? element_type(et)
|
361
|
+
end
|
362
|
+
|
363
|
+
def element_type(et = nil)
|
364
|
+
return nil unless et
|
365
|
+
result = case et
|
366
|
+
when :vertex, Pacer::Vertex
|
367
|
+
:vertex
|
368
|
+
when :edge, Pacer::Edge
|
369
|
+
:edge
|
370
|
+
when :mixed, Pacer::Element
|
371
|
+
:mixed
|
372
|
+
when :object
|
373
|
+
:object
|
374
|
+
else
|
375
|
+
if et == Object
|
376
|
+
:object
|
377
|
+
elsif et == index_class(:vertex)
|
378
|
+
:vertex
|
379
|
+
elsif et == index_class(:edge)
|
380
|
+
:edge
|
381
|
+
end
|
382
|
+
end
|
383
|
+
if result
|
384
|
+
result
|
385
|
+
else
|
386
|
+
raise ArgumentError, 'Element type may be one of :vertex, :edge, :mixed or :object'
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
include ElementType
|
391
|
+
|
392
|
+
private
|
393
|
+
|
394
|
+
def id_modules_properties(args)
|
395
|
+
props = args.last if args.last.is_a? Hash
|
396
|
+
modules = args.select { |obj| obj.is_a? Module or obj.is_a? Class }
|
397
|
+
wrapper = modules.detect { |obj| obj.is_a? Class and obj.ancestors.include? Pacer::Wrappers::ElementWrapper }
|
398
|
+
id = args.first
|
399
|
+
if not wrapper and modules.empty?
|
400
|
+
args.each do |obj|
|
401
|
+
if obj.respond_to? :wrapper
|
402
|
+
wrapper = obj.wrapper
|
403
|
+
id = nil if id == obj
|
404
|
+
break
|
405
|
+
elsif obj.respond_to? :parts
|
406
|
+
modules = obj.parts
|
407
|
+
id = nil if id == obj
|
408
|
+
break
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
modules.delete wrapper
|
413
|
+
begin
|
414
|
+
id = nil if id == props or modules.include? id or id == wrapper
|
415
|
+
rescue Exception
|
416
|
+
# Orient uses an ID type that can't be compared with things?
|
417
|
+
end
|
418
|
+
[id, wrapper, modules, props]
|
419
|
+
end
|
420
|
+
|
421
|
+
# Helper method to wrap element creation in exception handling.
|
422
|
+
def creating_elements
|
423
|
+
begin
|
424
|
+
yield
|
425
|
+
rescue NativeException => e
|
426
|
+
if e.message =~ /already exists/
|
427
|
+
raise ElementExists, e.message
|
428
|
+
else
|
429
|
+
raise
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def source_iterator
|
435
|
+
[blueprints_graph]
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Pacer
|
2
|
+
class SimpleEncoder
|
3
|
+
def self.sanitize_properties(props)
|
4
|
+
props
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.encode_property(value)
|
8
|
+
if value.is_a? String
|
9
|
+
value = value.strip
|
10
|
+
value unless value == ''
|
11
|
+
else
|
12
|
+
value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.decode_property(value)
|
17
|
+
value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Pacer
|
2
|
+
# This encoder was originally part of pacer-neo4j. It uses native data where
|
3
|
+
# Neo4j could and for everything else it uses (slow (but easy))
|
4
|
+
# human-readable YAML encoding.
|
5
|
+
class YamlEncoder
|
6
|
+
def self.sanitize_properties(props)
|
7
|
+
pairs = props.map do |name, value|
|
8
|
+
[name, encode_property(value)]
|
9
|
+
end
|
10
|
+
Hash[pairs]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.encode_property(value)
|
14
|
+
case value
|
15
|
+
when nil
|
16
|
+
nil
|
17
|
+
when String
|
18
|
+
value = value.strip
|
19
|
+
value = nil if value == ''
|
20
|
+
value
|
21
|
+
when Numeric
|
22
|
+
if value.is_a? Bignum
|
23
|
+
value.to_yaml
|
24
|
+
else
|
25
|
+
value
|
26
|
+
end
|
27
|
+
when true, false
|
28
|
+
value
|
29
|
+
when Array
|
30
|
+
if value.length == 0
|
31
|
+
value_type = Fixnum
|
32
|
+
else
|
33
|
+
value_type = value.first.class
|
34
|
+
value_type = TrueClass if value_type == FalseClass
|
35
|
+
value.each do |v|
|
36
|
+
if value_type != v.class or (value == true or value == false and value_type == TrueClass)
|
37
|
+
value_type = nil
|
38
|
+
break
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
case value_type
|
43
|
+
when Fixnum
|
44
|
+
value.to_java :long
|
45
|
+
when Float
|
46
|
+
value.to_java :double
|
47
|
+
when TrueClass
|
48
|
+
value.to_java :boolean
|
49
|
+
when String
|
50
|
+
value.to_java :string
|
51
|
+
else
|
52
|
+
value.to_yaml
|
53
|
+
end
|
54
|
+
else
|
55
|
+
value.to_yaml
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
if 'x'.to_yaml[0, 5] == '%YAML'
|
60
|
+
def self.decode_property(value)
|
61
|
+
if value.is_a? String and value[0, 5] == '%YAML'
|
62
|
+
YAML.load(value)
|
63
|
+
elsif value.is_a? ArrayJavaProxy
|
64
|
+
value.to_a
|
65
|
+
else
|
66
|
+
value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else
|
70
|
+
def self.decode_property(value)
|
71
|
+
if value.is_a? String and value[0, 3] == '---'
|
72
|
+
YAML.load(value)
|
73
|
+
elsif value.is_a? ArrayJavaProxy
|
74
|
+
value.to_a
|
75
|
+
else
|
76
|
+
value
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/pacer/graph.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
module Pacer
|
2
|
-
import com.tinkerpop.blueprints.
|
3
|
-
import com.tinkerpop.blueprints.
|
4
|
-
import com.tinkerpop.blueprints.
|
5
|
-
import com.tinkerpop.blueprints.
|
2
|
+
import com.tinkerpop.blueprints.Graph
|
3
|
+
import com.tinkerpop.blueprints.Element
|
4
|
+
import com.tinkerpop.blueprints.Vertex
|
5
|
+
import com.tinkerpop.blueprints.Edge
|
6
6
|
end
|
7
7
|
|
8
|
-
require 'pacer/graph/graph_mixin'
|
9
|
-
require 'pacer/graph/element_mixin'
|
10
|
-
require 'pacer/graph/vertex_mixin'
|
11
|
-
require 'pacer/graph/edge_mixin'
|
12
|
-
require 'pacer/graph/index_mixin'
|
13
|
-
require 'pacer/graph/graph_indices_mixin'
|
14
8
|
require 'pacer/graph/graph_transactions_mixin'
|
9
|
+
require 'pacer/graph/pacer_graph.rb'
|
10
|
+
require 'pacer/graph/simple_encoder.rb'
|
11
|
+
require 'pacer/graph/yaml_encoder.rb'
|
12
|
+
require 'pacer/graph/graph_ml'
|
@@ -6,8 +6,10 @@ module Pacer::Pipes
|
|
6
6
|
# pass it on to a pipe like FutureFilterPipe that only
|
7
7
|
# knows how to act on a single pipe.
|
8
8
|
class BlackboxPipeline
|
9
|
-
include com.tinkerpop.pipes.Pipe
|
10
|
-
|
9
|
+
include com.tinkerpop.pipes.Pipe
|
10
|
+
|
11
|
+
attr_reader :pathEnabled
|
12
|
+
|
11
13
|
def initialize(start_pipe, end_pipe)
|
12
14
|
@start_pipe = start_pipe
|
13
15
|
@end_pipe = end_pipe
|
@@ -33,8 +35,13 @@ module Pacer::Pipes
|
|
33
35
|
@end_pipe.reset
|
34
36
|
end
|
35
37
|
|
36
|
-
def
|
37
|
-
@
|
38
|
+
def enablePath(b)
|
39
|
+
@pathEnabled = b
|
40
|
+
@end_pipe.enablePath b
|
41
|
+
end
|
42
|
+
|
43
|
+
def getCurrentPath
|
44
|
+
@end_pipe.getCurrentPath
|
38
45
|
end
|
39
46
|
|
40
47
|
def iterator
|
@@ -2,37 +2,20 @@ module Pacer::Pipes
|
|
2
2
|
class BlockFilterPipe < AbstractPipe
|
3
3
|
field_reader :starts
|
4
4
|
|
5
|
+
attr_reader :block
|
6
|
+
|
5
7
|
def initialize(back, block, invert = false)
|
6
8
|
super()
|
7
|
-
@
|
8
|
-
@block = block
|
9
|
-
@graph = back.graph
|
10
|
-
@invert = invert
|
11
|
-
|
12
|
-
@exts = @back.extensions + [Pacer::Extensions::BlockFilterElement]
|
13
|
-
@is_element = @graph.element_type?(back.element_type) if @graph
|
9
|
+
@block = Pacer::Wrappers::WrappingPipeFunction.new back, block
|
14
10
|
end
|
15
11
|
|
16
12
|
def processNextStart()
|
17
13
|
while raw_element = starts.next
|
18
|
-
|
19
|
-
extended_element = raw_element.add_extensions(@exts)
|
20
|
-
extended_element.back = @back
|
21
|
-
extended_element.graph = @back.graph
|
22
|
-
ok = @block.call extended_element
|
23
|
-
else
|
24
|
-
ok = @block.call raw_element
|
25
|
-
end
|
14
|
+
ok = block.call raw_element
|
26
15
|
ok = !ok if @invert
|
27
16
|
return raw_element if ok
|
28
17
|
end
|
29
|
-
raise
|
30
|
-
rescue NativeException => e
|
31
|
-
if e.cause.getClass == Pacer::NoSuchElementException.getClass
|
32
|
-
raise e.cause
|
33
|
-
else
|
34
|
-
raise e
|
35
|
-
end
|
18
|
+
raise EmptyPipe.instance
|
36
19
|
end
|
37
20
|
end
|
38
21
|
end
|
@@ -15,12 +15,6 @@ module Pacer::Pipes
|
|
15
15
|
def processNextStart
|
16
16
|
next_pair
|
17
17
|
a.send method, b rescue nil if a.respond_to? method
|
18
|
-
rescue NativeException => e
|
19
|
-
if e.cause.getClass == Pacer::NoSuchElementException.getClass
|
20
|
-
raise e.cause
|
21
|
-
else
|
22
|
-
raise e
|
23
|
-
end
|
24
18
|
end
|
25
19
|
|
26
20
|
protected
|
@@ -31,8 +25,12 @@ module Pacer::Pipes
|
|
31
25
|
if branch_b
|
32
26
|
begin
|
33
27
|
self.b = branch_b.next
|
28
|
+
rescue Pacer::EmptyPipe, java.util.NoSuchElementException
|
29
|
+
next_a
|
30
|
+
branch_b.setStarts SingleIterator.new(element)
|
31
|
+
retry
|
34
32
|
rescue NativeException => e
|
35
|
-
if
|
33
|
+
if @first
|
36
34
|
next_a
|
37
35
|
branch_b.setStarts SingleIterator.new(element)
|
38
36
|
retry
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Pacer::Pipes
|
2
|
+
class EdgesPipe < AbstractPipe
|
3
|
+
attr_reader :starts
|
4
|
+
|
5
|
+
def setStarts(starts)
|
6
|
+
@starts = starts.first
|
7
|
+
self.iter = @starts.getEdges.iterator
|
8
|
+
end
|
9
|
+
|
10
|
+
def processNextStart
|
11
|
+
iter.next
|
12
|
+
end
|
13
|
+
|
14
|
+
def reset
|
15
|
+
self.iter = @starts.getEdges.iterator
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_accessor :iter
|
21
|
+
end
|
22
|
+
end
|
@@ -5,8 +5,8 @@ module Pacer::Pipes
|
|
5
5
|
case enumerable
|
6
6
|
when Enumerator
|
7
7
|
starts = enumerable
|
8
|
-
when Pacer::
|
9
|
-
starts = [enumerable].to_enum
|
8
|
+
when Pacer::Wrappers::ElementWrapper
|
9
|
+
starts = [enumerable.element].to_enum
|
10
10
|
when Enumerable
|
11
11
|
starts = enumerable.to_enum
|
12
12
|
else
|
@@ -18,13 +18,7 @@ module Pacer::Pipes
|
|
18
18
|
def processNextStart()
|
19
19
|
@starts.next
|
20
20
|
rescue StopIteration
|
21
|
-
raise
|
22
|
-
rescue NativeException => e
|
23
|
-
if e.cause.getClass == Pacer::NoSuchElementException.getClass
|
24
|
-
raise e.cause
|
25
|
-
else
|
26
|
-
raise e
|
27
|
-
end
|
21
|
+
raise EmptyPipe.instance
|
28
22
|
end
|
29
23
|
end
|
30
24
|
end
|