/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jena.sparql.engine.iterator; import java.util.Set; import org.apache.jena.sparql.core.Var; import org.apache.jena.sparql.engine.ExecutionContext; import org.apache.jena.sparql.engine.QueryIterator; import org.apache.jena.sparql.engine.binding.Binding; import org.apache.jena.sparql.engine.index.IndexFactory; import org.apache.jena.sparql.engine.index.IndexTable; /** Minus by materializing the RHS - this is not streamed on the right */ public class QueryIterMinus extends QueryIter2 { private final IndexTable tableRight; private Binding slot = null; public static QueryIterator create(QueryIterator left, QueryIterator right, Set<Var> commonVars, ExecutionContext qCxt) { if ( ! right.hasNext() ) // Empty MINUS left return left ; return new QueryIterMinus(left, right, commonVars, qCxt) ; } private QueryIterMinus(QueryIterator left, QueryIterator right, Set<Var> commonVars, ExecutionContext qCxt) { super(left, right, qCxt); tableRight = IndexFactory.createIndex(commonVars, right); } protected Binding getNextSlot(Binding bindingLeft) { if ( tableRight.containsCompatibleWithSharedDomain(bindingLeft) ) return null; return bindingLeft; } @Override protected final void closeSubIterator() {} @Override protected void requestSubCancel() {} @Override protected final boolean hasNextBinding() { if ( slot != null ) return true; while (getLeft().hasNext()) { Binding bindingLeft = getLeft().nextBinding(); slot = getNextSlot(bindingLeft); if ( slot != null ) { slot = bindingLeft; return true; } } getLeft().close(); return false; } @Override protected final Binding moveToNextBinding() { if ( !hasNextBinding() ) return null; Binding x = slot; slot = null; return x; } }