factbase 0.15.5 → 0.15.6
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.
- checksums.yaml +4 -4
- data/README.md +26 -26
- data/lib/factbase/indexed/indexed_term.rb +7 -27
- data/lib/factbase/terms/ordering.rb +1 -21
- data/lib/factbase/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d348b6ea04ba59f16e1a92c3769cb3139395507e60f1bdb3df1aef182cd8f8c0
|
4
|
+
data.tar.gz: cc5c09f1ae7c7d35766f3b9083894b0785470831c886fe5e620669150a0bf689
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a720744b99cedd9d8360a1e485078091aae144dbaaa3a7f28b006e39df3269890db9043c6177614c33adfca7dec59c2042dcc7369fc68cc62ab0b182a0bbc18
|
7
|
+
data.tar.gz: 027f5ac0993655496b93db5e2d38f33288823608b8935e185ad1b0b186a3b308d0be3ba319abba5a3be119667fa69ee2e7be50643e6b5733517572ad864ea736
|
data/README.md
CHANGED
@@ -204,35 +204,35 @@ This is the result of the benchmark:
|
|
204
204
|
<!-- benchmark_begin -->
|
205
205
|
```text
|
206
206
|
user
|
207
|
-
insert 20000 facts 0.
|
208
|
-
export 20000 facts 0.
|
209
|
-
import
|
210
|
-
insert 10 facts 0.
|
211
|
-
query 10 times w/txn 2.
|
212
|
-
query 10 times w/o txn 0.
|
213
|
-
modify 10 attrs w/txn
|
214
|
-
delete 10 facts w/txn 1.
|
215
|
-
(and (eq what 'issue-was-closed') (exists... -> 200
|
216
|
-
(and (eq what 'issue-was-closed') (exists... -> 200/txn 1.
|
217
|
-
(and (eq what 'issue-was-closed') (exists... -> zero
|
218
|
-
(and (eq what 'issue-was-closed') (exists... -> zero/txn 1.
|
219
|
-
(gt time '2024-03-23T03:21:43Z') 0.
|
220
|
-
(gt cost 50) 0.
|
221
|
-
(eq title 'Object Thinking 5000') 0.
|
222
|
-
(and (eq foo 42.998) (or (gt bar 200) (absent z... 0.
|
223
|
-
(and (exists foo) (not (exists blue))) 0.
|
224
|
-
(eq id (agg (always) (max id))) 0.
|
225
|
-
(join "c<=cost,b<=bar" (eq id (agg (always) (ma... 1.
|
226
|
-
(and (eq what "foo") (join "w<=what" (and (eq i...
|
227
|
-
delete! 0.
|
228
|
-
Taped.append() x50000 0.
|
229
|
-
Taped.each() x125 1.
|
230
|
-
Taped.delete_if() x375 0.
|
207
|
+
insert 20000 facts 0.595620
|
208
|
+
export 20000 facts 0.019511
|
209
|
+
import 410903 bytes (20000 facts) 0.021517
|
210
|
+
insert 10 facts 0.039990
|
211
|
+
query 10 times w/txn 2.051662
|
212
|
+
query 10 times w/o txn 0.043900
|
213
|
+
modify 10 attrs w/txn 1.928921
|
214
|
+
delete 10 facts w/txn 1.075461
|
215
|
+
(and (eq what 'issue-was-closed') (exists... -> 200 1.120060
|
216
|
+
(and (eq what 'issue-was-closed') (exists... -> 200/txn 1.114975
|
217
|
+
(and (eq what 'issue-was-closed') (exists... -> zero 1.080422
|
218
|
+
(and (eq what 'issue-was-closed') (exists... -> zero/txn 1.131242
|
219
|
+
(gt time '2024-03-23T03:21:43Z') 0.342271
|
220
|
+
(gt cost 50) 0.188269
|
221
|
+
(eq title 'Object Thinking 5000') 0.089654
|
222
|
+
(and (eq foo 42.998) (or (gt bar 200) (absent z... 0.050858
|
223
|
+
(and (exists foo) (not (exists blue))) 0.920006
|
224
|
+
(eq id (agg (always) (max id))) 0.597035
|
225
|
+
(join "c<=cost,b<=bar" (eq id (agg (always) (ma... 1.319789
|
226
|
+
(and (eq what "foo") (join "w<=what" (and (eq i... 7.039262
|
227
|
+
delete! 0.219260
|
228
|
+
Taped.append() x50000 0.025503
|
229
|
+
Taped.each() x125 1.345823
|
230
|
+
Taped.delete_if() x375 0.818237
|
231
231
|
```
|
232
232
|
|
233
233
|
The results were calculated in [this GHA job][benchmark-gha]
|
234
|
-
on 2025-08-
|
234
|
+
on 2025-08-21 at 14:27,
|
235
235
|
on Linux with 4 CPUs.
|
236
236
|
<!-- benchmark_end -->
|
237
237
|
|
238
|
-
[benchmark-gha]: https://github.com/yegor256/factbase/actions/runs/
|
238
|
+
[benchmark-gha]: https://github.com/yegor256/factbase/actions/runs/17129904396
|
@@ -22,8 +22,6 @@ module Factbase::IndexedTerm
|
|
22
22
|
def predict(maps, params)
|
23
23
|
key = [maps.object_id, @operands.first, @op]
|
24
24
|
case @op
|
25
|
-
when :unique
|
26
|
-
maps
|
27
25
|
when :one
|
28
26
|
if @idx[key].nil?
|
29
27
|
@idx[key] = []
|
@@ -122,8 +120,8 @@ module Factbase::IndexedTerm
|
|
122
120
|
r = nil
|
123
121
|
if @operands.all? { |o| o.op == :eq } && @operands.size > 1 \
|
124
122
|
&& @operands.all? { |o| o.operands.first.is_a?(Symbol) && _scalar?(o.operands[1]) }
|
125
|
-
key = [maps.object_id, @operands.map { |o| o.operands.first }, :multi_eq]
|
126
123
|
props = @operands.map { |o| o.operands.first }.sort
|
124
|
+
key = [maps.object_id, props, :multi_and_eq]
|
127
125
|
if @idx[key].nil?
|
128
126
|
@idx[key] = {}
|
129
127
|
maps.to_a.each do |m|
|
@@ -133,8 +131,8 @@ module Factbase::IndexedTerm
|
|
133
131
|
end
|
134
132
|
end
|
135
133
|
end
|
136
|
-
tuples =
|
137
|
-
|
134
|
+
tuples = Enumerator.product(
|
135
|
+
*@operands.sort_by { |o| o.operands.first }.map do |o|
|
138
136
|
if o.operands[1].is_a?(Symbol)
|
139
137
|
params[o.operands[1].to_s] || []
|
140
138
|
else
|
@@ -147,16 +145,14 @@ module Factbase::IndexedTerm
|
|
147
145
|
else
|
148
146
|
@operands.each do |o|
|
149
147
|
n = o.predict(maps, params)
|
150
|
-
if n.nil?
|
151
|
-
r = maps
|
152
|
-
break
|
153
|
-
end
|
148
|
+
break if n.nil?
|
154
149
|
if r.nil?
|
155
150
|
r = n
|
156
151
|
elsif n.size < r.size * 8 # to skip some obvious matchings
|
157
152
|
r &= n.to_a
|
158
153
|
end
|
159
|
-
break if r.size <
|
154
|
+
break if r.size < maps.size / 32 # it's already small enough
|
155
|
+
break if r.size < 128 # it's obviously already small enough
|
160
156
|
end
|
161
157
|
end
|
162
158
|
r
|
@@ -170,6 +166,7 @@ module Factbase::IndexedTerm
|
|
170
166
|
end
|
171
167
|
r = maps & [] if r.nil?
|
172
168
|
r |= n.to_a
|
169
|
+
return maps if r.size > maps.size / 4 # it's big enough already
|
173
170
|
end
|
174
171
|
r
|
175
172
|
when :not
|
@@ -193,23 +190,6 @@ module Factbase::IndexedTerm
|
|
193
190
|
|
194
191
|
private
|
195
192
|
|
196
|
-
# The input looks like this: [[6, 55], [3], [4, 3, 5]].
|
197
|
-
# The outputh should contain all possible combinations: [[6, 3, 4], [6, 3, 3], [55, 3, 5], ...]
|
198
|
-
def _as_tuples(values)
|
199
|
-
tuples = [values.first]
|
200
|
-
if values.size > 1
|
201
|
-
tails = _as_tuples(values[1..])
|
202
|
-
ext = []
|
203
|
-
tuples.each do |t|
|
204
|
-
tails.each do |tail|
|
205
|
-
ext << (t + tail)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
tuples = ext
|
209
|
-
end
|
210
|
-
tuples
|
211
|
-
end
|
212
|
-
|
213
193
|
def _all_tuples(fact, props)
|
214
194
|
prop = props.first.to_s
|
215
195
|
tuples = []
|
@@ -25,30 +25,10 @@ module Factbase::Ordering
|
|
25
25
|
vv = (0..(@operands.size - 1)).map { |i| _values(i, fact, maps, fb) }
|
26
26
|
return false if vv.any?(nil)
|
27
27
|
pass = true
|
28
|
-
|
28
|
+
Enumerator.product(*vv).to_a.each do |t|
|
29
29
|
pass = false if @seen.include?(t)
|
30
30
|
@seen << t
|
31
31
|
end
|
32
32
|
pass
|
33
33
|
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
# Multiplies arrays and returns a list of all possible combinations
|
38
|
-
# of their elements. If this array is provided:
|
39
|
-
#
|
40
|
-
# [ [4, 3], [2, 88, 13] ]
|
41
|
-
#
|
42
|
-
# This will be the result:
|
43
|
-
#
|
44
|
-
# [ [4, 2], [4, 88], [4, 13], [3, 2], [3, 88], [3, 13]]
|
45
|
-
def _cartesian(vv)
|
46
|
-
ff = vv.first.zip
|
47
|
-
if vv.one?
|
48
|
-
ff
|
49
|
-
else
|
50
|
-
tail = _cartesian(vv[1..])
|
51
|
-
ff.map { |f| tail.map { |t| f + t } }
|
52
|
-
end
|
53
|
-
end
|
54
34
|
end
|
data/lib/factbase/version.rb
CHANGED