red_grape 0.0.9 → 0.0.10

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/lib/ext/array_ext.rb CHANGED
@@ -1,12 +1,18 @@
1
1
  class Array
2
+ attr_accessor :should_pass_through_whole #TODO
3
+
2
4
  def pass_through(pipe, context)
3
- loops = context.loops
4
- map! do |e|
5
+ if @should_pass_through_whole
6
+ super
7
+ else
8
+ loops = context.loops
9
+ map! do |e|
10
+ context.loops = loops
11
+ pipe.pass e, context
12
+ end
5
13
  context.loops = loops
6
- pipe.pass e, context
14
+ normalize_for_graph
7
15
  end
8
- context.loops = loops
9
- normalize_for_graph
10
16
  end
11
17
 
12
18
  def normalize_for_graph
@@ -61,6 +61,8 @@ module RedGrape
61
61
  context.resume_from_aggregating
62
62
  elsif context.grouping?
63
63
  context.resume_from_grouping
64
+ elsif context.gathering?
65
+ context.resume_from_gathering
64
66
  else
65
67
  val
66
68
  end
@@ -5,9 +5,9 @@ module RedGrape
5
5
  class CapPipe < Pipe::Base
6
6
  def pass(obj, context)
7
7
  ret = {}
8
- context.grouping_items.each do |e|
9
- ret[e.first] ||= 0
10
- ret[e.first] += 1
8
+ context.grouping_items.each do |k, v|
9
+ v = v.map &:first
10
+ ret[k] = self.pipe_eval(it:v, &self.prev.reduce_function)
11
11
  end
12
12
  ret
13
13
  end
@@ -9,7 +9,8 @@ module RedGrape
9
9
  @marks = {}
10
10
  @aggregating_items = {}
11
11
  @aggregated_items = {}
12
- @grouping_items = []
12
+ @grouping_items = {}
13
+ @gathering_items = []
13
14
  @loops = 1
14
15
  end
15
16
 
@@ -66,8 +67,8 @@ module RedGrape
66
67
  ret.normalize_for_graph
67
68
  end
68
69
 
69
- def group(val, next_pipe)
70
- @grouping_items << [val, next_pipe]
70
+ def group(next_pipe, key, val=key)
71
+ (@grouping_items[key] ||= []) << [val, next_pipe]
71
72
  val
72
73
  end
73
74
 
@@ -76,16 +77,42 @@ module RedGrape
76
77
  end
77
78
 
78
79
  def resume_from_grouping
79
- obj, pipe = *@grouping_items.first # TODO: '.first' is used to get next_pipe.
80
+ obj, pipe = *@grouping_items.values.first.first # TODO: '.first' is used to get next_pipe.
80
81
  if pipe
81
82
  push_history obj do |ctx|
82
- obj.pass_through(pipe, ctx)
83
+ obj.pass_through pipe, ctx
83
84
  end
84
85
  else
85
86
  obj
86
87
  end
87
88
  end
88
89
 
90
+ def gather(obj, next_pipe)
91
+ @gathering_items << [obj, next_pipe]
92
+ end
93
+
94
+ def gathering?
95
+ not @gathering_items.empty?
96
+ end
97
+
98
+ def clear_gathering
99
+ @gathering_items.clear
100
+ end
101
+
102
+ def resume_from_gathering
103
+ obj, pipe = *@gathering_items.first
104
+ objs = @gathering_items.map &:first
105
+ objs.should_pass_through_whole = true
106
+ if pipe
107
+ push_history objs do |ctx|
108
+ pipe.prev = objs
109
+ pipe.take ctx
110
+ end
111
+ else
112
+ objs
113
+ end
114
+ end
115
+
89
116
  def eval(args={}, &block)
90
117
  args.each {|k, v| self.send "#{k}=", v}
91
118
  instance_eval(&block)
@@ -0,0 +1,12 @@
1
+ require 'red_grape/pipe/base'
2
+
3
+ module RedGrape
4
+ module Pipe
5
+ class GatherPipe < Pipe::Base
6
+ def pass(obj, context)
7
+ context.gather obj, self.next
8
+ obj
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ require 'red_grape/pipe/base'
2
+
3
+ module RedGrape
4
+ module Pipe
5
+ class GroupByPipe < Pipe::Base
6
+ attr_accessor :reduce_function
7
+
8
+ def pass(obj, context)
9
+ key_function, value_function, @reduce_function = *self.opts
10
+ value_function ||= proc{it}
11
+ @reduce_function ||= proc{it}
12
+ if self.opts.empty?
13
+ context.group self.next, obj
14
+ elsif self.opts.first.is_a? Proc
15
+ context.group(
16
+ self.next,
17
+ pipe_eval(it:obj, &key_function),
18
+ pipe_eval(it:obj, &value_function)
19
+ )
20
+ else
21
+ self.opts.first[obj] ||= []
22
+ self.opts.first[obj] << obj
23
+ end
24
+ obj
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -3,13 +3,13 @@ require 'red_grape/pipe/base'
3
3
  module RedGrape
