org.apache.jena.sdb.layout2.index.SlotCompilerIndex Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-sdb Show documentation
Show all versions of jena-sdb Show documentation
SDB is a persistence layer for use with Apache Jena that uses an SQL database to store triples/quads.
/*
* 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.sdb.layout2.index;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.jena.graph.Node ;
import org.apache.jena.sdb.SDBException ;
import org.apache.jena.sdb.compiler.QuadBlock ;
import org.apache.jena.sdb.compiler.SqlBuilder ;
import org.apache.jena.sdb.core.AliasesSql ;
import org.apache.jena.sdb.core.SDBRequest ;
import org.apache.jena.sdb.core.sqlexpr.* ;
import org.apache.jena.sdb.core.sqlnode.SqlNode ;
import org.apache.jena.sdb.core.sqlnode.SqlTable ;
import org.apache.jena.sdb.layout2.NodeLayout2 ;
import org.apache.jena.sdb.layout2.SlotCompiler2 ;
import org.apache.jena.sdb.layout2.TableDescNodes ;
import org.apache.jena.sdb.layout2.TableDescTriples ;
import org.apache.jena.sparql.core.Quad ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.util.FmtUtils ;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SlotCompilerIndex extends SlotCompiler2
{
private static Logger log = LoggerFactory.getLogger(SlotCompilerIndex.class) ;
private static final String NodeConstBase = AliasesSql.NodesConstantAliasBase ;
Map constantCols = new HashMap() ;
// Could be a set but it's convenient to keep thing in order for debugging.
private List constants ; // = new ArrayList() ;
private List vars ; // = new ArrayList() ;
protected TableDescTriples tripleTableDesc ;
protected TableDescNodes nodeTableDesc ;
private SqlNode constantsSqlNode ;
public SlotCompilerIndex(SDBRequest request)
{
super(request) ;
tripleTableDesc = request.getStore().getTripleTableDesc() ;
nodeTableDesc = request.getStore().getNodeTableDesc() ;
}
@Override
public SqlNode start(QuadBlock quads)
{
// Need to work out when constants are in-scope from earlier.
// Reset context.
constants = new ArrayList() ;
vars = new ArrayList() ;
classify(quads, constants, vars) ;
constantsSqlNode = insertConstantAccesses(constants) ;
// can be hold this back until the end of a block?
return constantsSqlNode ;
}
@Override
protected void constantSlot(SDBRequest request, Node node, SqlColumn thisCol, SqlExprList conditions)
{
SqlColumn colId = constantCols.get(node) ;
if ( colId == null )
{
log.warn("Failed to find id col for "+node) ;
return ;
}
SqlExpr c = new S_Equal(thisCol, colId) ;
c.addNote("Const condition: "+FmtUtils.stringForNode(node, getRequest().getPrefixMapping())) ;
conditions.add(c) ;
return ;
}
protected SqlNode insertConstantAccesses(Collection constants)
{
SqlNode sqlNode = null ;
for ( Node n : constants )
{
long hash = NodeLayout2.hash(n);
SqlConstant hashValue = new SqlConstant(hash) ;
// Access nodes table.
SqlTable nTable = new SqlTable(getRequest().genId(NodeConstBase),
nodeTableDesc.getTableName()) ;
nTable.addNote("Const: "+FmtUtils.stringForNode(n, getRequest().getPrefixMapping())) ;
SqlColumn cHash = new SqlColumn(nTable, nodeTableDesc.getHashColName()) ;
// Record
constantCols.put(n, new SqlColumn(nTable, nodeTableDesc.getIdColName())) ;
SqlExpr c = new S_Equal(cHash, hashValue) ;
sqlNode = SqlBuilder.innerJoin(getRequest(), sqlNode, nTable) ;
sqlNode = SqlBuilder.restrict(getRequest(), sqlNode, c) ;
}
return sqlNode ;
}
protected void classify(QuadBlock quadBlock, Collection constants, Collectionvars)
{
for ( Quad quad : quadBlock )
{
// Some constants are only markers and are not stored in the database.
if ( ! Quad.isDefaultGraph(quad.getGraph()) && ! quad.isUnionGraph() ) // quad.isDefaultGraph ARQ 2.8.4 and later
acc(constants, vars, quad.getGraph()) ;
acc(constants, vars, quad.getSubject()) ;
acc(constants, vars, quad.getPredicate()) ;
acc(constants, vars, quad.getObject()) ;
}
}
private static void acc(Collectionconstants, Collectionvars, Node node)
{
if ( node.isLiteral() || node.isBlank() || node.isURI() )
{
if ( ! constants.contains(node) )
constants.add(node) ;
return ;
}
if ( Var.isVar(node) )
{
vars.add(Var.alloc(node)) ;
return ;
}
if ( node.isVariable() )
{
log.warn("Node_Varable but not a Var; bodged") ;
vars.add(Var.alloc(node)) ;
return ;
}
log.error("Unknown Node type: "+node) ;
throw new SDBException("Unknown Node type: "+node) ;
}
}