@Override public QueryResult process(final QueryResult bindings, final int operandID) { if (operandID < this.operandResults.length) { this.operandResults[operandID] = bindings; } else System.err.println( "NAryMergeJoin is a " + this.operandResults.length + "-ary operator, but received the operand number " + operandID); boolean go = true; for (int i = 0; i < this.operandResults.length; i++) { if (this.operandResults[i] == null) { go = false; break; } } if (go) { this.comp.setVariables(this.intersectionVariables); if (this.minimum == null) return null; @SuppressWarnings("unchecked") final Iterator<Bindings>[] itb = new Iterator[this.operandResults.length]; for (int i = 0; i < this.operandResults.length; i++) { itb[i] = this.operandResults[i].oneTimeIterator(); } final ParallelIterator<Bindings> currentResult = (this.intersectionVariables.size() == 0) ? MergeJoin.cartesianProductIterator(this.operandResults) : MergeJoin.mergeJoinIterator( itb, this.comp, this.intersectionVariables, this.minimum, this.maximum); if (currentResult != null && currentResult.hasNext()) { final QueryResult result = QueryResult.createInstance( new SIPParallelIterator<Bindings, Bindings>() { int number = 0; @Override public void close() { currentResult.close(); } @Override public boolean hasNext() { if (!currentResult.hasNext()) { NAryMergeJoinWithoutSorting.this.realCardinality = this.number; close(); } return currentResult.hasNext(); } @Override public Bindings next() { final Bindings b = currentResult.next(); if (b != null) this.number++; if (!currentResult.hasNext()) { NAryMergeJoinWithoutSorting.this.realCardinality = this.number; close(); } return b; } public Bindings getNext(final Bindings k) { @SuppressWarnings("unchecked") final Bindings b = ((SIPParallelIterator<Bindings, Bindings>) currentResult).next(k); if (b != null) this.number++; if (!currentResult.hasNext()) { NAryMergeJoinWithoutSorting.this.realCardinality = this.number; close(); } return b; } @Override public void remove() { currentResult.remove(); } @Override public void finalize() { close(); } @Override public Bindings next(final Bindings k) { if (currentResult instanceof SIPParallelIterator) return getNext(k); else return next(); } }); return result; } else { for (int i = 0; i < this.operandResults.length; i++) { if (this.operandResults[i] != null) { this.operandResults[i].release(); this.operandResults[i] = null; } } return null; } } else { return null; } }
@SuppressWarnings("unchecked") @Override public QueryResult process(final QueryResult bindings, final int operandID) { bindings.materialize(); this.comp.setVariables(this.intersectionVariables); final QueryResult oldLeft = this.left; final QueryResult oldRight = this.right; if (operandID == 0) { if (this.left == null) this.left = bindings; else this.left = QueryResult.createInstance( new MergeIterator<Bindings>(this.comp, this.left.iterator(), bindings.iterator())); } else if (operandID == 1) { if (this.right == null) this.right = bindings; else this.right = QueryResult.createInstance( new MergeIterator<Bindings>(this.comp, this.right.iterator(), bindings.iterator())); } else System.err.println( "MergeJoin is a binary operator, but received the operand number " + operandID); if (this.left != null && this.right != null) { this.left.materialize(); this.right.materialize(); final Iterator<Bindings> leftIterator = (operandID == 0 && oldLeft != null) ? new MinusIterator(bindings.iterator(), oldLeft.iterator()) : this.left.iterator(); final QueryResult rightLocal = (operandID == 1 && oldRight != null) ? QueryResult.createInstance( new MinusIterator(bindings.iterator(), oldRight.iterator())) : this.right; final ParallelIterator<Bindings> currentResult = (this.intersectionVariables.size() == 0) ? MergeJoin.cartesianProductIterator(leftIterator, rightLocal) : MergeJoin.mergeJoinIterator( leftIterator, rightLocal.iterator(), this.comp, this.intersectionVariables); if (currentResult != null && currentResult.hasNext()) { final QueryResult result = QueryResult.createInstance( new ParallelIterator<Bindings>() { int number = 0; @Override public void close() { currentResult.close(); } @Override public boolean hasNext() { if (!currentResult.hasNext()) { MergeJoinWithoutSortingSeveralIterations.this.realCardinality = this.number; close(); } return currentResult.hasNext(); } @Override public Bindings next() { final Bindings b = currentResult.next(); if (!currentResult.hasNext()) { MergeJoinWithoutSortingSeveralIterations.this.realCardinality = this.number; close(); } if (b != null) this.number++; return b; } @Override public void remove() { currentResult.remove(); } @Override public void finalize() { close(); } }); return result; } else { return null; } } else { return null; } }