omf_rete 0.5 → 0.6.1
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/README.md +82 -74
- data/lib/omf_rete/abstract_tuple_set.rb +5 -1
- data/lib/omf_rete/indexed_tuple_set.rb +84 -17
- data/lib/omf_rete/join_op.rb +78 -18
- data/lib/omf_rete/planner/join_plan.rb +16 -15
- data/lib/omf_rete/planner/plan_builder.rb +52 -48
- data/lib/omf_rete/planner/source_plan.rb +14 -13
- data/lib/omf_rete/store/alpha/alpha_element.rb +3 -74
- data/lib/omf_rete/store/alpha/alpha_inner_element.rb +8 -58
- data/lib/omf_rete/store/alpha/alpha_leaf_element.rb +18 -3
- data/lib/omf_rete/store/alpha_store.rb +118 -0
- data/lib/omf_rete/store/named_alpha_store.rb +38 -0
- data/lib/omf_rete/store/object_store.rb +119 -0
- data/lib/omf_rete/store/predicate_store.rb +96 -0
- data/lib/omf_rete/store.rb +58 -13
- data/lib/omf_rete/tuple.rb +53 -0
- data/lib/omf_rete/tuple_stream.rb +89 -60
- data/lib/omf_rete/version.rb +1 -1
- data/lib/omf_rete.rb +14 -4
- data/omf_rete.gemspec +3 -0
- data/tests/test_filter.rb +1 -1
- data/tests/test_join_op.rb +30 -0
- data/tests/test_named_store.rb +36 -0
- data/tests/test_object_store.rb +150 -0
- data/tests/test_planner.rb +72 -40
- data/tests/test_predicate_store.rb +95 -0
- data/tests/test_readme.rb +66 -0
- data/tests/test_store.rb +56 -0
- metadata +30 -5
- data/lib/omf_rete/store/alpha/alpha_store.rb +0 -197
@@ -1,197 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'omf_rete/store/alpha/alpha_inner_element'
|
3
|
-
require 'omf_rete/store/alpha/alpha_leaf_element'
|
4
|
-
|
5
|
-
module OMF::Rete::Store::Alpha
|
6
|
-
|
7
|
-
# Module internal class, will only be instantiated by +Store+
|
8
|
-
#
|
9
|
-
class AlphaElement
|
10
|
-
|
11
|
-
def self.create(level, length)
|
12
|
-
rem = length - level
|
13
|
-
if (rem > 1)
|
14
|
-
AlphaInnerElement.new(level, length)
|
15
|
-
else
|
16
|
-
AlphaLeafElement.new(level)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def initialize(level)
|
21
|
-
@level = level
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
class AlphaInnerElement < AlphaElement
|
27
|
-
|
28
|
-
def initialize(level, length)
|
29
|
-
super(level)
|
30
|
-
@length = length
|
31
|
-
@children = {}
|
32
|
-
if (level < length)
|
33
|
-
@wildChild = AlphaElement.create(level + 1, length)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# see Store
|
38
|
-
#
|
39
|
-
def registerTSet(tset, pattern)
|
40
|
-
pitem = pattern[@level]
|
41
|
-
if (pitem) # not nil
|
42
|
-
child = (@children[pitem] ||= AlphaElement.create(@level + 1, @length))
|
43
|
-
child.registerTSet(tset, pattern)
|
44
|
-
else # wildcard
|
45
|
-
@wildChild.registerTSet(tset, pattern)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
|
50
|
-
def addTuple(tarray)
|
51
|
-
el = tarray[@level]
|
52
|
-
if (child = @children[el])
|
53
|
-
child.addTuple(tarray)
|
54
|
-
end
|
55
|
-
@wildChild.addTuple(tarray) if (@wildChild)
|
56
|
-
end
|
57
|
-
end # AlphaInnerElement
|
58
|
-
|
59
|
-
# Module internal class, will only be instantiated by +Store+
|
60
|
-
#
|
61
|
-
class AlphaLeafElement < AlphaElement
|
62
|
-
|
63
|
-
def initialize(level)
|
64
|
-
super
|
65
|
-
@tsetIndex = {}
|
66
|
-
@tsetWildcards = []
|
67
|
-
end
|
68
|
-
|
69
|
-
# see Store
|
70
|
-
#
|
71
|
-
def registerTSet(tset, pattern)
|
72
|
-
pitem = pattern[@level]
|
73
|
-
leaf = (@level == @length)
|
74
|
-
if (pitem) # not nil
|
75
|
-
(@tsetIndex[pitem] ||= []) << tset
|
76
|
-
else # wildcard
|
77
|
-
@tsetWildcards << tset
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def addTuple(tarray)
|
82
|
-
# check if we have any matching tsets
|
83
|
-
item = tarray[@level]
|
84
|
-
if (arr = @tsetIndex[item])
|
85
|
-
arr.each do |s|
|
86
|
-
s.addTuple(tarray)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
@tsetWildcards.each do |s|
|
90
|
-
s.addTuple(tarray)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end # AlphaLeafElement
|
97
|
-
|
98
|
-
#
|
99
|
-
# Class to store tuples for use in MoanaFilter
|
100
|
-
#
|
101
|
-
class Store #< MObject
|
102
|
-
include OMF::Rete::Store
|
103
|
-
|
104
|
-
attr_reader :length
|
105
|
-
|
106
|
-
# Initialize a tuple store for tuples of
|
107
|
-
# fixed length +length+.
|
108
|
-
#
|
109
|
-
def initialize(length, opts = {})
|
110
|
-
@length = length
|
111
|
-
@root = AlphaInnerElement.new(0, length)
|
112
|
-
@index = []
|
113
|
-
length.times do @index << {} end
|
114
|
-
end
|
115
|
-
|
116
|
-
def query(queryPattern, projectPattern = nil, &block)
|
117
|
-
pb = PlanBuilder.new(queryPattern, self)
|
118
|
-
pb.build
|
119
|
-
pb.materialize(projectPattern, &block)
|
120
|
-
end
|
121
|
-
|
122
|
-
# Register a +TSet+ and add all tuples currently
|
123
|
-
# and in the future matching +pattern+
|
124
|
-
#
|
125
|
-
def registerTSet(tset, pattern)
|
126
|
-
pat = pattern.collect do |el|
|
127
|
-
(el.is_a?(Symbol) && el.to_s.end_with?('?')) ? nil : el
|
128
|
-
end
|
129
|
-
@root.registerTSet(tset, pat)
|
130
|
-
# seed tset which already stored data
|
131
|
-
find(pattern).each do |t|
|
132
|
-
tset.addTuple(t)
|
133
|
-
end
|
134
|
-
tset
|
135
|
-
end
|
136
|
-
|
137
|
-
def createTSet(description, indexPattern)
|
138
|
-
tset = Moana::Filter::IndexedTupleSet.new(description, indexPattern)
|
139
|
-
registerTSet(tset, description)
|
140
|
-
tset
|
141
|
-
end
|
142
|
-
|
143
|
-
def addTuple(tarray)
|
144
|
-
@length.times do |i|
|
145
|
-
item = tarray[i]
|
146
|
-
ia = @index[i][item] ||= Set.new
|
147
|
-
unless ia.add?(tarray)
|
148
|
-
return # this is a duplicate
|
149
|
-
end
|
150
|
-
end
|
151
|
-
@root.addTuple(tarray)
|
152
|
-
end
|
153
|
-
|
154
|
-
# Return a set of tuples which match +pattern+. Pattern is
|
155
|
-
# a tuples of the same length this store is configured for
|
156
|
-
# where any non-nil element is matched directly and any
|
157
|
-
# nil element is considered a wildcard.
|
158
|
-
#
|
159
|
-
def find(pattern)
|
160
|
-
seta = []
|
161
|
-
allWildcards = true
|
162
|
-
@length.times do |i|
|
163
|
-
if (item = pattern[i])
|
164
|
-
allWildcards = false
|
165
|
-
res = @index[i][item]
|
166
|
-
#puts "res: index #{i}, res: #{res.inspect}"
|
167
|
-
seta << res if res # only add if non-nil
|
168
|
-
end
|
169
|
-
end
|
170
|
-
if (allWildcards)
|
171
|
-
res = Set.new
|
172
|
-
@index[0].each_value do |s|
|
173
|
-
res.merge(s)
|
174
|
-
end
|
175
|
-
return res
|
176
|
-
end
|
177
|
-
# get intersection of all returned sets
|
178
|
-
if (seta.empty?)
|
179
|
-
return Set.new
|
180
|
-
end
|
181
|
-
res = nil
|
182
|
-
seta.each do |s|
|
183
|
-
if res
|
184
|
-
res = res.intersection(s)
|
185
|
-
else
|
186
|
-
res = s
|
187
|
-
end
|
188
|
-
#puts "merge: in: #{s.inspect}, res: #{res.inspect}"
|
189
|
-
end
|
190
|
-
return res
|
191
|
-
end
|
192
|
-
|
193
|
-
def to_s()
|
194
|
-
"Store"
|
195
|
-
end
|
196
|
-
end # Store
|
197
|
-
end # Moana
|