}
@Override
public QueryResult join(final Collection<Indices> indicesC){
try{
QueryResult queryResult = QueryResult.createInstance();
queryResult.add(this.bindingsFactory.createInstance());
// move over the collection of the provided triple patterns
for (final TriplePattern tp : this.triplePatterns) {
final QueryResult zQueryResult = queryResult;
final Iterator<Bindings> itb = new ImmutableIterator<Bindings>() {
Iterator<Bindings> oldBindings = zQueryResult.oneTimeIterator();
Bindings currentBindings = null;
Iterator<Triple> newTriples = null;
Bindings next = null;
@Override
public boolean hasNext() {
if (this.next != null) {
return true;
}
this.next = this.computeNext();
return (this.next != null);
}
@Override
public Bindings next() {
if (this.next != null) {
final Bindings znext = this.next;
this.next = null;
return znext;
}
return this.computeNext();
}
public Bindings computeNext() {
while ((this.newTriples == null || !this.newTriples.hasNext()) && this.oldBindings.hasNext()) {
this.retrieveNewTriples();
}
if (this.newTriples == null || !this.newTriples.hasNext()) {
return null;
}
final Triple triple = this.newTriples.next();
final Bindings cB = this.currentBindings.clone();
for (int i = 0; i < 3; i++) {
if (tp.getPos(i).isVariable()) {
final Literal l = cB.get((Variable) tp.getPos(i));
if (l != null) {
if (!triple.getPos(i).equals(l)) {
return this.computeNext();
}
} else {
cB.add((Variable) tp.getPos(i), triple.getPos(i));
}
}
}
cB.addTriple(triple);
return cB;
}
private void retrieveNewTriples() {
this.currentBindings = this.oldBindings.next();
final StringBuffer key = new StringBuffer();
int mapPattern = MAP_PATTERN.NONE.ordinal();
// compute a key which is as restrictive as possible
// to cut down the amount of triple pattern which
// have
// to be processed to produce the result
if (MemoryIndexScan.this.computeKey4Maps(this.currentBindings, key, tp.getPos(0))) {
mapPattern += MAP_PATTERN.SMAP.ordinal();
}
if (MemoryIndexScan.this.computeKey4Maps(this.currentBindings, key, tp.getPos(1))) {
mapPattern += MAP_PATTERN.PMAP.ordinal();
}
if (MemoryIndexScan.this.computeKey4Maps(this.currentBindings, key, tp.getPos(2))) {
mapPattern += MAP_PATTERN.OMAP.ordinal();
}
this.newTriples = MemoryIndexScan.this.getFromMap(MAP_PATTERN.values()[mapPattern], key.toString(), indicesC);
}
};
// use a "fresh" object to gather the result of the join
// operation
// when using the current triple pattern and the previous query
// results
final QueryResult qresult = QueryResult.createInstance(itb);
// replace the previous query results with the new ones
queryResult.release();
queryResult = qresult;
}