Skip to content

Commit 6363274

Browse files
committed
fastest yet, with codegen
1 parent 9f0d330 commit 6363274

14 files changed

Lines changed: 917 additions & 30 deletions

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

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import java.util.HashMap;
1515
import java.util.IdentityHashMap;
16+
import java.util.List;
1617
import java.util.Map;
1718
import java.util.function.BiConsumer;
1819

@@ -28,6 +29,8 @@ public final class LmdbLftjBindingState {
2829
private final BindingSet inputBindings;
2930
private final LmdbQueryAccess queryAccess;
3031
private final String[] variableNames;
32+
private final String[] outputNames;
33+
private final int[] outputSlots;
3134
private final Map<String, Integer> variableSlots = new HashMap<>();
3235
private final long[] fixedValues;
3336
private final boolean[] fixedPresent;
@@ -52,6 +55,19 @@ public final class LmdbLftjBindingState {
5255
for (int i = 0; i < variableCount; i++) {
5356
variableSlots.put(variableNames[i], i);
5457
}
58+
List<LmdbLftjPlan.OutputBinding> outputBindings = plan.outputBindings();
59+
this.outputNames = new String[outputBindings.size()];
60+
this.outputSlots = new int[outputBindings.size()];
61+
for (int i = 0; i < outputBindings.size(); i++) {
62+
LmdbLftjPlan.OutputBinding outputBinding = outputBindings.get(i);
63+
Integer slot = variableSlots.get(outputBinding.sourceVariable());
64+
if (slot == null) {
65+
throw new IllegalArgumentException(
66+
"Unknown LMDB LFTJ output source variable: " + outputBinding.sourceVariable());
67+
}
68+
outputNames[i] = outputBinding.outputName();
69+
outputSlots[i] = slot;
70+
}
5571
}
5672

5773
public boolean initialize() {
@@ -150,9 +166,10 @@ long fixedId(LmdbLftjPatternPlan.TermRef term) {
150166
public BindingSet materialize(QueryEvaluationContext context) {
151167
MutableBindingSet result = context.createBindingSet(inputBindings);
152168
BiConsumer<Value, MutableBindingSet>[] setters = bindingSetters(context);
153-
for (int slot = 0; slot < variableNames.length; slot++) {
154-
if (assignedPresent[slot]) {
155-
setters[slot].accept(queryAccess.resolveValue(assignedValues[slot]), result);
169+
for (int outputIndex = 0; outputIndex < outputSlots.length; outputIndex++) {
170+
int slot = outputSlots[outputIndex];
171+
if (isBound(slot)) {
172+
setters[outputIndex].accept(queryAccess.lazyValue(value(slot)), result);
156173
}
157174
}
158175
return result;
@@ -182,9 +199,9 @@ private BiConsumer<Value, MutableBindingSet>[] bindingSetters(QueryEvaluationCon
182199
if (bindingSetters != null && bindingSettersContext == context) {
183200
return bindingSetters;
184201
}
185-
BiConsumer<Value, MutableBindingSet>[] setters = new BiConsumer[variableNames.length];
186-
for (int slot = 0; slot < variableNames.length; slot++) {
187-
setters[slot] = context.setBinding(variableNames[slot]);
202+
BiConsumer<Value, MutableBindingSet>[] setters = new BiConsumer[outputNames.length];
203+
for (int outputIndex = 0; outputIndex < outputNames.length; outputIndex++) {
204+
setters[outputIndex] = context.setBinding(outputNames[outputIndex]);
188205
}
189206
bindingSetters = setters;
190207
bindingSettersContext = context;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
public final class LmdbLftjExecutionShape {
2121

22-
private static final int FULL_STACK_TEMPLATE_VERSION = 3;
22+
private static final int FULL_STACK_TEMPLATE_VERSION = 4;
2323

2424
private final int variableCount;
2525
private final int[][] cursorOrdinalsBySlot;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ protected void handleClose() {
157157
private BindingSet computeNextElement() {
158158
while (depth >= 0) {
159159
if (depth == searchSlots.length) {
160+
if (!passesInequalityConstraints(plan, state)) {
161+
backtrackAfterLeaf();
162+
continue;
163+
}
160164
long multiplicity = witnessMultiplicity(plan, metrics, frontierProvider);
161165
backtrackAfterLeaf();
162166
if (multiplicity > 0) {
@@ -258,6 +262,15 @@ private void releaseDepth(int depth) {
258262
}
259263
}
260264

265+
private static boolean passesInequalityConstraints(LmdbLftjPlan plan, LmdbLftjBindingState state) {
266+
for (LmdbLftjPlan.InequalityConstraint inequality : plan.inequalityConstraints()) {
267+
if (state.value(inequality.leftVariable()) == state.value(inequality.rightVariable())) {
268+
return false;
269+
}
270+
}
271+
return true;
272+
}
273+
261274
private int[] collectSearchSlots(LmdbLftjPlan plan, LmdbLftjBindingState state) {
262275
int[] searchSlots = new int[plan.variableOrder().size()];
263276
int count = 0;

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ private void appendComputeNextElement(StringBuilder source, int variableCount) {
318318
source.append(" protected BindingSet computeNextElement() {\n");
319319
source.append(" while (depth >= 0) {\n");
320320
source.append(" if (depth == ").append(variableCount).append(") {\n");
321+
source.append(" if (!passesInequalityConstraints()) {\n");
322+
source.append(" backtrackAfterLeaf();\n");
323+
source.append(" continue;\n");
324+
source.append(" }\n");
321325
source.append(" long multiplicity = 1L;\n");
322326
for (int patternOrdinal = 0; patternOrdinal < shape.patternCount(); patternOrdinal++) {
323327
source.append(" long witnesses")
@@ -1214,6 +1218,7 @@ private void appendHelpers(StringBuilder source) {
12141218
source.append(" throw new SailException(e);\n");
12151219
source.append(" }\n");
12161220
source.append(" }\n\n");
1221+
appendInequalityHelper(source);
12171222
for (int patternOrdinal = 0; patternOrdinal < shape.patternCount(); patternOrdinal++) {
12181223
LmdbLftjExecutionShape.PatternShape patternShape = shape.pattern(patternOrdinal);
12191224
if (patternShape.derivedBinaryRelation()) {
@@ -1227,6 +1232,28 @@ private void appendHelpers(StringBuilder source) {
12271232
}
12281233
}
12291234

1235+
private void appendInequalityHelper(StringBuilder source) {
1236+
source.append(" private boolean passesInequalityConstraints() {\n");
1237+
if (plan.inequalityConstraints().isEmpty()) {
1238+
source.append(" return true;\n");
1239+
} 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(")
1247+
.append(variableSlot(inequality.leftVariable()))
1248+
.append(") != state().value(")
1249+
.append(variableSlot(inequality.rightVariable()))
1250+
.append(')');
1251+
}
1252+
source.append(";\n");
1253+
}
1254+
source.append(" }\n\n");
1255+
}
1256+
12301257
private void appendCursorRowHelpers(StringBuilder source, int patternOrdinal, int slot,
12311258
LmdbLftjExecutionShape.PatternShape patternShape) {
12321259
String suffix = slotSuffix(patternOrdinal, slot);
@@ -1393,6 +1420,14 @@ private String slotSuffix(int patternOrdinal, int slot) {
13931420
return "P" + patternOrdinal + (slot >= 0 ? "S" + slot : "W");
13941421
}
13951422

1423+
private int variableSlot(String variableName) {
1424+
int slot = plan.variableOrder().indexOf(variableName);
1425+
if (slot < 0) {
1426+
throw new IllegalArgumentException("Unknown LMDB LFTJ variable in full-stack codegen: " + variableName);
1427+
}
1428+
return slot;
1429+
}
1430+
13961431
private String componentAccessor(int patternOrdinal, int slot, String kind, int component) {
13971432
return componentFieldName(component) + slotSuffix(patternOrdinal, slot) + kind;
13981433
}

0 commit comments

Comments
 (0)