blob: 289bfbac5d642fc6c60f23226a0b972152409906 [file] [log] [blame]
/**
* 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.algebra.optimize ;
import java.util.List ;
import org.apache.jena.sparql.algebra.Op ;
import org.apache.jena.sparql.algebra.TransformCopy ;
import org.apache.jena.sparql.algebra.op.OpBGP ;
import org.apache.jena.sparql.algebra.op.OpJoin ;
import org.apache.jena.sparql.algebra.op.OpSequence ;
import org.apache.jena.sparql.core.BasicPattern ;
/** Merge BGPs
*
* <li>(join BGP1 BGP2) {@literal =>} BGP
* <li>(sequence ...BGP1 BGP2 ...) {@literal =>} (sequence ...BGP ...)
*/
public class TransformMergeBGPs extends TransformCopy {
@Override
public Op transform(OpJoin opJoin, Op left, Op right) {
BasicPattern p1 = asBGP(left) ;
BasicPattern p2 = asBGP(right) ;
if ( p1 != null && p2 != null ) {
BasicPattern p = merge(p1, p2) ;
return new OpBGP(p) ;
}
return super.transform(opJoin, left, right) ;
}
@Override
public Op transform(OpSequence opSequence, List<Op> elts) {
// First check whether we need to do anything at all.
// Check for two BGPs.
boolean xform = false ;
boolean previousBGP = false ;
for ( Op op1 : elts ) {
BasicPattern p1 = asBGP(op1) ;
if ( previousBGP && p1 != null ) {
xform = true ;
break ;
}
previousBGP = (p1 != null) ;
}
if ( !xform )
// Nothing to do here.
return super.transform(opSequence, elts) ;
OpSequence seq2 = OpSequence.create() ;
for ( int i = 0 ; i < elts.size() ; i++ ) {
Op op = elts.get(i) ;
BasicPattern p1 = asBGP(op) ;
if ( p1 == null ) {
// Do nothing
seq2.add(op) ;
continue ; // Outer loop.
}
// This is the op after the merge, if any.
BasicPattern pMerge = new BasicPattern() ;
seq2.add(new OpBGP(pMerge)) ;
// Merge any BGPs from here on ...
// Re-gets the BGP that trigegrs this all.
for ( ; i < elts.size() ; i++ ) {
// Look at next element.
Op opNext = elts.get(i) ;
BasicPattern p2 = asBGP(opNext) ;
if ( p2 == null ) {
seq2.add(opNext) ;
break ;
}
// Merge.
pMerge.addAll(p2) ;
}
}
if ( seq2.size() == 1 )
return seq2.get(0) ;
return seq2 ;
}
private static BasicPattern asBGP(Op op) {
if ( op instanceof OpBGP )
return ((OpBGP)op).getPattern() ;
return null ;
}
private static BasicPattern merge(BasicPattern p1, BasicPattern p2) {
if ( p1 == null || p2 == null )
return null ;
BasicPattern p = new BasicPattern() ;
p.addAll(p1) ;
p.addAll(p2) ;
return p ;
}
}