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,43 @@
1
+ module Pacer
2
+ module Pipes
3
+ class SimpleVisitorPipe < Pacer::Pipes::RubyPipe
4
+ attr_reader :visitor, :in_section
5
+
6
+ attr_accessor :use_on_element, :use_after_element, :use_reset
7
+
8
+ def initialize(visitor = nil)
9
+ super()
10
+ self.visitor = visitor if visitor
11
+ @in_section = false
12
+ end
13
+
14
+ def visitor=(visitor)
15
+ @visitor = visitor
16
+ @use_on_element = visitor.respond_to? :on_element
17
+ @use_after_element = visitor.respond_to? :after_element
18
+ @use_reset = visitor.respond_to? :reset
19
+ end
20
+
21
+ def processNextStart
22
+ visitor.after_element if use_after_element and in_section
23
+ current = starts.next
24
+ @in_section = true unless in_section
25
+ visitor.on_element(current) if use_on_element
26
+ return current
27
+ rescue NativeException => e
28
+ if e.cause.getClass == Pacer::NoSuchElementException.getClass
29
+ @in_section = false
30
+ raise e.cause
31
+ else
32
+ raise
33
+ end
34
+ end
35
+
36
+ def reset
37
+ visitor.reset if use_reset
38
+ @in_section = false
39
+ super
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,84 @@
1
+ module Pacer::Pipes
2
+ # has 3 states:
3
+ # - starts in rebalancing mode to build up a working set which stores
4
+ # elements in 4 silos
5
+ # - if the first silo becomes empty, it goes into clearing mode
6
+ # - in clearing mode, it will empty all elements out of the first non-empty silo
7
+ # - it then goes back into rebalancing mode
8
+ #
9
+ # Number of silos is 4 by default, a number I pulled out of my ass without any testing.
10
+ class StreamSortPipe < RubyPipe
11
+ def initialize(queue_length = 100, silo_size = 10)
12
+ super()
13
+ @queue_length = queue_length
14
+ @rebalancing = []
15
+ @rebal_length = 0
16
+ @first_silo = []
17
+ @second_silo = []
18
+ @third_silo = []
19
+ @clearing = []
20
+ @silo_size = silo_size
21
+ end
22
+
23
+ def setSiloSize(n)
24
+ @silo_size = n
25
+ end
26
+
27
+ def processNextStart
28
+ if @clearing.any?
29
+ return @clearing.shift
30
+ end
31
+ while @rebal_length < @queue_length and @starts.hasNext
32
+ @rebalancing << @starts.next
33
+ @rebal_length += 1
34
+ end
35
+ if @rebalancing.any?
36
+ if @starts.hasNext
37
+ @rebalancing.sort!
38
+ @first_silo = @rebalancing.slice(0, @silo_size)
39
+ @second_silo = @rebalancing.slice(@silo_size, @silo_size * 2) || []
40
+ @third_silo = @rebalancing.slice(@silo_size * 2..-1) || []
41
+ @rebalancing = []
42
+ else
43
+ @clearing = @rebalancing.sort
44
+ @rebalancing = []
45
+ return processNextStart
46
+ end
47
+ end
48
+ if @starts.hasNext
49
+ if @first_silo.any?
50
+ element = @starts.next
51
+ begin
52
+ if element < @first_silo.last
53
+ @first_silo << element
54
+ @first_silo.sort!
55
+ elsif @second_silo.none? or element < @second_silo.last
56
+ @second_silo.unshift element
57
+ else
58
+ @third_silo << element
59
+ end
60
+ rescue => e
61
+ @first_silo.unshift element
62
+ end
63
+ return @first_silo.shift
64
+ else
65
+ @clearing = @second_silo
66
+ @clearing.sort!
67
+ @rebalancing = @third_silo
68
+ @rebal_length = @rebalancing.length
69
+ return @rebalancing.shift
70
+ end
71
+ else
72
+ @clearing = @first_silo + @second_silo.sort! + @third_silo.sort!
73
+ return processNextStart if @clearing.any?
74
+ end
75
+ raise Pacer::NoSuchElementException
76
+ rescue NativeException => e
77
+ if e.cause.getClass == NoSuchElementException.getClass
78
+ raise e.cause
79
+ else
80
+ raise e
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,33 @@
1
+ module Pacer::Pipes
2
+ class StreamUniqPipe < RubyPipe
3
+ def initialize(buffer = 1000)
4
+ super()
5
+ @list = java.util.LinkedList.new
6
+ @buffer = buffer
7
+ end
8
+
9
+ protected
10
+
11
+ def processNextStart
12
+ while true
13
+ obj = @starts.next
14
+ duplicate = @list.removeLastOccurrence(obj)
15
+ @list.addLast obj
16
+ if not duplicate
17
+ if @buffer == 0
18
+ @list.removeFirst
19
+ else
20
+ @buffer -= 1
21
+ end
22
+ return obj
23
+ end
24
+ end
25
+ rescue NativeException => e
26
+ if e.cause.getClass == NoSuchElementException.getClass
27
+ raise e.cause
28
+ else
29
+ raise e
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ module Pacer::Pipes
2
+ class TypeFilterPipe < RubyPipe
3
+ def initialize(type)
4
+ super()
5
+ @type = type
6
+ end
7
+
8
+ def processNextStart()
9
+ while @starts.hasNext
10
+ s = @starts.next
11
+ return s if s.is_a? @type
12
+ end
13
+ raise Pacer::NoSuchElementException
14
+ rescue NativeException => e
15
+ if e.cause.getClass == Pacer::NoSuchElementException.getClass
16
+ raise e.cause
17
+ else
18
+ raise e
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,59 @@
1
+ module Pacer::Pipes
2
+ class UnaryTransformPipe < RubyPipe
3
+ import com.tinkerpop.pipes.Pipe
4
+ import com.tinkerpop.pipes.util.SingleIterator
5
+
6
+ attr_reader :branch_a, :method
7
+
8
+ def initialize(method, branch_a)
9
+ super()
10
+ if branch_a.is_a? Pipe
11
+ @branch_a = branch_a
12
+ @a = nil
13
+ else
14
+ @a = branch_a
15
+ end
16
+ @first = true
17
+ @method = method
18
+ @element = nil
19
+ end
20
+
21
+ def processNextStart
22
+ next_a
23
+ a.send method rescue nil if a.respond_to? method
24
+ rescue NativeException => e
25
+ if e.cause.getClass == Pacer::NoSuchElementException.getClass
26
+ raise e.cause
27
+ else
28
+ raise e
29
+ end
30
+ end
31
+
32
+ protected
33
+
34
+ attr_accessor :element, :a
35
+
36
+ def next_element
37
+ @first = false
38
+ self.element = starts.next
39
+ end
40
+
41
+ def next_a
42
+ if branch_a
43
+ begin
44
+ self.a = branch_a.next
45
+ rescue NativeException => e
46
+ if e.cause.getClass == Pacer::NoSuchElementException.getClass or @first
47
+ next_element
48
+ branch_a.setStarts SingleIterator.new(element) if branch_a
49
+ retry
50
+ else
51
+ raise e
52
+ end
53
+ end
54
+ else
55
+ next_element
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,26 @@
1
+ module Pacer::Pipes
2
+ class VariableStoreIteratorWrapper < AbstractPipe
3
+
4
+ field_reader :starts
5
+ attr_accessor :vars
6
+
7
+ def initialize(pipe, vars, variable_name)
8
+ super()
9
+ setStarts pipe if pipe
10
+ @vars = vars
11
+ @variable_name = variable_name
12
+ end
13
+
14
+ protected
15
+
16
+ def processNextStart
17
+ @vars[@variable_name] = starts.next
18
+ rescue NativeException => e
19
+ if e.cause.getClass == Pacer::NoSuchElementException.getClass
20
+ raise e.cause
21
+ else
22
+ raise e
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,67 @@
1
+ module Pacer
2
+ module Pipes
3
+ class VisitorPipe < Pacer::Pipes::RubyPipe
4
+ attr_reader :visitor, :queue, :in_section
5
+
6
+ attr_accessor :use_on_element, :use_replace_element,
7
+ :use_after_element, :use_reset, :use_hasNext, :use_next
8
+
9
+ def initialize(visitor = nil)
10
+ super()
11
+ self.visitor = visitor if visitor
12
+ @queue = []
13
+ @in_section = false
14
+ end
15
+
16
+ def visitor=(visitor)
17
+ if visitor.respond_to? :on_pipe
18
+ @visitor = visitor.on_pipe(self)
19
+ else
20
+ @visitor = visitor
21
+ end
22
+ @use_hasNext = visitor.respond_to? :hasNext
23
+ @use_next = visitor.respond_to? :next
24
+ @use_on_element = visitor.respond_to? :on_element
25
+ @use_replace_element = visitor.respond_to? :replace_element
26
+ @use_after_element = visitor.respond_to? :after_element
27
+ @use_reset = visitor.respond_to? :reset
28
+ end
29
+
30
+ def processNextStart
31
+ while true
32
+ visitor.after_element if use_after_element and in_section
33
+ if use_next and (not use_hasNext or visitor.hasNext)
34
+ return visitor.next
35
+ elsif queue.any?
36
+ return queue.shift
37
+ else
38
+ current = starts.next
39
+ @in_section = true unless in_section
40
+ visitor.on_element(current) if use_on_element
41
+ if use_replace_element
42
+ visitor.replace_element(current) do |e|
43
+ queue << e
44
+ end
45
+ else
46
+ return current
47
+ end
48
+ end
49
+ end
50
+ rescue NativeException => e
51
+ if e.cause.getClass == Pacer::NoSuchElementException.getClass
52
+ @in_section = false
53
+ raise e.cause
54
+ else
55
+ raise
56
+ end
57
+ end
58
+
59
+ def reset
60
+ visitor.reset if use_reset
61
+ @in_section = false
62
+ @queue = []
63
+ super
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,61 @@
1
+ module Pacer
2
+ # Import the Pipes and related objects that we'll be using.
3
+ module Pipes
4
+ # TODO: move pipe imports to the modules that actually use them.
5
+ import com.tinkerpop.pipes.AbstractPipe
6
+ import com.tinkerpop.pipes.transform.IdentityPipe
7
+ import com.tinkerpop.pipes.util.Pipeline
8
+ import com.tinkerpop.pipes.util.ExpandableIterator
9
+ import com.tinkerpop.pipes.util.MultiIterator
10
+ import com.tinkerpop.pipes.util.PipeHelper
11
+
12
+ import com.tinkerpop.pipes.filter.RandomFilterPipe
13
+ import com.tinkerpop.pipes.filter.DuplicateFilterPipe
14
+ import com.tinkerpop.pipes.filter.RangeFilterPipe
15
+ import com.tinkerpop.pipes.filter.FilterPipe
16
+
17
+ import com.tinkerpop.pipes.transform.IdPipe
18
+ import com.tinkerpop.pipes.transform.PropertyPipe
19
+
20
+ EQUAL = FilterPipe::Filter::EQUAL
21
+ NOT_EQUAL = FilterPipe::Filter::NOT_EQUAL
22
+ #GREATER_THAN, LESS_THAN, GREATER_THAN_EQUAL, LESS_THAN_EQUAL
23
+ end
24
+
25
+ import java.util.Iterator
26
+ begin
27
+ java.util.ArrayList.new.iterator.next
28
+ rescue NativeException => e
29
+ NoSuchElementException = e.cause
30
+ Pipes::NoSuchElementException = e.cause
31
+ end
32
+ end
33
+
34
+ require 'pacer/pipe/ruby_pipe'
35
+
36
+ require 'pacer/pipe/never_pipe'
37
+ require 'pacer/pipe/block_filter_pipe'
38
+ require 'pacer/pipe/collection_filter_pipe'
39
+ require 'pacer/pipe/enumerable_pipe'
40
+ require 'pacer/pipe/expandable_pipe'
41
+ require 'pacer/pipe/loop_pipe'
42
+ require 'pacer/pipe/map_pipe'
43
+ require 'pacer/pipe/process_pipe'
44
+ require 'pacer/pipe/visitor_pipe'
45
+ require 'pacer/pipe/simple_visitor_pipe'
46
+ require 'pacer/pipe/is_unique_pipe'
47
+ require 'pacer/pipe/is_empty_pipe'
48
+ require 'pacer/pipe/stream_sort_pipe'
49
+ require 'pacer/pipe/stream_uniq_pipe'
50
+ require 'pacer/pipe/type_filter_pipe'
51
+ require 'pacer/pipe/label_collection_filter_pipe'
52
+ require 'pacer/pipe/id_collection_filter_pipe'
53
+ require 'pacer/pipe/label_prefix_pipe'
54
+ require 'pacer/pipe/variable_store_iterator_wrapper'
55
+
56
+ require 'pacer/pipe/property_comparison_pipe'
57
+
58
+ require 'pacer/pipe/blackbox_pipeline'
59
+
60
+ require 'pacer/pipe/unary_transform_pipe'
61
+ require 'pacer/pipe/cross_product_transform_pipe'
@@ -0,0 +1,52 @@
1
+ module Pacer::Routes
2
+
3
+ # Additional iteration methods that allow for rapid data
4
+ # manipulation in transactional graphs. Bulk operations automatically
5
+ # manage transactions in larger batches rather than on every
6
+ # element created or removed or every property set.
7
+ module BulkOperations
8
+ # Like bulk_job that also returns an array of results
9
+ def bulk_map(size = nil, target_graph = nil)
10
+ result = []
11
+ bulk_job(size, target_graph) do |e|
12
+ result << yield(e)
13
+ end
14
+ result
15
+ end
16
+
17
+ # Iterates over each element in the route, controlling
18
+ # transactions so that they are only committed once every
19
+ # +size+ records.
20
+ def bulk_job(size = nil, target_graph = nil)
21
+ target_graph ||= graph
22
+ if target_graph and not target_graph.in_bulk_job?
23
+ begin
24
+ target_graph.in_bulk_job = true
25
+ size ||= target_graph.bulk_job_size
26
+ counter = 0
27
+ each_slice(size) do |slice|
28
+ print counter if Pacer.verbose?
29
+ counter += size
30
+ target_graph.managed_manual_transaction do
31
+ target_graph.unmanaged_transactions do
32
+ slice.each do |element|
33
+ yield element
34
+ end
35
+ end
36
+ print '.' if Pacer.verbose?
37
+ end
38
+ end
39
+ ensure
40
+ puts '!' if Pacer.verbose?
41
+ target_graph.in_bulk_job = false
42
+ end
43
+ elsif target_graph
44
+ each do |element|
45
+ yield element
46
+ end
47
+ else
48
+ raise 'No graph in route for bulk job'
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,107 @@
1
+ module Pacer::Routes
2
+
3
+ # Additional convenience and data analysis methods that can be mixed into
4
+ # routes if they support the full route interface.
5
+ module RouteOperations
6
+ include BulkOperations
7
+
8
+ def has?(element)
9
+ any? { |e| e == element }
10
+ end
11
+
12
+ # Creates a hash where the key is the properties and return value of the
13
+ # given block, and the value is the number of times each key was found in
14
+ # the results set.
15
+ def group_count(*props)
16
+ result = Hash.new(0)
17
+ props = props.collect { |p| p.to_s }
18
+ if props.empty? and block_given?
19
+ each { |e| result[yield(e)] += 1 }
20
+ elsif block_given?
21
+ each do |e|
22
+ key = props.collect { |p| e.getProperty(p) }
23
+ key << yield(e)
24
+ result[key] += 1
25
+ end
26
+ elsif props.count == 1
27
+ prop = props.first
28
+ each do |e|
29
+ result[e.getProperty(prop)] += 1
30
+ end
31
+ elsif props.any?
32
+ each do |e|
33
+ result[props.collect { |p| e.getProperty(p) }] += 1
34
+ end
35
+ else
36
+ each do |e|
37
+ result[e] += 1
38
+ end
39
+ end
40
+ result
41
+ end
42
+
43
+ def most_frequent(range = 0, include_counts = false)
44
+ if include_counts
45
+ result = group_count.sort_by { |k, v| -v }[range]
46
+ if not result and range.is_a? Fixnum
47
+ []
48
+ else
49
+ result
50
+ end
51
+ else
52
+ result = group_count.sort_by { |k, v| -v }[range]
53
+ if range.is_a? Fixnum
54
+ result.first if result
55
+ elsif result
56
+ result.collect { |k, v| k }.to_route(:based_on => self)
57
+ else
58
+ [].to_route(:based_on => self)
59
+ end
60
+ end
61
+ end
62
+
63
+ # Store the current intermediate element in the route's vars hash by the
64
+ # given name so that it is accessible subsequently in the processing of the
65
+ # route.
66
+ def as(name)
67
+ chain_route :modules => VariableRouteModule, :variable_name => name
68
+ end
69
+
70
+ # Returns true if this route could contain both vertices and edges.
71
+ def mixed_route?
72
+ self.is_a? Pacer::Core::Graph::MixedRoute
73
+ end
74
+
75
+ # Returns true if this route countains only vertices.
76
+ def vertices_route?
77
+ self.is_a? Pacer::Core::Graph::VerticesRoute
78
+ end
79
+
80
+ # Returns true if this route countains only edges.
81
+ def edges_route?
82
+ self.is_a? Pacer::Core::Graph::EdgesRoute
83
+ end
84
+
85
+ def pages(elements_per_page = 1000)
86
+ page = []
87
+ results = []
88
+ idx = 0
89
+ each do |e|
90
+ page << e
91
+ idx += 1
92
+ if idx % elements_per_page == 0
93
+ results << yield(page)
94
+ page = []
95
+ end
96
+ end
97
+ yield page unless page.empty?
98
+ results
99
+ end
100
+
101
+ protected
102
+
103
+ def has_routable_class?
104
+ true
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,26 @@
1
+ module Pacer::Routes
2
+
3
+ # Adds support to a route to store a variable inline during processing. See
4
+ # Pacer::Routes::RouteOperations#as
5
+ module VariableRouteModule
6
+ attr_accessor :variable_name
7
+
8
+ def root?
9
+ false
10
+ end
11
+
12
+ protected
13
+
14
+ def attach_pipe(pipe)
15
+ Pacer::Pipes::VariableStoreIteratorWrapper.new(pipe, vars, @variable_name)
16
+ end
17
+
18
+ def has_routable_class?
19
+ false
20
+ end
21
+
22
+ def inspect_class_name
23
+ @variable_name.inspect
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ require 'pacer/route/mixin/bulk_operations'
2
+ require 'pacer/route/mixin/route_operations'
3
+ require 'pacer/route/mixin/variable_route_module'