Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 3 commits
  • 9 files changed
  • 0 commit comments
  • 1 contributor
Commits on Oct 27, 2011
Darrick Wiebe Revert "Temporarily remove the experimental stuff from this branch to…
… prepare to merge it."

This reverts commit 7ca15e6.
a7db4ff
Darrick Wiebe The join samples I'm playing with. d26a711
Darrick Wiebe idea on improving loop pipe d468b96
View
2  lib/pacer/blueprints.rb
@@ -2,3 +2,5 @@
require 'pacer/blueprints/tg'
require 'pacer/blueprints/ruby_graph'
require 'pacer/blueprints/multi_graph'
+require 'pacer/blueprints/replay_graph'
+require 'pacer/blueprints/hyper_graph'
View
47 lib/pacer/blueprints/hyper_graph.rb
@@ -0,0 +1,47 @@
+module Pacer
+ class HyperGraph < MultiGraph
+ def element_class
+ RubyElement
+ end
+
+ def vertex_class
+ MultiVertex
+ end
+
+ def edge_class
+ HyperEdge
+ end
+ end
+
+
+ class HyperEdge < RubyEdge
+ include com.tinkerpop.blueprints.pgm.Vertex
+
+ def getInEdges(*labels)
+ labels = extract_varargs_strings(labels)
+ edges = graph.getEdges.select { |e| e.getInVertex == self and (labels.empty? or labels.include? e.getLabel) }
+ Pacer::Pipes::EnumerablePipe.new edges
+ end
+
+ def getOutEdges(*labels)
+ labels = extract_varargs_strings(labels)
+ edges = graph.getEdges.select { |e| e.getOutVertex == self and (labels.empty? or labels.include? e.getLabel) }
+ Pacer::Pipes::EnumerablePipe.new edges
+ end
+
+ def inspect
+ "#<E[#{element_id}]:#{display_name}>"
+ end
+
+ def display_name
+ if graph and graph.edge_name
+ graph.edge_name.call self
+ else
+ "#{ out_vertex.element_id }-#{ getLabel }-#{ in_vertex.element_id }"
+ end
+ end
+
+ include VertexExtensions
+ include EdgeExtensions
+ end
+end
View
79 lib/pacer/blueprints/replay_graph.rb
@@ -0,0 +1,79 @@
+module Pacer
+ class ReplayGraph < RubyGraph
+ attr_accessor :target_graph
+ attr_reader :commands, :id_prefix
+
+ def initialize(target_graph = nil)
+ super()
+ @graph_id = Pacer.next_graph_id
+ @id_prefix = "#{ @graph_id }:".freeze
+ @target_graph = target_graph
+ end
+
+ def addVertex(id)
+ if id.is_a? String and id[0, id_prefix.length] == id_prefix
+ v_id = id
+ elsif id
+ v_id = id_prefix + id.to_s
+ else
+ v_id = next_id
+ end
+ raise Pacer::ElementExists if @vertices.key? v_id
+ vertex = @vertices[v_id] = vertex_class.new(self, v_id)
+ commands << [nil, :addVertex, v_id]
+ vertex
+ end
+
+ def getVertex(id)
+ if id.is_a? String and id[0, id_prefix.length] == id_prefix
+ @vertices[id]
+ else
+ @vertices[id_prefix + id.to_s]
+ end
+ end
+
+ def removeVertex(vertex)
+ commands << [nil, :removeVertex, vertex]
+ super
+ end
+
+ def addEdge(id, outVertex, inVertex, label)
+ super.tap do |edge|
+ commands << [nil, :addEdge, edge.element_id, edge.getOutVertex, edge.getInVertex, edge.getLabel]
+ end
+ end
+
+ def removeEdge(edge)
+ edge = edge.getRawEdge if edge.respond_to? :getRawEdge
+ commands << [nil, :removeEdge, edge.getRawEdge]
+ super
+ end
+
+ def clear
+ super
+ @commands = []
+ end
+
+ def ==(other)
+ (@target_graph and other == @target_graph) or super
+ end
+
+ protected
+
+ def next_id
+ id_prefix + super.to_s
+ end
+ end
+
+ class ReplayElement < RubyElement
+ def setProperty(key, value)
+ @graph.commands << [self, :setProperty, key, value]
+ super
+ end
+
+ def removeProperty(key)
+ @graph.commands << [self, :removeProperty, key]
+ super
+ end
+ end
+end
View
1  lib/pacer/extensions.rb
@@ -4,3 +4,4 @@ module Extensions
end
require 'pacer/extensions/block_filter_element'
+require 'pacer/extensions/disconnected_element'
View
31 lib/pacer/extensions/disconnected_element.rb
@@ -0,0 +1,31 @@
+module Pacer
+ module Extensions
+ module Disconnected
+ module Element
+ def replay
+ @replay = ReplayGraph.new(graph) unless defined? @replay
+ @replay
+ end
+ end
+
+ module Vertex
+ V = com.tinkerpop.blueprints.pgm.Vertex
+ include Element
+
+ def initialize(element = nil)
+ if element.is_a? V
+ @element = element
+ else
+ @element ||= replay.create_vertex
+ @element.properties = element if element.is_a? Hash
+ end
+ after_initialize
+ end
+ end
+
+ module Edge
+ include Element
+ end
+ end
+ end
+end
View
1  lib/pacer/side_effect.rb
@@ -9,3 +9,4 @@ module SideEffect
require 'pacer/side_effect/counted'
require 'pacer/side_effect/section'
require 'pacer/side_effect/visitor'
+require 'pacer/side_effect/collected'
View
85 lib/pacer/side_effect/collected.rb
@@ -0,0 +1,85 @@
+module Pacer
+ module Core
+ module Route
+ def collect_with(multigraph)
+ vars[:multigraph] = multigraph
+ end
+
+ def collect_as(name, opts = {})
+ process do |element|
+ g = vars[:multigraph] ||= Pacer::MultiGraph.new
+ v = vars[name] = g.create_vertex
+ v[name] = element
+ within = opts[:within]
+ if within
+ within_v = vars[within]
+ g.create_edge nil, v, within_v, :within
+ end
+ end
+ end
+
+ def add_to(collection_name, name = nil)
+ process do |element|
+ v = vars[collection_name]
+ if name
+ existing = v[name]
+ if existing
+ existing << element
+ else
+ v[name] = [element]
+ end
+ end
+ if block_given?
+ yield v, element
+ end
+ end
+ end
+
+ def map_to(collection_name, name)
+ process do |element|
+ v = vars[collection_name]
+ existing = v[name]
+ if block_given?
+ mapped = yield element, v
+ else
+ mapped = element
+ end
+ if existing
+ existing << mapped
+ else
+ v[name] = [mapped]
+ end
+ end
+ end
+
+ def reduce_to(collection_name, name, starting_value)
+ process do |element|
+ v = vars[collection_name]
+ total = v[name]
+ if total
+ v[name] = yield total, element
+ else
+ v[name] = yield starting_value, element
+ end
+ end
+ end
+
+ def execute!
+ p = pipe
+ while p.hasNext
+ p.next
+ end
+ self.route
+ end
+
+ def collected(name = nil)
+ # TODO: VarSideEffectPipe
+ if name
+ map(graph: vars[:multigraph], element_type: :vertex) { vars[name] }
+ else
+ execute!.vars[:multigraph]
+ end
+ end
+ end
+ end
+end
View
64 samples/join.rb
@@ -0,0 +1,64 @@
+# setup:
+def setup_graph
+ g = Pacer.tg
+ person = g.create_vertex type: 'person'
+ 20.times { g.create_vertex type: 'person' }
+ g.v.each { |v| v.add_edges_to :friend, g.v.random(rand(10)) }
+ 20.times { g.create_vertex :type => 'product' }
+ g.v(type: 'person').each { |person| g.v(type: 'product').random(rand(10)).each { |prod| prod.add_edges_to :rated, person, weight: rand(5) } }
+ [g, person]
+end
+
+def groups1(person)
+ groups = person.out.group.values_route(:default) { |friend| friend.out.is_not(person).in_e(:rated)[:weight] }
+ groups.each { |g| g.set_values(:sum, g.values.sum) }
+ groups.sort_by { |g| -g.values.sum }
+
+ groups.reduce(0, :values) { |r, v| r + v }
+end
+
+
+def groups2(person)
+ groups2 = person.v.collect_as(:person).out.collect_as(:friend, within: :person).out.is_not(person).in_e(:rated)[:weight].reduce_to(:friend, :sum, 0) { |total, weight| total + weight }.collected
+end
+
+def sorted(person)
+ groups2(person).v.where('sum != nil')[[:sum, :friend]].sort
+end
+
+def groups3(person)
+ person.in(:rated).out(:rated).is_not(person).uniq.group.values_route(:default) do |friend|
+ friend.in_e(:rated).as(:fre).out_v.out_e.as(:mre).in_v.is(person).map do |v|
+ 5 - (v.vars[:fre][:weight] - v.vars[:mre][:weight]).abs
+ end
+ end.reduce(0) { |total, n| total + n }
+end
+
+def groups5(person)
+ mg = person.in(:rated).out(:rated).is_not(person).uniq.
+ join(:ratings) do |friend|
+ friend.in_e(:rated).as(:fre).out_v.out_e.as(:mre).in_v.is(person).map do |v|
+ 5 - (v.vars[:fre][:weight] - v.vars[:mre][:weight]).abs
+ end
+ end.
+ join(:friend) { |f| f }.
+ join(:person) { person }.
+ join(:rated) { |friend| friend.in_e(:rated).out_v.lookahead { |v| v.out_e.in_v.is(person) } }.
+ join(:friend_ratings) { |friend| friend.in_e(:rated).lookahead { |e| e.out_v.out.is(person) }[:weight].paths }.
+ join(:person_ratings) { |friend| friend.in(:rated).out_e.lookahead { |e| e.in_v.is(person) }[:weight].paths }.
+ multigraph
+ mg.v.each { |v| v[:sum] = v[:ratings].inject(:+) }
+ mg
+end
+
+def groups4(person)
+ graph = person.v.
+ in(:rated).out(:rated).is_not(person).uniq.collect_as(:friend).
+ in_e(:rated).as(:fre).out_v.out_e.as(:mre).in_v.is(person).map_to(:friend, :ratings) do |v, _|
+ 5 - (v.vars[:fre][:weight] - v.vars[:mre][:weight]).abs
+ end.
+ collected
+ graph.v.each { |v| v[:sum] = v[:ratings].inject(:+) }
+ graph
+end
+
View
11 spec/pacer/filter/loop_filter_spec.rb
@@ -16,6 +16,17 @@
end
describe 'with a range' do
+ # Because the same pipe is reused for looping pipes, this will only ever return
+ # the first element before the range pipe is exhausted. The resulting element which is emitted and looped will produce
+ # no output because the range is not reset for the new depth.
+ #
+ # A possible solution to this would be for the loop pipe to generate and maintain a separate segment of pipe for each depth. It could generate them
+ # dynamically, In fact it would be as simple as using a hash with a default proc to provide pipes for each depth. Pseudo code:
+ # depths = Hash.new { |h, depth| h[depth] = build_pipe_segment }
+ # pipeline = depths[depth]
+ # pipeline.expand element
+ # pipeline.next
+ #
before { pending }
let(:start) { graph.vertex(0).v }
subject { start.repeat(1..3) { |tail| tail.out_e.in_v[0] } }

No commit comments for this range

Something went wrong with that request. Please try again.