4
4
  module Pipe
5
5
  class GroupCountPipe < Pipe::Base
6
+ attr_accessor :reduce_function
6
7
  def pass(obj, context)
8
+ @reduce_function = proc{it.size}
7
9
  if self.opts.empty?
8
- #context.group({obj => 1}, self.next)
9
- context.group obj, self.next
10
+ context.group self.next, obj
10
11
  elsif self.opts.first.is_a? Proc
11
- #context.group({pipe_eval(it:obj, &self.opts.first) => 1}, self.next)
12
- context.group pipe_eval(it:obj, &self.opts.first), self.next
12
+ context.group self.next, pipe_eval(it:obj, &self.opts.first)
13
13
  else
14
14
  self.opts.first[obj] ||= 0
15
15
  self.opts.first[obj] += 1
@@ -0,0 +1,19 @@
1
+ require 'red_grape/pipe/base'
2
+
3
+ module RedGrape
4
+ module Pipe
5
+ class HasNotPipe < Pipe::Base
6
+ def pass(obj, context)
7
+ prop, val = *self.opts
8
+ filter = proc{it[prop] == val}
9
+
10
+ # TODO: same as filter_pipe (has_pipe)
11
+ unless context.eval :it => obj, &filter
12
+ pass_next context, obj
13
+ else
14
+ nil
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ require 'red_grape/pipe/base'
2
+
3
+ module RedGrape
4
+ module Pipe
5
+ class ScatterPipe < Pipe::Base
6
+ def pass(obj, context)
7
+ obj.should_pass_through_whole = false
8
+ context.clear_gathering
9
+ pass_next context, obj
10
+ end
11
+ end
12
+ end
13
+ end
@@ -3,8 +3,12 @@ require 'red_grape/pipe/base'
3
3
  module RedGrape
4
4
  module Pipe
5
5
  module Underscore
6
- def _(*opts)
7
- UnderscorePipe.new self.dup, *opts#
6
+ def _(*opts, &block)
7
+ if block
8
+ Proc.new &block
9
+ else
10
+ UnderscorePipe.new self.dup, *opts#
11
+ end
8
12
  end
9
13
  end
10
14
 
data/lib/red_grape.rb CHANGED
@@ -1,7 +1,10 @@
1
+ module RedGrape
2
+ VERSION = '0.0.10'
3
+ end
4
+
1
5
  require 'ext/nil_class_ext'
2
6
  require 'ext/object_ext'
3
7
  require 'ext/array_ext'
4
- require 'red_grape/version'
5
8
  require 'red_grape/pipe/aggregate_pipe'
6
9
  require 'red_grape/pipe/as_pipe'
7
10
  require 'red_grape/pipe/back_pipe'
@@ -11,6 +14,7 @@ require 'red_grape/pipe/except_pipe'
11
14
  require 'red_grape/pipe/exhaust_merge_pipe'
12
15
  require 'red_grape/pipe/fill_pipe'
13
16
  require 'red_grape/pipe/filter_pipe'
17
+ require 'red_grape/pipe/gather_pipe'
14
18
  require 'red_grape/pipe/group_by_pipe'
15
19
  require 'red_grape/pipe/group_count_pipe'
16
20
  require 'red_grape/pipe/has_pipe'
@@ -26,6 +30,7 @@ require 'red_grape/pipe/out_v_pipe'
26
30
  require 'red_grape/pipe/property_pipe'
27
31
  require 'red_grape/pipe/paths_pipe'
28
32
  require 'red_grape/pipe/retain_pipe'
33
+ require 'red_grape/pipe/scatter_pipe'
29
34
  require 'red_grape/pipe/side_effect_pipe'
30
35
  require 'red_grape/pipe/transform_pipe'
31
36
  require 'red_grape/pipe/v_pipe'
@@ -33,8 +38,6 @@ require 'red_grape/pipe/e_pipe'
33
38
  require 'red_grape/graph'
34
39
 
35
40
  module RedGrape
36
- VERSION = "0.0.9"
37
-
38
41
  module_function
39
42
  def set_auto_take(val=true)
40
43
  Pipe.set_auto_take val
@@ -117,17 +117,47 @@ class TraversalPatternsTest < Test::Unit::TestCase
117
117
  )
118
118
  end
119
119
 
120
+ # https://github.com/tinkerpop/gremlin/wiki/MapReduce-Pattern
120
121
  def test_map_reduce_pattern
121
122
  @g2 ||= RedGrape.load_graph 'data/graph-example-2.xml'
122
123
  assert_equal(
123
124
  {'cover'=>313, 'original'=>184},
124
125
  @g2.V.has_not('song_type', nil).group_count(proc{it.song_type}).cap.take
125
126
  )
