Skip to content

Commit e110c96

Browse files
committed
more tests and fixes
1 parent 38a8216 commit e110c96

10 files changed

Lines changed: 735 additions & 160 deletions

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/AbstractLmdbFullStackCompiledLftjIteration.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ protected final LmdbLftjPlan plan() {
6868
return plan;
6969
}
7070

71+
protected final LmdbLftjPatternPlan patternPlan(int patternOrdinal) {
72+
return plan.patternPlans().get(patternOrdinal);
73+
}
74+
75+
protected final LmdbDerivedBinaryRelation loadDerivedRelation(int patternOrdinal, long predicateId) {
76+
return LmdbPrefixFrontierProvider.loadDerivedRelation(queryAccess, state.txn(), patternPlan(patternOrdinal),
77+
predicateId);
78+
}
79+
7180
protected final LmdbLftjExecutionShape shape() {
7281
return shape;
7382
}

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbLftjCodegenCompiler.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
// Some portions generated by Codex
1212
package org.eclipse.rdf4j.sail.lmdb;
1313

14+
import java.io.IOException;
15+
import java.nio.file.Files;
16+
import java.nio.file.Path;
1417
import java.util.concurrent.atomic.AtomicLong;
1518

1619
import org.codehaus.janino.SimpleCompiler;
@@ -54,18 +57,30 @@ String sourceFor(LmdbLftjPlan plan, LmdbLftjExecutionShape shape, boolean includ
5457
return sourceFor("GeneratedLmdbLftjSource", plan, shape, includeInferred);
5558
}
5659

60+
Path dumpSourceFor(Path outputFile, LmdbLftjPlan plan, LmdbLftjExecutionShape shape, boolean includeInferred)
61+
throws IOException {
62+
Path parent = outputFile.getParent();
63+
if (parent != null) {
64+
Files.createDirectories(parent);
65+
}
66+
Files.writeString(outputFile, sourceFor(plan, shape, includeInferred));
67+
return outputFile;
68+
}
69+
5770
protected String sourceFor(String simpleClassName, LmdbLftjPlan plan, LmdbLftjExecutionShape shape,
5871
boolean includeInferred) {
59-
return new SourceBuilder(simpleClassName, shape).build();
72+
return new SourceBuilder(simpleClassName, plan, shape).build();
6073
}
6174

