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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74b612e25e2049c5a9ca7479d32109671f31418cbc9a2d82585477ff49b5727b
4
- data.tar.gz: '094ed4fe01c04634069850d2761f3c8d4b84843cc1888a8682c9d2c4582feded'
3
+ metadata.gz: d348b6ea04ba59f16e1a92c3769cb3139395507e60f1bdb3df1aef182cd8f8c0
4
+ data.tar.gz: cc5c09f1ae7c7d35766f3b9083894b0785470831c886fe5e620669150a0bf689
5
5
  SHA512:
6
- metadata.gz: ad57f438328d323dcaf6127795952a6594a7d5eb65923a248d38f2824ebf00f709bf1e2c0cb60d108737c4fc94d43357c929f3d5009dac2557f9da56ed13936f
7
- data.tar.gz: 5ec7f708d55964e836b014d714f462647ee3fe29326e5ba29b4ef609a507fd238a483d580c29cd73074a53f14f09b58554a5db36d36193abe01458b2af340404
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.638553
208
- export 20000 facts 0.027273
209
- import 410717 bytes (20000 facts) 0.021643
210
- insert 10 facts 0.042390
211
- query 10 times w/txn 2.278994
212
- query 10 times w/o txn 0.037285
213
- modify 10 attrs w/txn 2.261902
214
- delete 10 facts w/txn 1.205367
215
- (and (eq what 'issue-was-closed') (exists... -> 200 2.092734
216
- (and (eq what 'issue-was-closed') (exists... -> 200/txn 1.032410
217
- (and (eq what 'issue-was-closed') (exists... -> zero 2.385969
218
- (and (eq what 'issue-was-closed') (exists... -> zero/txn 1.190590
219
- (gt time '2024-03-23T03:21:43Z') 0.321057
220
- (gt cost 50) 0.210374
221
- (eq title 'Object Thinking 5000') 0.055549
222
- (and (eq foo 42.998) (or (gt bar 200) (absent z... 0.049508
223
- (and (exists foo) (not (exists blue))) 0.999753
224
- (eq id (agg (always) (max id))) 0.627528
225
- (join "c<=cost,b<=bar" (eq id (agg (always) (ma... 1.246746
226
- (and (eq what "foo") (join "w<=what" (and (eq i... 6.881145
227
- delete! 0.174194
228
- Taped.append() x50000 0.023669
229
- Taped.each() x125 1.423781
230
- Taped.delete_if() x375 0.843940
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-09 at 06:42,
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/16846550540
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 = _as_tuples(
137
- @operands.sort_by { |o| o.operands.first }.map do |o|
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 < 512
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
- _cartesian(vv).each do |t|
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
@@ -9,5 +9,5 @@
9
9
  # License:: MIT
10
10
  class Factbase
11
11
  # Current version of the gem (changed by .rultor.yml on every release)
12
- VERSION = '0.15.5' unless const_defined?(:VERSION)
12
+ VERSION = '0.15.6' unless const_defined?(:VERSION)
13
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.5
4
+ version: 0.15.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko