-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gh 5121 fedx bind left join #5122
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Eclipse RDF4J contributors. | ||
* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Distribution License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.php. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*******************************************************************************/ | ||
package org.eclipse.rdf4j.federated.evaluation.iterator; | ||
|
||
import java.util.HashSet; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.ListIterator; | ||
import java.util.Set; | ||
|
||
import org.eclipse.rdf4j.common.iteration.CloseableIteration; | ||
import org.eclipse.rdf4j.common.iteration.LookAheadIteration; | ||
import org.eclipse.rdf4j.query.Binding; | ||
import org.eclipse.rdf4j.query.BindingSet; | ||
import org.eclipse.rdf4j.query.QueryEvaluationException; | ||
import org.eclipse.rdf4j.query.algebra.evaluation.QueryBindingSet; | ||
|
||
/** | ||
* A {@link LookAheadIteration} for processing bind left join results. | ||
* | ||
* Algorithm: | ||
* | ||
* <ul> | ||
* <li>execute left bind join using regular bound join query</li> | ||
* <li>process result iteration similar to {@link BoundJoinVALUESConversionIteration}</li> | ||
* <li>remember seen set of bindings (using index) and add original bindings to those, i.e. put to result return all | ||
* non-seen bindings directly from the input</li> | ||
* | ||
* | ||
* @author Andreas Schwarte | ||
*/ | ||
public class BindLeftJoinIteration extends LookAheadIteration<BindingSet> { | ||
|
||
protected final CloseableIteration<BindingSet> iter; | ||
protected final List<BindingSet> bindings; | ||
|
||
protected Set<Integer> seenBindingIndexes = new HashSet<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would the IntHashSet be appropriate here? |
||
protected final ListIterator<BindingSet> bindingsIterator; | ||
|
||
public BindLeftJoinIteration(CloseableIteration<BindingSet> iter, | ||
List<BindingSet> bindings) { | ||
this.iter = iter; | ||
this.bindings = bindings; | ||
this.bindingsIterator = bindings.listIterator(); | ||
} | ||
|
||
@Override | ||
protected BindingSet getNextElement() { | ||
|
||
if (iter.hasNext()) { | ||
var bIn = iter.next(); | ||
int bIndex = Integer.parseInt( | ||
bIn.getBinding(BoundJoinVALUESConversionIteration.INDEX_BINDING_NAME).getValue().stringValue()); | ||
Comment on lines
+60
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the binding Value object ever a literal? So it would be possible to check if it's instanceof IntegerLiteral or something like that? |
||
seenBindingIndexes.add(bIndex); | ||
return convert(bIn, bIndex); | ||
} | ||
|
||
while (bindingsIterator.hasNext()) { | ||
if (seenBindingIndexes.contains(bindingsIterator.nextIndex())) { | ||
// the binding was already processed as part of the optional | ||
bindingsIterator.next(); | ||
continue; | ||
} | ||
return bindingsIterator.next(); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@Override | ||
protected void handleClose() { | ||
iter.close(); | ||
} | ||
|
||
protected BindingSet convert(BindingSet bIn, int bIndex) throws QueryEvaluationException { | ||
QueryBindingSet res = new QueryBindingSet(); | ||
Iterator<Binding> bIter = bIn.iterator(); | ||
while (bIter.hasNext()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be a for-each look?
|
||
Binding b = bIter.next(); | ||
if (b.getName().equals(BoundJoinVALUESConversionIteration.INDEX_BINDING_NAME)) { | ||
continue; | ||
} | ||
res.addBinding(b); | ||
} | ||
for (Binding bs : bindings.get(bIndex)) { | ||
res.setBinding(bs); | ||
} | ||
return res; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add that this is used for OPTIONAL clauses. Is it used for anything else?