Skip to content

Commit 6366d90

Browse files
committed
Invert costs in Pattern, as it ends up that favoring objects before subjects is much more expensive.
1 parent 17f3431 commit 6366d90

2 files changed

Lines changed: 22 additions & 22 deletions

File tree

lib/rdf/query/pattern.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ def initialize!
5050

5151
# Estmate cost positionally, with variables being least expensive as objects, then predicates, then subjects, then graph_names.
5252
# XXX does not consider bound variables, which would need to be dynamically calculated.
53-
@cost = (@object.nil? || @object.is_a?(Variable) ? 1 : 0) +
54-
(@predicate.nil? || @predicate.is_a?(Variable) ? 2 : 0) +
55-
(@subject.nil? || @subject.is_a?(Variable) ? 4 : 0) +
56-
(@graph_name.is_a?(Variable) ? 8 : 0) +
57-
(@object.is_a?(Pattern) ? @object.cost : 0) +
58-
(@subject.is_a?(Pattern) ? (@subject.cost + 4) : 0)
53+
@cost = (@object.nil? || @object.is_a?(Variable) ? 8 : 0) +
54+
(@predicate.nil? || @predicate.is_a?(Variable) ? 4 : 0) +
55+
(@subject.nil? || @subject.is_a?(Variable) ? 2 : 0) +
56+
(@graph_name.is_a?(Variable) ? 1 : 0) +
57+
(@object.is_a?(Pattern) ? (@object.cost * 4) : 0) +
58+
(@subject.is_a?(Pattern) ? (@subject.cost * 2) : 0)
5959
super
6060
end
6161

spec/query_pattern_spec.rb

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
end
2424
end
2525

26-
its(:cost) {is_expected.to be (4+2+1)}
26+
its(:cost) {is_expected.to be (2+4+8)}
2727

2828
it "should not have variables" do
2929
expect(subject.variables?).to be_falsey
@@ -59,7 +59,7 @@
5959
specify {is_expected.to be_variable}
6060
specify {is_expected.to be_bound}
6161

62-
its(:cost) {is_expected.to be (4+2+1)}
62+
its(:cost) {is_expected.to be (2+4+8)}
6363

6464
it "should have one variable" do
6565
expect(subject).to be_variables
@@ -99,7 +99,7 @@
9999
specify {is_expected.to be_variable}
100100
specify {is_expected.to be_bound}
101101

102-
its(:cost) {is_expected.to be (4+2+1)}
102+
its(:cost) {is_expected.to be (2+4+8)}
103103

104104
it "should have three variables" do
105105
expect(subject).to be_variables
@@ -132,10 +132,10 @@
132132
context "with variable in different locations" do
133133
{
134134
"spog": [[RDF::URI("s"), RDF::URI("p"), RDF::URI("o"), graph_name: RDF::URI("g")], 0],
135-
"spo?": [[RDF::URI("s"), RDF::URI("p"), RDF::URI("o"), graph_name: :g], 8],
136-
"sp?g": [[RDF::URI("s"), RDF::URI("p"), :o, graph_name: RDF::URI("g")], 1],
137-
"s?og": [[RDF::URI("s"), :p, RDF::URI("o"), graph_name: RDF::URI("g")], 2],
138-
"?pog": [[:s, RDF::URI("p"), RDF::URI("o"), graph_name: RDF::URI("g")], 4],
135+
"spo?": [[RDF::URI("s"), RDF::URI("p"), RDF::URI("o"), graph_name: :g], 1],
136+
"sp?g": [[RDF::URI("s"), RDF::URI("p"), :o, graph_name: RDF::URI("g")], 8],
137+
"s?og": [[RDF::URI("s"), :p, RDF::URI("o"), graph_name: RDF::URI("g")], 4],
138+
"?pog": [[:s, RDF::URI("p"), RDF::URI("o"), graph_name: RDF::URI("g")], 2],
139139
}.each do |name, (args, cost)|
140140
it "cost for #{name} should be #{cost}" do
141141
pattern = described_class.new(*args)
@@ -146,7 +146,7 @@
146146

147147
context "#cost" do
148148
it "can be set separately" do
149-
expect(subject.cost).to be (4+2+1)
149+
expect(subject.cost).to be (2+4+8)
150150
subject.cost = 0
151151
expect(subject.cost).to be 0
152152
end
@@ -162,12 +162,12 @@
162162
expect(subject.graph_name).to eq RDF::Query::Variable.new(:c)
163163
end
164164

165-
its(:cost) {is_expected.to be (8+4+2+1)}
165+
its(:cost) {is_expected.to be (1+2+4+8)}
166166

167167
it "uses a constant for :default" do
168168
pattern = described_class.new(s, p, o, graph_name: false)
169169
expect(pattern.graph_name).to eq false
170-
expect(pattern.cost).to eq (4+2+1)
170+
expect(pattern.cost).to eq (2+4+8)
171171
end
172172
end
173173

@@ -181,7 +181,7 @@
181181
specify {is_expected.to be_variable}
182182
specify {is_expected.not_to be_bound}
183183

184-
its(:cost) {is_expected.to be (4+2+1)}
184+
its(:cost) {is_expected.to be (2+4+8)}
185185

186186
describe "#bind" do
187187
context "complete solution" do
@@ -236,7 +236,7 @@
236236
specify {is_expected.to be_variable}
237237
specify {is_expected.not_to be_bound}
238238

239-
its(:cost) {is_expected.to be (4+2+1)}
239+
its(:cost) {is_expected.to be (2+4+8)}
240240

241241
it "should have two variable" do
242242
expect(subject).to be_variables
@@ -275,7 +275,7 @@
275275
let(:pattern) {described_class.new(s, p, o)}
276276
subject {described_class.new(pattern, RDF::URI("ex:p"), "o")}
277277

278-
its(:cost) {is_expected.to be (4+2+1+4)}
278+
its(:cost) {is_expected.to be ((2+4+8)*2)}
279279

280280
specify {is_expected.not_to be_constant}
281281
specify {is_expected.to be_variable}
@@ -349,7 +349,7 @@
349349
context "with constant subject pattern" do
350350
let(:pattern) {described_class.new(RDF::URI("ex:s"), RDF::URI("ex:p"), "o")}
351351
let(:subject) {described_class.new(pattern, p, o)}
352-
its(:cost) {is_expected.to be (4+2+1)}
352+
its(:cost) {is_expected.to be (4+8)}
353353

354354
specify {is_expected.not_to be_constant}
355355
specify {is_expected.to be_variable}
@@ -370,7 +370,7 @@
370370
context "with variable object pattern" do
371371
let(:pattern) {described_class.new(s, p, o)}
372372
let(:subject) {described_class.new(RDF::URI("ex:s"), RDF::URI("ex:p"), pattern)}
373-
its(:cost) {is_expected.to be (4+2+1)}
373+
its(:cost) {is_expected.to be ((2+4+8)*4)}
374374

375375
specify {is_expected.not_to be_constant}
376376
specify {is_expected.to be_variable}
@@ -443,7 +443,7 @@
443443
context "with constant object pattern" do
444444
let(:pattern) {described_class.new(RDF::URI("ex:s1"), RDF::URI("ex:p1"), "o1")}
445445
let(:subject) {described_class.new(s, p, pattern)}
446-
its(:cost) {is_expected.to be (4+2)}
446+
its(:cost) {is_expected.to be (2+4)}
447447

448448
specify {is_expected.not_to be_constant}
449449
specify {is_expected.to be_variable}

0 commit comments

Comments
 (0)