public void insert(final String treePath,
@SuppressWarnings("rawtypes") final FeatureSource source, final Query query,
ProgressListener listener) {
final NodeRef treeRef = findOrCreateTypeTree(treePath, source);
Long collectionSize = null;
try {
// try for a fast count
int count = source.getCount(Query.ALL);
if (count > -1) {
collectionSize = Long.valueOf(count);
}
} catch (IOException e) {
throw Throwables.propagate(e);
}
final int nFetchThreads;
{
// maxFeatures is assumed to be supported by all data sources, so supportsPaging depends
// only on offset being supported
boolean supportsPaging = source.getQueryCapabilities().isOffsetSupported();
if (supportsPaging) {
Platform platform = context.platform();
int availableProcessors = platform.availableProcessors();
nFetchThreads = Math.max(2, availableProcessors / 2);
} else {
nFetchThreads = 1;
}
}
final ExecutorService executorService = Executors.newFixedThreadPool(2 + nFetchThreads,
new ThreadFactoryBuilder().setNameFormat("WorkingTree-tree-builder-%d").build());
listener.started();
Stopwatch sw = Stopwatch.createStarted();
final RevTree origTree = indexDatabase.getTree(treeRef.objectId());
Platform platform = context.platform();
RevTreeBuilder2 builder = new RevTreeBuilder2(indexDatabase, origTree,
treeRef.getMetadataId(), platform, executorService);
List<Future<Integer>> insertBlobsFuture = insertBlobs(source, query, executorService,
listener, collectionSize, nFetchThreads, builder);
RevTree newFeatureTree;
try {
long insertedCount = 0;
for (Future<Integer> f : insertBlobsFuture) {
insertedCount += f.get().longValue();
}
sw.stop();
listener.setDescription(insertedCount + " distinct features inserted in " + sw);
listener.setDescription("Building final tree...");
sw.reset().start();
newFeatureTree = builder.build();
listener.setDescription(String.format("%d features tree built in %s",
newFeatureTree.size(), sw.stop()));
listener.complete();
} catch (Exception e) {
throw Throwables.propagate(Throwables.getRootCause(e));
} finally {
executorService.shutdown();
}
ObjectId newTree = context.command(WriteBack.class).setAncestor(getTreeSupplier())
.setChildPath(treePath).setMetadataId(treeRef.getMetadataId()).setToIndex(true)
.setTree(newFeatureTree).call();
updateWorkHead(newTree);
}