use of com.google.common.base.Function in project druid by druid-io.
the class AppenderatorImpl method persistAll.
@Override
public ListenableFuture<Object> persistAll(final Committer committer) {
// Submit persistAll task to the persistExecutor
final Map<SegmentIdentifier, Integer> commitHydrants = Maps.newHashMap();
final List<Pair<FireHydrant, SegmentIdentifier>> indexesToPersist = Lists.newArrayList();
final Set<SegmentIdentifier> identifiers = sinks.keySet();
for (SegmentIdentifier identifier : identifiers) {
final Sink sink = sinks.get(identifier);
final List<FireHydrant> hydrants = Lists.newArrayList(sink);
commitHydrants.put(identifier, hydrants.size());
final int limit = sink.isWritable() ? hydrants.size() - 1 : hydrants.size();
for (FireHydrant hydrant : hydrants.subList(0, limit)) {
if (!hydrant.hasSwapped()) {
log.info("Hydrant[%s] hasn't persisted yet, persisting. Segment[%s]", hydrant, identifier);
indexesToPersist.add(Pair.of(hydrant, identifier));
}
}
if (sink.swappable()) {
indexesToPersist.add(Pair.of(sink.swap(), identifier));
}
}
log.info("Submitting persist runnable for dataSource[%s]", schema.getDataSource());
final String threadName = String.format("%s-incremental-persist", schema.getDataSource());
final Object commitMetadata = committer.getMetadata();
final Stopwatch runExecStopwatch = Stopwatch.createStarted();
final Stopwatch persistStopwatch = Stopwatch.createStarted();
final ListenableFuture<Object> future = persistExecutor.submit(new ThreadRenamingCallable<Object>(threadName) {
@Override
public Object doCall() {
try {
for (Pair<FireHydrant, SegmentIdentifier> pair : indexesToPersist) {
metrics.incrementRowOutputCount(persistHydrant(pair.lhs, pair.rhs));
}
log.info("Committing metadata[%s] for sinks[%s].", commitMetadata, Joiner.on(", ").join(Iterables.transform(commitHydrants.entrySet(), new Function<Map.Entry<SegmentIdentifier, Integer>, String>() {
@Override
public String apply(Map.Entry<SegmentIdentifier, Integer> entry) {
return String.format("%s:%d", entry.getKey().getIdentifierAsString(), entry.getValue());
}
})));
committer.run();
objectMapper.writeValue(computeCommitFile(), Committed.create(commitHydrants, commitMetadata));
return commitMetadata;
} catch (Exception e) {
metrics.incrementFailedPersists();
throw Throwables.propagate(e);
} finally {
metrics.incrementNumPersists();
metrics.incrementPersistTimeMillis(persistStopwatch.elapsed(TimeUnit.MILLISECONDS));
persistStopwatch.stop();
}
}
});
final long startDelay = runExecStopwatch.elapsed(TimeUnit.MILLISECONDS);
metrics.incrementPersistBackPressureMillis(startDelay);
if (startDelay > WARN_DELAY) {
log.warn("Ingestion was throttled for [%,d] millis because persists were pending.", startDelay);
}
runExecStopwatch.stop();
resetNextFlush();
// NB: The rows are still in memory until they're done persisting, but we only count rows in active indexes.
rowsCurrentlyInMemory.set(0);
return future;
}
use of com.google.common.base.Function in project druid by druid-io.
the class DatasourcesResource method getSegmentDataSourceSpecificInterval.
/**
* Provides serverView for a datasource and Interval which gives details about servers hosting segments for an interval
* Used by the realtime tasks to fetch a view of the interval they are interested in.
*/
@GET
@Path("/{dataSourceName}/intervals/{interval}/serverview")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(DatasourceResourceFilter.class)
public Response getSegmentDataSourceSpecificInterval(@PathParam("dataSourceName") String dataSourceName, @PathParam("interval") String interval, @QueryParam("partial") final boolean partial) {
TimelineLookup<String, SegmentLoadInfo> timeline = serverInventoryView.getTimeline(new TableDataSource(dataSourceName));
final Interval theInterval = new Interval(interval.replace("_", "/"));
if (timeline == null) {
log.debug("No timeline found for datasource[%s]", dataSourceName);
return Response.ok(Lists.<ImmutableSegmentLoadInfo>newArrayList()).build();
}
Iterable<TimelineObjectHolder<String, SegmentLoadInfo>> lookup = timeline.lookupWithIncompletePartitions(theInterval);
FunctionalIterable<ImmutableSegmentLoadInfo> retval = FunctionalIterable.create(lookup).transformCat(new Function<TimelineObjectHolder<String, SegmentLoadInfo>, Iterable<ImmutableSegmentLoadInfo>>() {
@Override
public Iterable<ImmutableSegmentLoadInfo> apply(TimelineObjectHolder<String, SegmentLoadInfo> input) {
return Iterables.transform(input.getObject(), new Function<PartitionChunk<SegmentLoadInfo>, ImmutableSegmentLoadInfo>() {
@Override
public ImmutableSegmentLoadInfo apply(PartitionChunk<SegmentLoadInfo> chunk) {
return chunk.getObject().toImmutableSegmentLoadInfo();
}
});
}
});
return Response.ok(retval).build();
}
use of com.google.common.base.Function in project druid by druid-io.
the class GutmanSearchStrategy method breadthFirstSearch.
public Iterable<ImmutableNode> breadthFirstSearch(Iterable<ImmutableNode> nodes, final Bound bound, int total) {
Iterable<ImmutableNode> points = Iterables.concat(Iterables.transform(Iterables.filter(nodes, new Predicate<ImmutableNode>() {
@Override
public boolean apply(ImmutableNode immutableNode) {
return immutableNode.isLeaf();
}
}), new Function<ImmutableNode, Iterable<ImmutableNode>>() {
@Override
public Iterable<ImmutableNode> apply(ImmutableNode immutableNode) {
return Iterables.filter(immutableNode.getChildren(), new Predicate<ImmutableNode>() {
@Override
public boolean apply(ImmutableNode immutableNode) {
return bound.contains(immutableNode.getMinCoordinates());
}
});
}
}));
Iterable<ImmutableNode> overlappingNodes = Iterables.filter(nodes, new Predicate<ImmutableNode>() {
@Override
public boolean apply(ImmutableNode immutableNode) {
return !immutableNode.isLeaf() && bound.overlaps(immutableNode);
}
});
int totalPoints = Iterables.size(points);
int totalOverlap = Iterables.size(overlappingNodes);
if (totalOverlap == 0 || (totalPoints + totalOverlap + total) >= bound.getLimit()) {
return Iterables.concat(points, overlappingNodes);
} else {
return Iterables.concat(points, breadthFirstSearch(Iterables.concat(Iterables.transform(overlappingNodes, new Function<ImmutableNode, Iterable<ImmutableNode>>() {
@Override
public Iterable<ImmutableNode> apply(ImmutableNode immutableNode) {
return immutableNode.getChildren();
}
})), bound, totalPoints));
}
}
use of com.google.common.base.Function in project druid by druid-io.
the class SchemalessIndexTest method makeMergedMMappedIndex.
private static QueryableIndex makeMergedMMappedIndex(Iterable<Pair<String, AggregatorFactory[]>> files) {
try {
File tmpFile = File.createTempFile("yay", "who");
tmpFile.delete();
File mergedFile = new File(tmpFile, "merged");
mergedFile.mkdirs();
mergedFile.deleteOnExit();
List<File> filesToMap = makeFilesToMap(tmpFile, files);
return INDEX_IO.loadIndex(INDEX_MERGER.mergeQueryableIndex(Lists.newArrayList(Iterables.transform(filesToMap, new Function<File, QueryableIndex>() {
@Override
public QueryableIndex apply(@Nullable File input) {
try {
return INDEX_IO.loadIndex(input);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
})), true, METRIC_AGGS, mergedFile, indexSpec));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
use of com.google.common.base.Function in project druid by druid-io.
the class SchemalessIndexTest method makeAppendedMMappedIndex.
private static QueryableIndex makeAppendedMMappedIndex(Iterable<Pair<String, AggregatorFactory[]>> files, final List<Interval> intervals) {
try {
File tmpFile = File.createTempFile("yay", "boo");
tmpFile.delete();
File mergedFile = new File(tmpFile, "merged");
mergedFile.mkdirs();
mergedFile.deleteOnExit();
List<File> filesToMap = makeFilesToMap(tmpFile, files);
VersionedIntervalTimeline<Integer, File> timeline = new VersionedIntervalTimeline<Integer, File>(Ordering.natural().nullsFirst());
ShardSpec noneShardSpec = NoneShardSpec.instance();
for (int i = 0; i < intervals.size(); i++) {
timeline.add(intervals.get(i), i, noneShardSpec.createChunk(filesToMap.get(i)));
}
final List<IndexableAdapter> adapters = Lists.newArrayList(Iterables.concat(// TimelineObjectHolder is actually an iterable of iterable of indexable adapters
Iterables.transform(timeline.lookup(new Interval("1000-01-01/3000-01-01")), new Function<TimelineObjectHolder<Integer, File>, Iterable<IndexableAdapter>>() {
@Override
public Iterable<IndexableAdapter> apply(final TimelineObjectHolder<Integer, File> timelineObjectHolder) {
return Iterables.transform(timelineObjectHolder.getObject(), // Each chunk can be used to build the actual IndexableAdapter
new Function<PartitionChunk<File>, IndexableAdapter>() {
@Override
public IndexableAdapter apply(PartitionChunk<File> chunk) {
try {
return new RowboatFilteringIndexAdapter(new QueryableIndexIndexableAdapter(INDEX_IO.loadIndex(chunk.getObject())), new Predicate<Rowboat>() {
@Override
public boolean apply(Rowboat input) {
return timelineObjectHolder.getInterval().contains(input.getTimestamp());
}
});
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
});
}
})));
return INDEX_IO.loadIndex(INDEX_MERGER.append(adapters, null, mergedFile, indexSpec));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
Aggregations