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.
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