pacer 0.9.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/.autotest +8 -0
  2. data/.document +5 -0
  3. data/.gitignore +26 -0
  4. data/.rspec +1 -0
  5. data/.rvmrc +0 -0
  6. data/CONTRIBUTORS +5 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +24 -0
  9. data/README.md +187 -0
  10. data/Rakefile +49 -0
  11. data/autotest/discover.rb +1 -0
  12. data/bin/autospec +16 -0
  13. data/bin/autotest +16 -0
  14. data/bin/rake +16 -0
  15. data/bin/rcov +16 -0
  16. data/bin/rspec +16 -0
  17. data/bin/yard +16 -0
  18. data/bin/yardoc +16 -0
  19. data/lib/pacer/blueprints/extensions.rb +77 -0
  20. data/lib/pacer/blueprints/multi_graph.rb +121 -0
  21. data/lib/pacer/blueprints/ruby_graph.rb +199 -0
  22. data/lib/pacer/blueprints/tg.rb +100 -0
  23. data/lib/pacer/blueprints.rb +4 -0
  24. data/lib/pacer/core/graph/edges_route.rb +92 -0
  25. data/lib/pacer/core/graph/element_route.rb +171 -0
  26. data/lib/pacer/core/graph/graph_index_route.rb +48 -0
  27. data/lib/pacer/core/graph/graph_route.rb +55 -0
  28. data/lib/pacer/core/graph/mixed_route.rb +96 -0
  29. data/lib/pacer/core/graph/vertices_route.rb +220 -0
  30. data/lib/pacer/core/graph.rb +13 -0
  31. data/lib/pacer/core/route.rb +502 -0
  32. data/lib/pacer/core/side_effect.rb +11 -0
  33. data/lib/pacer/core.rb +8 -0
  34. data/lib/pacer/exceptions.rb +11 -0
  35. data/lib/pacer/extensions/block_filter_element.rb +22 -0
  36. data/lib/pacer/extensions.rb +6 -0
  37. data/lib/pacer/filter/block_filter.rb +31 -0
  38. data/lib/pacer/filter/collection_filter.rb +109 -0
  39. data/lib/pacer/filter/empty_filter.rb +70 -0
  40. data/lib/pacer/filter/future_filter.rb +68 -0
  41. data/lib/pacer/filter/index_filter.rb +30 -0
  42. data/lib/pacer/filter/loop_filter.rb +95 -0
  43. data/lib/pacer/filter/object_filter.rb +55 -0
  44. data/lib/pacer/filter/property_filter/edge_filters.rb +93 -0
  45. data/lib/pacer/filter/property_filter/filters.rb +269 -0
  46. data/lib/pacer/filter/property_filter.rb +111 -0
  47. data/lib/pacer/filter/random_filter.rb +13 -0
  48. data/lib/pacer/filter/range_filter.rb +104 -0
  49. data/lib/pacer/filter/uniq_filter.rb +12 -0
  50. data/lib/pacer/filter/where_filter/node_visitor.rb +280 -0
  51. data/lib/pacer/filter/where_filter.rb +47 -0
  52. data/lib/pacer/filter.rb +17 -0
  53. data/lib/pacer/function_resolver.rb +43 -0
  54. data/lib/pacer/graph/edge_mixin.rb +127 -0
  55. data/lib/pacer/graph/element_mixin.rb +202 -0
  56. data/lib/pacer/graph/graph_indices_mixin.rb +93 -0
  57. data/lib/pacer/graph/graph_mixin.rb +361 -0
  58. data/lib/pacer/graph/graph_transactions_mixin.rb +207 -0
  59. data/lib/pacer/graph/index_mixin.rb +30 -0
  60. data/lib/pacer/graph/vertex_mixin.rb +119 -0
  61. data/lib/pacer/graph.rb +14 -0
  62. data/lib/pacer/pipe/blackbox_pipeline.rb +48 -0
  63. data/lib/pacer/pipe/block_filter_pipe.rb +38 -0
  64. data/lib/pacer/pipe/collection_filter_pipe.rb +10 -0
  65. data/lib/pacer/pipe/cross_product_transform_pipe.rb +48 -0
  66. data/lib/pacer/pipe/enumerable_pipe.rb +30 -0
  67. data/lib/pacer/pipe/expandable_pipe.rb +63 -0
  68. data/lib/pacer/pipe/id_collection_filter_pipe.rb +33 -0
  69. data/lib/pacer/pipe/is_empty_pipe.rb +30 -0
  70. data/lib/pacer/pipe/is_unique_pipe.rb +61 -0
  71. data/lib/pacer/pipe/label_collection_filter_pipe.rb +21 -0
  72. data/lib/pacer/pipe/label_prefix_pipe.rb +21 -0
  73. data/lib/pacer/pipe/loop_pipe.rb +86 -0
  74. data/lib/pacer/pipe/map_pipe.rb +36 -0
  75. data/lib/pacer/pipe/never_pipe.rb +9 -0
  76. data/lib/pacer/pipe/process_pipe.rb +37 -0
  77. data/lib/pacer/pipe/property_comparison_pipe.rb +40 -0
  78. data/lib/pacer/pipe/ruby_pipe.rb +25 -0
  79. data/lib/pacer/pipe/simple_visitor_pipe.rb +43 -0
  80. data/lib/pacer/pipe/stream_sort_pipe.rb +84 -0
  81. data/lib/pacer/pipe/stream_uniq_pipe.rb +33 -0
  82. data/lib/pacer/pipe/type_filter_pipe.rb +22 -0
  83. data/lib/pacer/pipe/unary_transform_pipe.rb +59 -0
  84. data/lib/pacer/pipe/variable_store_iterator_wrapper.rb +26 -0
  85. data/lib/pacer/pipe/visitor_pipe.rb +67 -0
  86. data/lib/pacer/pipes.rb +61 -0
  87. data/lib/pacer/route/mixin/bulk_operations.rb +52 -0
  88. data/lib/pacer/route/mixin/route_operations.rb +107 -0
  89. data/lib/pacer/route/mixin/variable_route_module.rb +26 -0
  90. data/lib/pacer/route/mixins.rb +3 -0
  91. data/lib/pacer/route.rb +228 -0
  92. data/lib/pacer/routes.rb +6 -0
  93. data/lib/pacer/side_effect/aggregate.rb +31 -0
  94. data/lib/pacer/side_effect/counted.rb +30 -0
  95. data/lib/pacer/side_effect/group_count.rb +44 -0
  96. data/lib/pacer/side_effect/is_unique.rb +32 -0
  97. data/lib/pacer/side_effect/section.rb +25 -0
  98. data/lib/pacer/side_effect/visitor.rb +37 -0
  99. data/lib/pacer/side_effect.rb +11 -0
  100. data/lib/pacer/support/array_list.rb +28 -0
  101. data/lib/pacer/support/enumerable.rb +100 -0
  102. data/lib/pacer/support/hash.rb +9 -0
  103. data/lib/pacer/support/iterator_mixins.rb +110 -0
  104. data/lib/pacer/support/native_exception.rb +22 -0
  105. data/lib/pacer/support/proc.rb +16 -0
  106. data/lib/pacer/support.rb +10 -0
  107. data/lib/pacer/transform/cap.rb +50 -0
  108. data/lib/pacer/transform/gather.rb +9 -0
  109. data/lib/pacer/transform/has_count_cap.rb +41 -0
  110. data/lib/pacer/transform/join.rb +181 -0
  111. data/lib/pacer/transform/map.rb +23 -0
  112. data/lib/pacer/transform/path.rb +50 -0
  113. data/lib/pacer/transform/process.rb +23 -0
  114. data/lib/pacer/transform/scatter.rb +23 -0
  115. data/lib/pacer/transform/sort_section.rb +103 -0
  116. data/lib/pacer/transform/stream_sort.rb +21 -0
  117. data/lib/pacer/transform/stream_uniq.rb +21 -0
  118. data/lib/pacer/transform.rb +16 -0
  119. data/lib/pacer/utils/graph_analysis.rb +112 -0
  120. data/lib/pacer/utils/trie.rb +93 -0
  121. data/lib/pacer/utils/tsort.rb +65 -0
  122. data/lib/pacer/utils/y_files.rb +127 -0
  123. data/lib/pacer/utils.rb +10 -0
  124. data/lib/pacer/version.rb +13 -0
  125. data/lib/pacer/wrappers/edge_wrapper.rb +51 -0
  126. data/lib/pacer/wrappers/element_wrapper.rb +78 -0
  127. data/lib/pacer/wrappers/new_element.rb +106 -0
  128. data/lib/pacer/wrappers/vertex_wrapper.rb +51 -0
  129. data/lib/pacer/wrappers.rb +19 -0
  130. data/lib/pacer-0.9.1.1-standalone.jar +0 -0
  131. data/lib/pacer.rb +290 -0
  132. data/pacer.gemspec +30 -0
  133. data/pom/standalone.xml +22 -0
  134. data/pom.xml +124 -0
  135. data/samples/grateful-dead.xml +26380 -0
  136. data/samples/grateful_dead.rb +63 -0
  137. data/samples/profile.rb +15 -0
  138. data/spec/data/grateful-dead.xml +26380 -0
  139. data/spec/data/pacer.graphml +319 -0
  140. data/spec/pacer/blueprints/dex_spec.rb +172 -0
  141. data/spec/pacer/blueprints/neo4j_spec.rb +177 -0
  142. data/spec/pacer/blueprints/tg_spec.rb +128 -0
  143. data/spec/pacer/core/graph/edges_route_spec.rb +52 -0
  144. data/spec/pacer/core/graph/element_route_spec.rb +46 -0
  145. data/spec/pacer/core/graph/graph_route_spec.rb +94 -0
  146. data/spec/pacer/core/graph/vertices_route_spec.rb +169 -0
  147. data/spec/pacer/core/route_spec.rb +197 -0
  148. data/spec/pacer/filter/collection_filter_spec.rb +19 -0
  149. data/spec/pacer/filter/empty_filter_spec.rb +29 -0
  150. data/spec/pacer/filter/future_filter_spec.rb +97 -0
  151. data/spec/pacer/filter/loop_filter_spec.rb +31 -0
  152. data/spec/pacer/filter/property_filter_spec.rb +111 -0
  153. data/spec/pacer/filter/random_filter_spec.rb +17 -0
  154. data/spec/pacer/filter/uniq_filter_spec.rb +18 -0
  155. data/spec/pacer/filter/where_filter_spec.rb +93 -0
  156. data/spec/pacer/graph/edge_mixin_spec.rb +116 -0
  157. data/spec/pacer/graph/element_mixin_spec.rb +297 -0
  158. data/spec/pacer/graph/graph_mixin_spec.rb +538 -0
  159. data/spec/pacer/graph/index_mixin_spec.rb +0 -0
  160. data/spec/pacer/graph/vertex_mixin_spec.rb +192 -0
  161. data/spec/pacer/pipe/block_filter_pipe_spec.rb +0 -0
  162. data/spec/pacer/pipe/labels_filter_pipe_spec.rb +0 -0
  163. data/spec/pacer/pipe/ruby_pipe_spec.rb +0 -0
  164. data/spec/pacer/pipe/type_filter_pipe_spec.rb +0 -0
  165. data/spec/pacer/route/mixin/base_spec.rb +419 -0
  166. data/spec/pacer/route/mixin/bulk_operations_spec.rb +30 -0
  167. data/spec/pacer/route/mixin/route_operations_spec.rb +127 -0
  168. data/spec/pacer/support/array_list_spec.rb +0 -0
  169. data/spec/pacer/support/enumerable_spec.rb +115 -0
  170. data/spec/pacer/transform/join_spec.rb +138 -0
  171. data/spec/pacer/transform/path_spec.rb +54 -0
  172. data/spec/pacer/utils/tsort_spec.rb +89 -0
  173. data/spec/pacer/wrapper/edge_wrapper_spec.rb +33 -0
  174. data/spec/pacer/wrapper/element_wrapper_spec.rb +169 -0
  175. data/spec/pacer/wrapper/vertex_wrapper_spec.rb +33 -0
  176. data/spec/pacer_spec.rb +0 -0
  177. data/spec/spec_helper.rb +91 -0
  178. data/spec/support/contexts.rb +14 -0
  179. data/spec/support/graph_runner.rb +142 -0
  180. data/spec/support/matchers.rb +19 -0
  181. data/spec/support/use_transactions.rb +31 -0
  182. data/spec/tackle/simple_mixin.rb +21 -0
  183. data/spec/tackle/tinkerpop_graph_mixins.rb +60 -0
  184. metadata +364 -0
@@ -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
@@ -0,0 +1,6 @@
1
+ module Pacer
2
+ module Routes
3
+ # Defines the Routes namespace
4
+ end
5
+ end
6
+ require 'pacer/route/mixins'
@@ -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,9 @@
1
+ class Hash
2
+ def to_hash_map
3
+ hm = java.util.HashMap.new
4
+ each do |key, value|
5
+ hm.put key, value
6
+ end
7
+ hm
8
+ end
9
+ 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