/* * 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.tdb.store.bulkloader2; import java.util.Iterator ; import org.apache.jena.atlas.lib.DateTimeUtils ; import org.apache.jena.atlas.lib.ProgressMonitor ; import org.apache.jena.atlas.lib.tuple.Tuple ; import org.apache.jena.tdb.base.file.Location ; import org.apache.jena.tdb.setup.Build ; import org.apache.jena.tdb.store.NodeId ; import org.apache.jena.tdb.store.tupletable.TupleIndex ; import org.apache.jena.tdb.sys.SystemTDB ; import org.slf4j.Logger ; import org.slf4j.LoggerFactory ; /** Copy one index to another, probably with a different key order */ public class ProcIndexCopy { private static Logger log = LoggerFactory.getLogger(ProcIndexCopy.class) ; static long tickQuantum = 100*1000 ; static int superTick = 10 ; // Ideas: // Copy to buffer, sort, write in sequential clumps. // Profile code for hotspots // Maybe be worth opening the data file (the leaves) as a regular, // non-memory mapped file as we read it through once, in natural order, // and it may be laid out in increasing block order on-disk, e.g. repacked // and in increasing order with occassional oddities if SPO from the bulk loader. public static void exec(String locationStr1, String indexName1, String locationStr2, String indexName2) { // Argument processing Location location1 = Location.create(locationStr1) ; Location location2 = Location.create(locationStr2) ; int keyLength = SystemTDB.SizeOfNodeId * indexName1.length() ; int valueLength = 0 ; // The name is the order. String primary = "SPO" ; String indexOrder = indexName2 ; String label = indexName1+" => "+indexName2 ; TupleIndex index1 = Build.openTupleIndex(location1, indexName1, primary, indexName1, 10, 10, keyLength, valueLength) ; TupleIndex index2 = Build.openTupleIndex(location2, indexName2, primary, indexOrder, 10, 10, keyLength, valueLength) ; tupleIndexCopy(index1, index2, label) ; index1.close() ; index2.close() ; } private static void tupleIndexCopy(TupleIndex index1, TupleIndex index2, String label) { ProgressMonitor monitor = ProgressMonitor.create(log, label, tickQuantum, superTick); monitor.start(); Iterator<Tuple<NodeId>> iter1 = index1.all(); long counter = 0; for ( ; iter1.hasNext() ; ) { counter++; Tuple<NodeId> tuple = iter1.next(); index2.add(tuple); monitor.tick(); } index2.sync(); long time = monitor.finish(); float elapsedSecs = time / 1000F; float rate = (elapsedSecs != 0) ? counter / elapsedSecs : 0; print("Total: %,d records : %,.2f seconds : %,.2f records/sec [%s]", counter, elapsedSecs, rate, DateTimeUtils.nowAsString()); } static private void print(String fmt, Object... args) { if ( log != null && log.isInfoEnabled() ) { String str = String.format(fmt, args); log.info(str); } } }