Class: OMF::Rete::JoinOP
- Inherits:
-
Object
- Object
- OMF::Rete::JoinOP
- Defined in:
- lib/omf_rete/join_op.rb
Overview
This class implements the join operation between two IndexedTupleSets
feeding into a third, result tuple set. The size of both incoming tuple sets needs to be identical and they are supposed to be indexed on the same list of variables as this is what they wil be joined at.
Implementation Note: We first calculate a combinePattern
from the description
of the result set. The combinePattern
describes how to create a joined tuple to insert into the result tuple set. The combinePattern
is an array of the same size as the result tuple. Each element is a 2-array with the first element describing the input set (0 .. left, 1 .. right) and the second one the index from which to take the value.
Instance Method Summary collapse
-
#check_for_tuple(tuple) ⇒ Object
Check if
tuple
can be produced by this join op. - #describe(out = STDOUT, offset = 0, incr = 2, sep = "\n") ⇒ Object
- #description ⇒ Object
-
#detach ⇒ Object
Detach all streams from each other as they are no longer in use.
-
#initialize(leftSet, rightSet, resultSet) ⇒ JoinOP
constructor
A new instance of JoinOP.
Constructor Details
#initialize(leftSet, rightSet, resultSet) ⇒ JoinOP
Returns a new instance of JoinOP.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/omf_rete/join_op.rb', line 21 def initialize(leftSet, rightSet, resultSet) @resultSet = resultSet @left = leftSet @right = rightSet @combinePattern = resultSet.description.collect do |bname| side = 0 unless (i = leftSet.index_for_binding(bname)) side = 1 unless (i = rightSet.index_for_binding(bname)) raise "Can't find binding '#{bname}' in either streams. Should never happen" end end #description << bname [side, i] end @resultLength = @combinePattern.length @results = {} # Keep track of how may input tuples create the same result - necessary for 'removeTuple' leftSet.on_add_with_index do |index, ltuple| if (rs = rightSet[index]) rs.each do |rtuple| add_result(ltuple, rtuple) end end end rightSet.on_add_with_index do |index, rtuple| if (ls = leftSet[index]) ls.each do |ltuple| add_result(ltuple, rtuple) end end end leftSet.on_remove_with_index do |index, ltuple| if (index.nil?) clear_result() else if (rs = rightSet[index]) rs.each do |rtuple| remove_result(ltuple, rtuple) end end end end rightSet.on_remove_with_index do |index, rtuple| if (index.nil?) clear_result() else if (ls = leftSet[index]) ls.each do |ltuple| remove_result(ltuple, rtuple) end end end end # Supporting 'check_for_tuple' @left_pattern = @left.description.map do |bname| @resultSet.index_for_binding(bname) end @right_pattern = @right.description.map do |bname| @resultSet.index_for_binding(bname) end end |
Instance Method Details
#check_for_tuple(tuple) ⇒ Object
Check if tuple
can be produced by this join op. We first check if we can find a match on one side and then request from the other side all the tuples which would lead to full join.
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/omf_rete/join_op.rb', line 93 def check_for_tuple(tuple) ltuple = @left_pattern.map {|i| tuple[i]} if @left.check_for_tuple(ltuple) rtuple = @right_pattern.map {|i| tuple[i]} if @right.check_for_tuple(rtuple) return true end end return false end |
#describe(out = STDOUT, offset = 0, incr = 2, sep = "\n") ⇒ Object
117 118 119 120 121 122 123 124 125 |
# File 'lib/omf_rete/join_op.rb', line 117 def describe(out = STDOUT, offset = 0, incr = 2, sep = "\n") out.write(" " * offset) result = @combinePattern.collect do |side, index| (side == 0) ? @left.binding_at(index) : @right.binding_at(index) end out.write("join: [#{@left.indexPattern.sort.join(', ')}] => [#{result.sort.join(', ')}]#{sep}") @left.describe(out, offset + incr, incr, sep) @right.describe(out, offset + incr, incr, sep) end |
#description ⇒ Object
113 114 115 |
# File 'lib/omf_rete/join_op.rb', line 113 def description() @resultSet.description end |
#detach ⇒ Object
Detach all streams from each other as they are no longer in use
106 107 108 109 110 |
# File 'lib/omf_rete/join_op.rb', line 106 def detach() @left.detach @right.detach @results.clear end |