126
- =begin
127
- assert_equal(
128
- {},
129
- @g2.V.has_not('song_type', nil).group_by(proc{it.song_type}, proc{it}).cap.take
130
- )
131
- =end
127
+
128
+ ret = @g2.V.has_not('song_type', nil).group_by(proc{it.song_type}, proc{it}).cap.take
129
+ assert_equal 2, ret.keys.size
130
+ assert_equal 313, ret.values[0].size
131
+ assert ret.values[0].all?{|e| e.is_a? RedGrape::Vertex}
132
+ assert_equal 184, ret.values[1].size
133
+ assert ret.values[1].all?{|e| e.is_a? RedGrape::Vertex}
134
+
135
+ ret = @g2.V.has_not('song_type', nil).group_by(_{it.song_type}, _{it.name}).cap.take
136
+ assert_equal 2, ret.keys.size
137
+ assert_equal 313, ret.values[0].size
138
+ assert ret.values[0].all?{|e| e.is_a? String}
139
+ assert_equal 184, ret.values[1].size
140
+ assert ret.values[1].all?{|e| e.is_a? String}
141
+ assert_equal 'HEY BO DIDDLEY', ret.values[0][0]
142
+ assert_equal 'BERTHA', ret.values[1][0]
143
+
144
+ ret = @g2.V.has_not('song_type', nil).group_by(_{it.song_type}, _{1}).cap.take
145
+ assert_equal 2, ret.keys.size
146
+ assert ret.values[0].all?{|e| e == 1}
147
+ assert ret.values[1].all?{|e| e == 1}
148
+
149
+ ret = @g2.V.has_not('song_type', nil).group_by(_{it.song_type}, _{1}, _{it.size}).cap.take
150
+ assert_equal 313, ret.values[0]
151
+ assert_equal 184, ret.values[1]
152
+
153
+ ret = @g2.V.has_not('song_type', nil).group_by(_{it.song_type}, _{it.out('sung_by').take}, _{it._.name.group_count.cap.take}).cap.take
154
+ assert_equal 66, ret[0]['cover']['Weir']
155
+ assert_equal 33, ret[0]['original']['Weir']
156
+ end
157
+
158
+ # https://github.com/tinkerpop/gremlin/wiki/Depth-First-vs.-Breadth-First
159
+ def test_depth_first_vs_bredth_first
160
+ assert_equal %w(1 4 6), @g1.v(1).out_e('created').in_v.in_e('created').out_v.take.map(&:id)
161
+ assert_equal %w(1 4 6), @g1.v(1).out_e('created').gather.scatter.in_v.gather.scatter.in_e('created').gather.scatter.out_v.gather.scatter.take.map(&:id)
132
162
  end
133
163
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: red_grape
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-15 00:00:00.000000000 Z
12
+ date: 2012-06-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &70205221723480 !ruby/object:Gem::Requirement
16
+ requirement: &70324009053140 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70205221723480
24
+ version_requirements: *70324009053140
25
25
  description: RedGrape is an in-memory graph database written in ruby. I made this
26
26
  in order to learn how graph databases work so that please do not use this for any
27
27
  serious purpose.
@@ -61,7 +61,10 @@ files:
61
61
  - lib/red_grape/pipe/exhaust_merge_pipe.rb
62
62
  - lib/red_grape/pipe/fill_pipe.rb
63
63
  - lib/red_grape/pipe/filter_pipe.rb
64
+ - lib/red_grape/pipe/gather_pipe.rb
65
+ - lib/red_grape/pipe/group_by_pipe.rb
64
66
  - lib/red_grape/pipe/group_count_pipe.rb
67
+ - lib/red_grape/pipe/has_not_pipe.rb
65
68
  - lib/red_grape/pipe/has_pipe.rb
66
69
  - lib/red_grape/pipe/if_then_else_pipe.rb
67
70
  - lib/red_grape/pipe/in_e_pipe.rb
@@ -74,6 +77,7 @@ files:
74
77
  - lib/red_grape/pipe/paths_pipe.rb
75
78
  - lib/red_grape/pipe/property_pipe.rb
76
79
  - lib/red_grape/pipe/retain_pipe.rb
80
+ - lib/red_grape/pipe/scatter_pipe.rb
77
81
  - lib/red_grape/pipe/side_effect_pipe.rb
78
82
  - lib/red_grape/pipe/transform_pipe.rb
79
83
  - lib/red_grape/pipe/underscore_pipe.rb
@@ -82,7 +86,6 @@ files:
82
86
  - lib/red_grape/serializer/graphml_serializer.rb
83
87
  - lib/red_grape/tools/graph_store.rb
84
88
  - lib/red_grape/tools/irg.rb
85
- - lib/red_grape/version.rb
86
89
  - lib/red_grape/vertex.rb
87
90
  - red_grape.gemspec
88
91
  - test/all.rb
@@ -1,3 +0,0 @@
1
- module RedGrape
2
- VERSION = "0.0.8"
3
- end