/* * 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 jena; import java.util.Iterator; import arq.cmdline.CmdARQ; import jena.cmd.ArgDecl ; import jena.cmd.CmdException ; import org.apache.jena.graph.Node ; import org.apache.jena.query.Dataset ; import org.apache.jena.query.spatial.DatasetGraphSpatial; import org.apache.jena.query.spatial.SpatialDatasetFactory; import org.apache.jena.query.spatial.SpatialIndex; import org.apache.jena.query.spatial.SpatialIndexContext; import org.apache.jena.sparql.core.Quad ; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Spatial indexer application that will read a dataset and index its triples in * its spatial index. */ public class spatialindexer extends CmdARQ { private static Logger log = LoggerFactory.getLogger(spatialindexer.class); public static final ArgDecl assemblerDescDecl = new ArgDecl( ArgDecl.HasValue, "desc", "dataset"); protected DatasetGraphSpatial dataset = null; protected SpatialIndex spatialIndex = null; protected SpatialIndexContext context = null; protected ProgressMonitor progressMonitor; static public void main(String... argv) { new spatialindexer(argv).mainRun(); } static public void testMain(String... argv) { new spatialindexer(argv).mainMethod(); } protected spatialindexer(String[] argv) { super(argv); super.add(assemblerDescDecl, "--desc=", "Assembler description file"); progressMonitor = new ProgressMonitor("properties indexed"); } @Override protected void processModulesAndArgs() { super.processModulesAndArgs(); // Two forms : with and without arg. // Maximises similarity with other tools. String file; if (super.contains(assemblerDescDecl)) { if (getValues(assemblerDescDecl).size() != 1) throw new CmdException("Multiple assembler descriptions given"); if (getPositional().size() != 0) throw new CmdException( "Additional assembler descriptions given"); file = getValue(assemblerDescDecl); } else { if (getNumPositional() != 1) throw new CmdException("Multiple assembler descriptions given"); file = getPositionalArg(0); } if (file == null) throw new CmdException("No dataset specified"); // Assumes a single test daatset description in the assembler file. Dataset ds = SpatialDatasetFactory.create(file); if (ds == null) throw new CmdException("No dataset description found"); // get index. dataset = (DatasetGraphSpatial) (ds.asDatasetGraph()); spatialIndex = dataset.getSpatialIndex(); if (spatialIndex == null) throw new CmdException("Dataset has no spatial index"); context= new SpatialIndexContext(spatialIndex); } @Override protected String getSummary() { return getCommandName() + " assemblerFile"; } @Override protected void exec() { // Set<Node> properties = getIndexedProperties() ; spatialIndex.startIndexing(); Iterator<Quad> quadIter = dataset.find(Node.ANY, Node.ANY, Node.ANY, Node.ANY); for (; quadIter.hasNext();) { Quad quad = quadIter.next(); context.index(quad.getGraph(), quad.getSubject(), quad.getPredicate(), quad.getObject()); progressMonitor.progressByOne(); } spatialIndex.finishIndexing(); progressMonitor.close(); } // TDBLoader has a similar progress monitor // Not used here to avoid making ARQ dependent on TDB // So potential to rationalise and put progress monitor in a common // utility class private static class ProgressMonitor { String progressMessage; long startTime; long progressCount; long intervalStartTime; long progressAtStartOfInterval; long reportingInterval = 10000; // milliseconds ProgressMonitor(String progressMessage) { this.progressMessage = progressMessage; start(); // in case start not called } void start() { startTime = System.currentTimeMillis(); progressCount = 0L; startInterval(); } private void startInterval() { intervalStartTime = System.currentTimeMillis(); progressAtStartOfInterval = progressCount; } void progressByOne() { progressCount++; long now = System.currentTimeMillis(); if (reportDue(now)) { report(now); startInterval(); } } boolean reportDue(long now) { return now - intervalStartTime >= reportingInterval; } private void report(long now) { long progressThisInterval = progressCount - progressAtStartOfInterval; long intervalDuration = now - intervalStartTime; long overallDuration = now - startTime; String message = progressCount + " (" + progressThisInterval / (intervalDuration / 1000) + " per second)" + progressMessage + " (" + progressCount / Math.max(overallDuration / 1000, 1) + " per second overall)"; log.info(message); } void close() { long overallDuration = System.currentTimeMillis() - startTime; String message = progressCount + " (" + progressCount / Math.max(overallDuration / 1000, 1) + " per second) " + progressMessage; log.info(message); } } }