Class: OMF::Rete::IndexedTupleSet

Inherits:
AbstractTupleSet show all
Defined in:
lib/omf_rete/indexed_tuple_set.rb

Overview

This class maintains a set of tuples and supports a block being attached which is being called whenever a tuple is added or removed.

The IndexedTupleSet is defined by a description and an indexPattern.

The description is an array of the same length as the tuples maintained. Each element, if not nil, names the binding variable associated with it. The position of a binding can be retrieved with index_for_binding.

The indexPattern describes which elements of the inserted tuple are being combined in an array to form the index key for each internal tuple. The elements in the indexPattern are described by the binding name.

Instance Attribute Summary collapse

Attributes inherited from AbstractTupleSet

#description, #source

Instance Method Summary collapse

Methods inherited from AbstractTupleSet

#binding_at, #detach, #index_for_binding, #register_with_store

Constructor Details

#initialize(description, indexPattern, source = nil, opts = {}) ⇒ IndexedTupleSet

Returns a new instance of IndexedTupleSet.



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/omf_rete/indexed_tuple_set.rb', line 30

def initialize(description, indexPattern, source = nil, opts = {})
  super description, source
  if (indexPattern.length == 0)
    raise "Expected index to be non-nil (#{description.join(', ')})"
  end
  @indexPattern = indexPattern
  @indexMap = indexPattern.collect do |bname|
    index_for_binding(bname)
  end

  @index = {}
end

Instance Attribute Details

#indexPatternObject (readonly)

Returns the value of attribute indexPattern.



27
28
29
# File 'lib/omf_rete/indexed_tuple_set.rb', line 27

def indexPattern
  @indexPattern
end

#transient=(value) ⇒ Object (writeonly)

if true only process tuple but don’t store it



28
29
30
# File 'lib/omf_rete/indexed_tuple_set.rb', line 28

def transient=(value)
  @transient = value
end

Instance Method Details

#[](key) ⇒ Object

Return the set of tuples index by key. Will return nil if nothing is stored for key



160
161
162
163
# File 'lib/omf_rete/indexed_tuple_set.rb', line 160

def [](key)
  res = @index[key]
  res
end

#addTuple(tuple) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/omf_rete/indexed_tuple_set.rb', line 43

def addTuple(tuple)
  key = @indexMap.collect do |ii|
    tuple[ii]
  end

  if @transient
    @onAddBlockWithIndex.call(key, tuple) if @onAddBlockWithIndex
    @onAddBlock.call(tuple) if @onAddBlock
  else
    vset = (@index[key] ||= Set.new)
    if vset.add?(tuple)
      # new value
      @onAddBlockWithIndex.call(key, tuple) if @onAddBlockWithIndex
      @onAddBlock.call(tuple) if @onAddBlock
    end
  end
  tuple # return added tuple
end

#clearObject

Clear index



82
83
84
85
86
# File 'lib/omf_rete/indexed_tuple_set.rb', line 82

def clear()
  @onRemoveBlockWithIndex.call(nil, nil) if @onRemoveBlockWithIndex
  @onRemoveBlock.call(nil) if @onRemoveBlock
  @index = {}
end

#describe(out = STDOUT, offset = 0, incr = 2, sep = "\n") ⇒ Object



189
190
191
192
193
194
195
196
# File 'lib/omf_rete/indexed_tuple_set.rb', line 189

def describe(out = STDOUT, offset = 0, incr = 2, sep = "\n")
  out.write(" " * offset)
  desc = @description.collect do |e| e || '*' end
  out.write("ts: [#{desc.join(', ')}]")
  ind = @indexMap.collect do |i| @description[i] end
  out.write("  (index: [#{ind.sort.join(', ')}])#{sep}")
  @source.describe(out, offset + incr, incr, sep) if @source
end

#on_add(&block) ⇒ Object

Call block for every tuple stored in this set currently and in the future. In other words, the block may be called even after this method returns.

The block will be called with one parameters, the tuple added.

Note: Only one block can be registered at a time



99
100
101
102
103
104
105
106
# File 'lib/omf_rete/indexed_tuple_set.rb', line 99

def on_add(&block)
  @index.each do |index, values|
    values.each do |v|
      block.call(v)
    end
  end
  @onAddBlock = block
end

#on_add_with_index(&block) ⇒ Object

Call block for every tuple stored in this set currently and in the future. In other words, the block may be called even after this method returns.

The block will be called with two parameters, the index of the tuple followed by the tuple itself.

Note: Only one block can be registered at a time



118
119
120
121
122
123
124
125
# File 'lib/omf_rete/indexed_tuple_set.rb', line 118

def on_add_with_index(&block)
  @index.each do |index, values|
    values.each do |v|
      block.call(index, v)
    end
  end
  @onAddBlockWithIndex = block
end

#on_remove(&block) ⇒ Object

Call block for every tuple removed from this set in the future. In other words, the block may be called after this method returns.

The block will be called with one parameters, the tuple removed. If the parameter is nil, everything has been removed (cleared)

Note: Only one block can be registered at a time



137
138
139
# File 'lib/omf_rete/indexed_tuple_set.rb', line 137

def on_remove(&block)
  @onRemoveBlock = block
end

#on_remove_with_index(&block) ⇒ Object

Call block for every tuple removed from this set in the future. In other words, the block may be called even after this method returns.

The block will be called with two parameters, the index of the tuple followed by the tuple itself. If both parameters are nil, everything has been removed (cleared)

Note: Only one block can be registered at a time



152
153
154
# File 'lib/omf_rete/indexed_tuple_set.rb', line 152

def on_remove_with_index(&block)
  @onRemoveBlockWithIndex = block
end

#removeTuple(tuple) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/omf_rete/indexed_tuple_set.rb', line 62

def removeTuple(tuple)
  key = @indexMap.collect do |ii|
    tuple[ii]
  end

  if @transient
    @onRemoveBlockWithIndex.call(key, tuple) if @onRemoveBlockWithIndex
    @onRemoveBlock.call(tuple) if @onRemoveBlock
  else
    vset = @index[key]
    if vset
      vset.delete(tuple)
      @onRemoveBlockWithIndex.call(key, tuple) if @onRemoveBlockWithIndex
      @onRemoveBlock.call(tuple) if @onRemoveBlock
    end
  end
  tuple # return removed tuple
end

#to_aObject

Return all stored tuples in an array.



166
167
168
169
170
171
172
173
174
# File 'lib/omf_rete/indexed_tuple_set.rb', line 166

def to_a
  a = []
  @index.each_value do |s|
    s.each do |t|
      a << t
    end
  end
  a
end

#to_setObject

Return all stored tuples in a set.



177
178
179
180
181
182
183
184
185
# File 'lib/omf_rete/indexed_tuple_set.rb', line 177

def to_set
  a = Set.new
  @index.each_value do |s|
    s.each do |t|
      a << t
    end
  end
  a
end