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
data/lib/pacer/route.rb
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
[Pacer::Core::Route, Pacer::ElementMixin, Pacer::Wrappers::EdgeWrapper, Pacer::Wrappers::VertexWrapper].each do |klass|
|
|
2
|
+
klass.class_eval %{
|
|
3
|
+
def chain_route(args_hash)
|
|
4
|
+
Pacer::Route.new({ :back => self }.merge(args_hash))
|
|
5
|
+
end
|
|
6
|
+
}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module Pacer
|
|
10
|
+
# The base class for almost everything in Pacer. Every route is an
|
|
11
|
+
# instance of this class with a variety of modules mixed into the
|
|
12
|
+
# instance at runtime.
|
|
13
|
+
#
|
|
14
|
+
# The class definition only contains methods directly related to the
|
|
15
|
+
# construction of new Routes. For methods more likely to be used, see
|
|
16
|
+
# the {Core::Route} module which is always mixed into this class.
|
|
17
|
+
#
|
|
18
|
+
# @see Core::Route
|
|
19
|
+
class Route
|
|
20
|
+
class << self
|
|
21
|
+
# A pipeline is sometimes required if a pipe needs to be passed
|
|
22
|
+
# into a method that will change the starts on the same object
|
|
23
|
+
# that it requests the next result from.
|
|
24
|
+
#
|
|
25
|
+
# @param [Route] route the route to create a pipeline based on
|
|
26
|
+
# @return [Pacer::Pipes::BlackboxPipeline] an instantiated pipeline
|
|
27
|
+
def pipeline(route)
|
|
28
|
+
s, e = route.send(:build_pipeline)
|
|
29
|
+
if s.equal?(e)
|
|
30
|
+
s
|
|
31
|
+
else
|
|
32
|
+
Pacer::Pipes::BlackboxPipeline.new s, e
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
include Pacer::Core::Route
|
|
38
|
+
include Pacer::Routes::RouteOperations
|
|
39
|
+
|
|
40
|
+
# The function mixed into this instance
|
|
41
|
+
attr_reader :function
|
|
42
|
+
|
|
43
|
+
# The type of object that this route emits.
|
|
44
|
+
attr_reader :element_type
|
|
45
|
+
|
|
46
|
+
# Additional info to include after the class name when generating a
|
|
47
|
+
# name for this route.
|
|
48
|
+
attr_accessor :info
|
|
49
|
+
|
|
50
|
+
# The previous route in the chain
|
|
51
|
+
attr_reader :back
|
|
52
|
+
|
|
53
|
+
# The soure of data for the entire chain. Routes that have a source
|
|
54
|
+
# generally should not have a {#back}
|
|
55
|
+
attr_reader :source
|
|
56
|
+
|
|
57
|
+
# Create a new route. It should be very rare that you would need to
|
|
58
|
+
# directly create a Route object.
|
|
59
|
+
#
|
|
60
|
+
# See {Core::Graph::GraphRoute} and {GraphMixin} for methods
|
|
61
|
+
# to build routes based on a graph.
|
|
62
|
+
#
|
|
63
|
+
# See {ElementMixin}, {VertexMixin} and
|
|
64
|
+
# {EdgeMixin} for methods to build routes based on an
|
|
65
|
+
# individual graph element.
|
|
66
|
+
#
|
|
67
|
+
# @see Core::Graph::GraphRoute
|
|
68
|
+
# @see GraphMixin
|
|
69
|
+
# @see ElementMixin
|
|
70
|
+
# @see VertexMixin
|
|
71
|
+
# @see EdgeMixin
|
|
72
|
+
#
|
|
73
|
+
# See Pacer's {Enumerable#to_route} method to create a route based
|
|
74
|
+
# on an Array, a Set or any other Enumerable type.
|
|
75
|
+
#
|
|
76
|
+
# @param [Hash] args
|
|
77
|
+
# @option args [Graph] :graph the graph this route is based on
|
|
78
|
+
# @option args [Route] :bace the previous route in the chain
|
|
79
|
+
# @option args [element type] :element_type
|
|
80
|
+
# @option args [Module] :modules additional modules to mix in
|
|
81
|
+
# @option args [Symbol, Module] :filter the filter to use as this
|
|
82
|
+
# route's function
|
|
83
|
+
# @option args [Symbol, Module] :side_effect the side effect to use
|
|
84
|
+
# as this route's function (Also triggers the {Core::SideEffect}
|
|
85
|
+
# mixin)
|
|
86
|
+
# @option args [Symbol, Module] :transform the transform module to
|
|
87
|
+
# use as this route's function
|
|
88
|
+
# @option args [[Module]] :extensions extensions for this route
|
|
89
|
+
#
|
|
90
|
+
# All other keys sent to the args method will be converted into
|
|
91
|
+
# setter method calls and called against the instantiated route to
|
|
92
|
+
# allow modules to define their own setup however they need.
|
|
93
|
+
#
|
|
94
|
+
# @example If a route is constructed with the a custom key:
|
|
95
|
+
# route = Route.new(:filter => :block, :block => proc { |element| element.element_id.even? })
|
|
96
|
+
#
|
|
97
|
+
# # is theoretically the same as
|
|
98
|
+
#
|
|
99
|
+
# route = Route.new
|
|
100
|
+
# route.extend Pacer::Filter::BlockFilter
|
|
101
|
+
# route.block = proc { |element| element.element_id.even? }
|
|
102
|
+
# route
|
|
103
|
+
#
|
|
104
|
+
# When the route object is fully initialized, the
|
|
105
|
+
# {#after_initialize} method is called to allow mixins to do any
|
|
106
|
+
# additional setup.
|
|
107
|
+
def initialize(args = {})
|
|
108
|
+
@@graph = @back = @source = nil
|
|
109
|
+
@wrapper = nil
|
|
110
|
+
@extensions = Set[]
|
|
111
|
+
self.graph = args[:graph]
|
|
112
|
+
self.back = args[:back]
|
|
113
|
+
include_function args
|
|
114
|
+
set_element_type args
|
|
115
|
+
include_other_modules args
|
|
116
|
+
keys = args.keys - [:element_type, :modules, :graph, :back, :filter, :side_effect, :transform]
|
|
117
|
+
keys.each do |key|
|
|
118
|
+
send("#{key}=", args[key])
|
|
119
|
+
end
|
|
120
|
+
include_extensions args
|
|
121
|
+
after_initialize
|
|
122
|
+
rescue Exception => e
|
|
123
|
+
puts "Exception creating Route with #{ args.inspect }" if Pacer.verbose?
|
|
124
|
+
raise
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
protected
|
|
128
|
+
|
|
129
|
+
# Set the element type of this route and include the apropriate
|
|
130
|
+
# mixin to support the element type.
|
|
131
|
+
#
|
|
132
|
+
# @param [:vertex, :edge, :mixed, element type, Object] et the
|
|
133
|
+
# element type to use
|
|
134
|
+
def element_type=(et)
|
|
135
|
+
if graph
|
|
136
|
+
@element_type = graph.element_type(et)
|
|
137
|
+
if @element_type == graph.element_type(:vertex)
|
|
138
|
+
extend Pacer::Core::Graph::VerticesRoute
|
|
139
|
+
elsif @element_type == graph.element_type(:edge)
|
|
140
|
+
extend Pacer::Core::Graph::EdgesRoute
|
|
141
|
+
elsif @element_type == graph.element_type(:mixed)
|
|
142
|
+
extend Pacer::Core::Graph::MixedRoute
|
|
143
|
+
end
|
|
144
|
+
elsif et == :object or et == Object
|
|
145
|
+
@element_type = Object
|
|
146
|
+
else
|
|
147
|
+
raise "Element type #{ et.inspect } specified, but no graph specified."
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# This callback may be overridden. Be sure to call super() though.
|
|
152
|
+
# @return ignored
|
|
153
|
+
def after_initialize
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Find the module for the function to include based on the :filter,
|
|
157
|
+
# :side_effect or :transform argument given to {#initialize} and
|
|
158
|
+
# extend this instance with it.
|
|
159
|
+
def include_function(args)
|
|
160
|
+
@function, extension = FunctionResolver.function(args)
|
|
161
|
+
self.extend extension if extension
|
|
162
|
+
self.extend function if function
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# @return [Route, nil] the previous route in the chain
|
|
166
|
+
def back_object(args)
|
|
167
|
+
back || args[:back]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Get element type from the previous route in the chain.
|
|
171
|
+
# @return [element type, nil]
|
|
172
|
+
def back_element_type(args)
|
|
173
|
+
b = back_object(args)
|
|
174
|
+
if b.respond_to? :element_type
|
|
175
|
+
b.element_type
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# If no element type has been specified, try to find one from
|
|
180
|
+
# the previous route in the chain.
|
|
181
|
+
# @raise [StandardError] if no element type can be found
|
|
182
|
+
def set_element_type(args)
|
|
183
|
+
if args[:element_type]
|
|
184
|
+
self.element_type = args[:element_type]
|
|
185
|
+
else
|
|
186
|
+
if bet = back_element_type(args)
|
|
187
|
+
self.element_type = bet
|
|
188
|
+
else
|
|
189
|
+
raise "No element_type specified or inferred"
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# extends this class with any modules passed to {#initialize} in the
|
|
195
|
+
# :modules key.
|
|
196
|
+
def include_other_modules(args)
|
|
197
|
+
if mods = args[:modules]
|
|
198
|
+
@modules = [*mods]
|
|
199
|
+
@modules.each do |mod|
|
|
200
|
+
extend mod
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Copy extensions from the previous route in the chain if the
|
|
206
|
+
# previous route's element type is the same as the current route's
|
|
207
|
+
# element type and no extensions were explicitly set on this route.
|
|
208
|
+
def include_extensions(args)
|
|
209
|
+
if back_element_type(args) == self.element_type and not args.key? :extensions and not args.key? :wrapper
|
|
210
|
+
back_obj = back_object(args)
|
|
211
|
+
if not wrapper and extensions.none?
|
|
212
|
+
self.wrapper = back_obj.wrapper if back_obj.respond_to? :wrapper
|
|
213
|
+
self.extensions = back_obj.extensions if back_obj.respond_to? :extensions
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Creates a terse, human-friendly name for the class based on its
|
|
219
|
+
# element type, function and info.
|
|
220
|
+
# @return [String]
|
|
221
|
+
def inspect_class_name
|
|
222
|
+
s = "#{element_type.to_s.scan(/Elem|Obj|V|E/).last}"
|
|
223
|
+
s = "#{s}-#{function.name.split('::').last.sub(/Filter|Route$/, '')}" if function
|
|
224
|
+
s = "#{s} #{ @info }" if @info
|
|
225
|
+
s
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
data/lib/pacer/routes.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Pacer
|
|
2
|
+
module Routes::RouteOperations
|
|
3
|
+
def aggregate(into = nil)
|
|
4
|
+
chain_route :side_effect => :aggregate, :into => into
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module SideEffect
|
|
9
|
+
module Aggregate
|
|
10
|
+
import com.tinkerpop.pipes.sideeffect.AggregatePipe
|
|
11
|
+
import java.util.HashSet
|
|
12
|
+
|
|
13
|
+
attr_accessor :into
|
|
14
|
+
|
|
15
|
+
protected
|
|
16
|
+
|
|
17
|
+
def attach_pipe(end_pipe)
|
|
18
|
+
if into.is_a? Symbol
|
|
19
|
+
hs = vars[into] = HashSet.new
|
|
20
|
+
pipe = AggregatePipe.new hs
|
|
21
|
+
elsif into
|
|
22
|
+
pipe = AggregatePipe.new into
|
|
23
|
+
else
|
|
24
|
+
pipe = AggregatePipe.new HashSet.new
|
|
25
|
+
end
|
|
26
|
+
pipe.setStarts end_pipe if end_pipe
|
|
27
|
+
pipe
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Pacer
|
|
2
|
+
module Routes
|
|
3
|
+
module RouteOperations
|
|
4
|
+
def counted
|
|
5
|
+
chain_route :side_effect => :counted
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def count
|
|
9
|
+
counted.count
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
module SideEffect
|
|
16
|
+
module Counted
|
|
17
|
+
def count
|
|
18
|
+
cap.first
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
protected
|
|
22
|
+
|
|
23
|
+
def attach_pipe(end_pipe)
|
|
24
|
+
@pipe = com.tinkerpop.pipes.sideeffect.CountPipe.new
|
|
25
|
+
@pipe.setStarts(end_pipe) if end_pipe
|
|
26
|
+
@pipe
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Pacer
|
|
2
|
+
module Routes::RouteOperations
|
|
3
|
+
def fast_group_count(hash_map = nil)
|
|
4
|
+
chain_route :side_effect => :group_count, :hash_map => hash_map
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module SideEffect
|
|
9
|
+
module GroupCount
|
|
10
|
+
def hash_map=(hash_map)
|
|
11
|
+
@hash_map = hash_map
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def at_least(n)
|
|
15
|
+
@min = n
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_h
|
|
20
|
+
c = 0
|
|
21
|
+
each { c = c + 1 }
|
|
22
|
+
puts c
|
|
23
|
+
h = {}
|
|
24
|
+
min = @min || 0
|
|
25
|
+
side_effect.each do |k,v|
|
|
26
|
+
h[k] = v if v >= min
|
|
27
|
+
end
|
|
28
|
+
h
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
def attach_pipe(end_pipe)
|
|
34
|
+
if @hash_map
|
|
35
|
+
@pipe = com.tinkerpop.pipes.sideeffect.GroupCountPipe.new @hash_map
|
|
36
|
+
else
|
|
37
|
+
@pipe = com.tinkerpop.pipes.sideeffect.GroupCountPipe.new
|
|
38
|
+
end
|
|
39
|
+
@pipe.set_starts(end_pipe) if end_pipe
|
|
40
|
+
@pipe
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Pacer
|
|
2
|
+
module Routes
|
|
3
|
+
module RouteOperations
|
|
4
|
+
def is_unique
|
|
5
|
+
chain_route :side_effect => :is_unique
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def unique?
|
|
9
|
+
is_unique.unique?
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
module SideEffect
|
|
16
|
+
module IsUnique
|
|
17
|
+
def unique?
|
|
18
|
+
pipe do |pipe|
|
|
19
|
+
pipe.next while pipe.unique?
|
|
20
|
+
end.unique?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
|
|
25
|
+
def attach_pipe(end_pipe)
|
|
26
|
+
@pipe = Pacer::Pipes::IsUniquePipe.new
|
|
27
|
+
@pipe.setStarts(end_pipe) if end_pipe
|
|
28
|
+
@pipe
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Pacer
|
|
2
|
+
module Routes
|
|
3
|
+
module RouteOperations
|
|
4
|
+
def section(section_name = nil)
|
|
5
|
+
chain_route side_effect: :section, section_name: section_name
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module SideEffect
|
|
11
|
+
module Section
|
|
12
|
+
attr_accessor :section_name
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
attr_reader :section_visitor
|
|
17
|
+
|
|
18
|
+
def attach_pipe(end_pipe)
|
|
19
|
+
@section_visitor = pipe = Pacer::Pipes::SimpleVisitorPipe.new
|
|
20
|
+
pipe.setStarts end_pipe if end_pipe
|
|
21
|
+
pipe
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Pacer
|
|
2
|
+
module Routes
|
|
3
|
+
module RouteOperations
|
|
4
|
+
def visitor(visitor)
|
|
5
|
+
chain_route side_effect: :visitor, visitor: visitor
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module SideEffect
|
|
11
|
+
module Visitor
|
|
12
|
+
attr_reader :visitor
|
|
13
|
+
|
|
14
|
+
def visitor=(v)
|
|
15
|
+
@visitor = v
|
|
16
|
+
@visitor = @visitor.on_route(self) if @visitor.respond_to? :on_route
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def element_type
|
|
20
|
+
if @visitor.respond_to? :element_type
|
|
21
|
+
@visitor.element_type
|
|
22
|
+
else
|
|
23
|
+
super
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
protected
|
|
28
|
+
|
|
29
|
+
def attach_pipe(end_pipe)
|
|
30
|
+
pipe = @visitor.attach_pipe(end_pipe) if @visitor.respond_to? :attach_pipe
|
|
31
|
+
pipe ||= Pacer::Pipes::VisitorPipe.new(visitor)
|
|
32
|
+
pipe.setStarts end_pipe if end_pipe
|
|
33
|
+
pipe
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Pacer
|
|
2
|
+
module SideEffect
|
|
3
|
+
end
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
require 'pacer/side_effect/aggregate'
|
|
7
|
+
require 'pacer/side_effect/group_count'
|
|
8
|
+
require 'pacer/side_effect/is_unique'
|
|
9
|
+
require 'pacer/side_effect/counted'
|
|
10
|
+
require 'pacer/side_effect/section'
|
|
11
|
+
require 'pacer/side_effect/visitor'
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
java.util.ArrayList
|
|
2
|
+
class Java::JavaUtil::ArrayList
|
|
3
|
+
def inspect
|
|
4
|
+
to_a.inspect
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
java.util.LinkedList
|
|
9
|
+
class Java::JavaUtil::LinkedList
|
|
10
|
+
def inspect
|
|
11
|
+
to_a.inspect
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
require 'set'
|
|
16
|
+
java.util.HashSet
|
|
17
|
+
class Java::JavaUtil::HashSet
|
|
18
|
+
def inspect
|
|
19
|
+
to_set.inspect.sub(/Set/, 'HashSet')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
java.util.HashMap
|
|
24
|
+
class Java::JavaUtil::HashMap
|
|
25
|
+
def to_hash_map
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Extend the built-in Enumerable module:
|
|
2
|
+
module Enumerable
|
|
3
|
+
|
|
4
|
+
def one?
|
|
5
|
+
counter = 0
|
|
6
|
+
each do
|
|
7
|
+
return false if counter == 1
|
|
8
|
+
counter += 1
|
|
9
|
+
end
|
|
10
|
+
counter == 1
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def many?
|
|
14
|
+
counter = 0
|
|
15
|
+
any? { if counter == 1; true; else; counter += 1; false; end }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Transform the enumerable into a java HashSet.
|
|
19
|
+
def to_hashset(method = nil, *args)
|
|
20
|
+
return self if self.is_a? java.util.HashSet and not method
|
|
21
|
+
hs = java.util.HashSet.new
|
|
22
|
+
iter = self.each rescue nil
|
|
23
|
+
if not iter and respond_to? :iterator
|
|
24
|
+
iter = self.iterator
|
|
25
|
+
end
|
|
26
|
+
e = iter.next
|
|
27
|
+
if method
|
|
28
|
+
while true
|
|
29
|
+
hs.add e.send(method, *args)
|
|
30
|
+
e = iter.next
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
while true
|
|
34
|
+
hs.add e
|
|
35
|
+
e = iter.next
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
rescue StopIteration
|
|
39
|
+
hs
|
|
40
|
+
rescue NativeException => e
|
|
41
|
+
if (e.cause.kind_of?(java.util.NoSuchElementException))
|
|
42
|
+
hs
|
|
43
|
+
else
|
|
44
|
+
raise
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# NOTE: if this is a collection of wrapped vertices or edges, Java pipes
|
|
49
|
+
# may crash with something like:
|
|
50
|
+
#
|
|
51
|
+
# NativeException: java.lang.ClassCastException: org.jruby.RubyObject cannot be cast to com.tinkerpop.blueprints.pgm.Element
|
|
52
|
+
#
|
|
53
|
+
# You can work around that by passing the option :unwrap => true or
|
|
54
|
+
# setting the :based_on parameter to a route that has extensions.
|
|
55
|
+
def to_route(opts = {})
|
|
56
|
+
if self.is_a? Pacer::Core::Route
|
|
57
|
+
self
|
|
58
|
+
else
|
|
59
|
+
based_on = opts[:based_on]
|
|
60
|
+
if opts[:unwrap] or based_on and (based_on.wrapper or based_on.extensions.any?) and based_on.is_a? Pacer::Core::Graph::ElementRoute
|
|
61
|
+
source = Pacer::Route.new(:source => self, :element_type => :object).map { |e| e.element }
|
|
62
|
+
else
|
|
63
|
+
source = self
|
|
64
|
+
end
|
|
65
|
+
if based_on
|
|
66
|
+
Pacer::Route.new(:source => source, :element_type => opts.fetch(:element_type, based_on.element_type), :graph => based_on.graph, :wrapper => based_on.wrapper, :extensions => based_on.extensions, :info => based_on.info)
|
|
67
|
+
else
|
|
68
|
+
graph = opts[:graph] if opts[:graph]
|
|
69
|
+
Pacer::Route.new(:source => source, :element_type => opts.fetch(:element_type, :object), :graph => graph, :wrapper => opts[:wrapper], :extensions => opts[:extensions], :info => opts[:info])
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def id_to_element_route(args = {})
|
|
75
|
+
based_on = args[:based_on]
|
|
76
|
+
raise 'Must supply :based_on option' unless based_on
|
|
77
|
+
raise 'Graph routes do not contain element ids to look up' if self.is_a? Pacer::Core::Route and graph
|
|
78
|
+
raise 'Based on route must be a graph route' unless based_on.graph
|
|
79
|
+
r = to_route(:info => "#{ count } ids")
|
|
80
|
+
r.chain_route(:graph => based_on.graph,
|
|
81
|
+
:element_type => based_on.element_type,
|
|
82
|
+
:pipe_class => based_on.send(:id_pipe_class),
|
|
83
|
+
:pipe_args => [based_on.graph],
|
|
84
|
+
:route_name => 'lookup',
|
|
85
|
+
:extensions => based_on.extensions,
|
|
86
|
+
:wrapper => based_on.wrapper,
|
|
87
|
+
:info => [args[:name], based_on.info].compact.join(':')).is_not(nil)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def group_count
|
|
91
|
+
result = Hash.new(0)
|
|
92
|
+
if block_given?
|
|
93
|
+
each { |e| result[yield(e)] += 1 }
|
|
94
|
+
else
|
|
95
|
+
each { |e| result[e] += 1 }
|
|
96
|
+
end
|
|
97
|
+
result
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
module Pacer::Core::Route
|
|
2
|
+
# This mixin allows an iterator to be returned from methods that perform a
|
|
3
|
+
# transformation on the elements in their collection. Set the block property
|
|
4
|
+
# to the proc that does the transformation.
|
|
5
|
+
module IteratorBlockMixin
|
|
6
|
+
attr_accessor :graph
|
|
7
|
+
|
|
8
|
+
# Set the block that does the transformation.
|
|
9
|
+
def block=(block)
|
|
10
|
+
@block = block
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def next
|
|
14
|
+
item = super
|
|
15
|
+
item.graph ||= @graph
|
|
16
|
+
@block.call(item)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module IteratorPathMixin
|
|
21
|
+
attr_accessor :graph
|
|
22
|
+
|
|
23
|
+
def next
|
|
24
|
+
super.collect do |e|
|
|
25
|
+
e.graph ||= @graph if e.respond_to? :graph=
|
|
26
|
+
e
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module IteratorExtensionsMixin
|
|
32
|
+
attr_accessor :graph, :extensions
|
|
33
|
+
|
|
34
|
+
def next
|
|
35
|
+
item = super
|
|
36
|
+
# TODO: optimize this (and other) check:
|
|
37
|
+
# - exception?
|
|
38
|
+
# - type check?
|
|
39
|
+
# - method check?
|
|
40
|
+
# - ...?
|
|
41
|
+
if item.respond_to? :graph=
|
|
42
|
+
item = item.add_extensions @extensions
|
|
43
|
+
item.graph ||= @graph
|
|
44
|
+
end
|
|
45
|
+
item
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
module IteratorWrapperMixin
|
|
50
|
+
attr_reader :graph, :extensions, :wrapper
|
|
51
|
+
|
|
52
|
+
def wrapper=(w)
|
|
53
|
+
@base_wrapper = w
|
|
54
|
+
@wrapper = build_wrapper?
|
|
55
|
+
@set_graph = set_graph?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def graph=(g)
|
|
59
|
+
@graph = g
|
|
60
|
+
@wrapper = build_wrapper?
|
|
61
|
+
@set_graph = set_graph?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def extensions=(exts)
|
|
65
|
+
@extensions = exts
|
|
66
|
+
@wrapper = build_wrapper?
|
|
67
|
+
@set_graph = set_graph?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def build_wrapper?
|
|
71
|
+
@base_wrapper = nil unless defined? @base_wrapper
|
|
72
|
+
@extensions = nil unless defined? @extensions
|
|
73
|
+
if @base_wrapper and @extensions
|
|
74
|
+
@wrapper = @base_wrapper.wrapper_for(@base_wrapper.extensions + @extensions.to_a)
|
|
75
|
+
elsif @base_wrapper
|
|
76
|
+
@wrapper = @base_wrapper
|
|
77
|
+
elsif @extensions
|
|
78
|
+
# We don't know what type of wrapper to create
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
if RUBY_VERSION =~ /^1\.8\./
|
|
83
|
+
def set_graph?
|
|
84
|
+
graph and wrapper and wrapper.instance_methods.include?('graph=')
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
def set_graph?
|
|
88
|
+
graph and wrapper and wrapper.instance_methods.include?(:graph=)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def next
|
|
93
|
+
item = wrapper.new(super)
|
|
94
|
+
item.graph ||= graph if @set_graph
|
|
95
|
+
item
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
module IteratorMixin
|
|
100
|
+
attr_accessor :graph
|
|
101
|
+
|
|
102
|
+
def next
|
|
103
|
+
item = super
|
|
104
|
+
if item.respond_to? :graph=
|
|
105
|
+
item.graph ||= @graph
|
|
106
|
+
end
|
|
107
|
+
item
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|