6275
protected static final class SourceBuilder {
6376

6477
private final String simpleClassName;
78+
private final LmdbLftjPlan plan;
6579
private final LmdbLftjExecutionShape shape;
6680

67-
private SourceBuilder(String simpleClassName, LmdbLftjExecutionShape shape) {
81+
private SourceBuilder(String simpleClassName, LmdbLftjPlan plan, LmdbLftjExecutionShape shape) {
6882
this.simpleClassName = simpleClassName;
83+
this.plan = plan;
6984
this.shape = shape;
7085
}
7186

@@ -124,6 +139,10 @@ private void appendIterationClass(StringBuilder source) {
124139
source.append(" protected BindingSet computeNextElement() {\n");
125140
source.append(" while (depth >= 0) {\n");
126141
source.append(" if (depth == ").append(variableCount).append(") {\n");
142+
source.append(" if (!passesInequalityConstraints()) {\n");
143+
source.append(" backtrackAfterLeaf();\n");
144+
source.append(" continue;\n");
145+
source.append(" }\n");
127146
source.append(" long multiplicity = 1L;\n");
128147
for (int patternOrdinal = 0; patternOrdinal < shape.patternCount(); patternOrdinal++) {
129148
source.append(" long witnesses")
@@ -163,6 +182,7 @@ private void appendIterationClass(StringBuilder source) {
163182
appendReleaseDepth(source, slot);
164183
appendPositionDepth(source, slot, shape.cursorOrdinals(slot));
165184
}
185+
appendInequalityHelper(source);
166186

167187
source.append(" @Override\n");
168188
source.append(" protected void closeCursors() {\n");
@@ -323,5 +343,32 @@ private void appendPositionDepth(StringBuilder source, int slot, int[] cursorOrd
323343
source.append(" }\n");
324344
source.append(" }\n\n");
325345
}
346+
347+
private void appendInequalityHelper(StringBuilder source) {
348+
source.append(" private boolean passesInequalityConstraints() {\n");
349+
if (plan.inequalityConstraints().isEmpty()) {
350+
source.append(" return true;\n");
351+
} else {
352+
for (LmdbLftjPlan.InequalityConstraint inequality : plan.inequalityConstraints()) {
353+
source.append(" if (state().value(")
354+
.append(variableSlot(inequality.leftVariable()))
355+
.append(") == state().value(")
356+
.append(variableSlot(inequality.rightVariable()))
357+
.append(")) {\n");
358+
source.append(" return false;\n");
359+
source.append(" }\n");
360+
}
361+
source.append(" return true;\n");
362+
}
363+
source.append(" }\n\n");
364+
}
365+
366+
private int variableSlot(String variableName) {
367+
int slot = plan.variableOrder().indexOf(variableName);
368+
if (slot < 0) {
369+
throw new IllegalArgumentException("Unknown variable in inequality constraint: " + variableName);
370+
}
371+
return slot;
372+
}
326373
}
327374
}

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbLftjFullCodegenCompiler.java

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -597,29 +597,16 @@ private void appendRelationGroupAccessor(StringBuilder source, RelationGroup rel
597597
source.append(" return relationGroup").append(relationGroup.groupId).append(";\n");
598598
source.append(" }\n");
599599
source.append(" metrics().recordRelationLoad();\n");
600-
source.append(" LmdbDerivedBinaryRelation.Builder builder = new LmdbDerivedBinaryRelation.Builder(")
601-
.append(sourceComponent)
600+
source.append(" long predicateId = state().fixedIdForComponent(")
601+
.append(patternOrdinal)
602602
.append(", ")
603-
.append(targetComponent)
603+
.append(TripleStore.PRED_IDX)
604604
.append(");\n");
605-
appendWitnessSeek(source, patternOrdinal, patternShape, "0L");
606-
source.append(" while (available").append(slotSuffix(patternOrdinal, -1)).append("Explicit");
607-
if (includeInferred) {
608-
source.append(" || available").append(slotSuffix(patternOrdinal, -1)).append("Inferred");
609-
}
610-
source.append(") {\n");
611-
if (includeInferred) {
612-
appendMergedWitnessRowSelection(source, patternOrdinal, patternShape, true);
613-
} else {
614-
source.append(" builder.add(")
615-
.append(componentAccessor(patternOrdinal, -1, "Explicit", sourceComponent))
616-
.append(", ")
617-
.append(componentAccessor(patternOrdinal, -1, "Explicit", targetComponent))
618-
.append(");\n");
619-
source.append(" advanceWitness").append(patternOrdinal).append("Explicit();\n");
620-
}
621-
source.append(" }\n");
622-
source.append(" relationGroup").append(relationGroup.groupId).append(" = builder.build();\n");
605+
source.append(" relationGroup")
606+
.append(relationGroup.groupId)
607+
.append(" = loadDerivedRelation(")
608+
.append(patternOrdinal)
609+
.append(", predicateId);\n");
623610
source.append(" relationGroup")
624611
.append(relationGroup.groupId)
625612
.append("Scratch.prepare(relationGroup")
@@ -1237,19 +1224,16 @@ private void appendInequalityHelper(StringBuilder source) {
12371224
if (plan.inequalityConstraints().isEmpty()) {
12381225
source.append(" return true;\n");
12391226
} else {
1240-
source.append(" return ");
1241-
for (int i = 0; i < plan.inequalityConstraints().size(); i++) {
1242-
LmdbLftjPlan.InequalityConstraint inequality = plan.inequalityConstraints().get(i);
1243-
if (i > 0) {
1244-
source.append("\n && ");
1245-
}
1246-
source.append("state().value(")
1227+
for (LmdbLftjPlan.InequalityConstraint inequality : plan.inequalityConstraints()) {
1228+
source.append(" if (state().value(")
12471229
.append(variableSlot(inequality.leftVariable()))
1248-
.append(") != state().value(")
1230+
.append(") == state().value(")
12491231
.append(variableSlot(inequality.rightVariable()))
1250-
.append(')');
1232+
.append(")) {\n");
1233+
source.append(" return false;\n");
1234+
source.append(" }\n");
12511235
}
1252-
source.append(";\n");
1236+
source.append(" return true;\n");
12531237
}
12541238
source.append(" }\n\n");
12551239
}

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbPrefixFrontierProvider.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -148,21 +148,27 @@ private LmdbDerivedBinaryRelation relation(LmdbLftjPatternPlan patternPlan) {
148148
}
149149

150150
metrics.recordRelationLoad();
151+
relation = loadDerivedRelation(queryAccess, state.txn(), patternPlan, predicateId);
152+
relationCache.put(lookup.freeze(), relation);
153+
return relation;
154+
}
155+
156+
static LmdbDerivedBinaryRelation loadDerivedRelation(LmdbQueryAccess queryAccess, TxnManager.Txn txn,
157+
LmdbLftjPatternPlan patternPlan, long predicateId) {
151158
int sourceComponent = patternPlan.keyTerm(1).component();
152159
int targetComponent = patternPlan.keyTerm(2).component();
153160
LmdbDerivedBinaryRelation.Builder builder = new LmdbDerivedBinaryRelation.Builder(sourceComponent,
154161
targetComponent);
155-
Arrays.fill(relationLowerBound, 0L);
156-
Arrays.fill(relationUpperBound, Long.MAX_VALUE);
157-
relationLowerBound[TripleStore.PRED_IDX] = predicateId;
158-
relationUpperBound[TripleStore.PRED_IDX] = predicateId;
162+
long[] lowerBound = new long[4];
163+
long[] upperBound = new long[4];
164+
Arrays.fill(upperBound, Long.MAX_VALUE);
165+
lowerBound[TripleStore.PRED_IDX] = predicateId;
166+
upperBound[TripleStore.PRED_IDX] = predicateId;
159167
int sourceKeyField = patternPlan.keyFieldIndexForComponent(sourceComponent);
160168
int targetKeyField = patternPlan.keyFieldIndexForComponent(targetComponent);
161-
forEachUniqueRow(patternPlan, relationLowerBound, relationUpperBound, 1,
169+
forEachUniqueRow(queryAccess, txn, patternPlan, lowerBound, upperBound, 1,
162170
row -> builder.add(row[sourceKeyField], row[targetKeyField]));
163-
relation = builder.build();
164-
relationCache.put(lookup.freeze(), relation);
165-
return relation;
171+
return builder.build();
166172
}
167173

168174
private boolean canUseDerivedRelation(LmdbLftjPatternPlan patternPlan) {
@@ -172,11 +178,17 @@ private boolean canUseDerivedRelation(LmdbLftjPatternPlan patternPlan) {
172178
private void forEachUniqueRow(LmdbLftjPatternPlan patternPlan, long[] lowerBound, long[] upperBound,
173179
int prefixLength,
174180
RowConsumer consumer) {
181+
forEachUniqueRow(queryAccess, state.txn(), patternPlan, lowerBound, upperBound, prefixLength, consumer);
182+
}
183+
184+
private static void forEachUniqueRow(LmdbQueryAccess queryAccess, TxnManager.Txn txn,
185+
LmdbLftjPatternPlan patternPlan, long[] lowerBound, long[] upperBound, int prefixLength,
186+
RowConsumer consumer) {
175187
try (CursorReader explicit = new CursorReader(
176-
queryAccess.openTrieCursor(state.txn(), patternPlan.indexName(), true),
188+
queryAccess.openTrieCursor(txn, patternPlan.indexName(), true),
177189
lowerBound, upperBound, prefixLength);
178190
CursorReader inferred = queryAccess.includeInferred()
179-
? new CursorReader(queryAccess.openTrieCursor(state.txn(), patternPlan.indexName(), false),
191+
? new CursorReader(queryAccess.openTrieCursor(txn, patternPlan.indexName(), false),
180192
lowerBound, upperBound, prefixLength)
181193
: CursorReader.empty()) {
182194
while (explicit.available() || inferred.available()) {
@@ -195,7 +207,7 @@ private void forEachUniqueRow(LmdbLftjPatternPlan patternPlan, long[] lowerBound
195207
}
196208
}
197209

198-
private int compareRows(long[] left, long[] right) {
210+
private static int compareRows(long[] left, long[] right) {
199211
for (int i = 0; i < 4; i++) {
200212
int comparison = Long.compare(left[i], right[i]);
201213
if (comparison != 0) {

0 commit comments

Comments
 (0)