shardFailures = this.shardFailures.get(); // read again otherwise somebody else has created it? if (shardFailures == null) { // still null so we are the first and create a new instance shardFailures = new AtomicArray<>(getNumShards()); this.shardFailures.set(shardFailures); ShardSearchFailure failure = shardFailures.get(shardIndex); if (failure == null) { shardFailures.set(shardIndex, new ShardSearchFailure(e, shardTarget)); } else { shardFailures.set(shardIndex, new ShardSearchFailure(e, shardTarget));
Stream<Result> getSuccessfulResults() { return results.asList().stream(); }
@Override public void onResponse(T element) { results.setOnce(pos.incrementAndGet() - 1, element); if (countDown.countDown()) { if (failure.get() != null) { delegate.onFailure(failure.get()); } else { List<T> collect = this.results.asList(); collect.addAll(defaults); delegate.onResponse(Collections.unmodifiableList(collect)); } } }
clusterState.blocks().globalBlockedRaiseException(ClusterBlockLevel.READ); final AtomicArray<MultiGetItemResponse> responses = new AtomicArray<>(request.items.size()); final Map<ShardId, MultiGetShardRequest> shardRequests = new HashMap<>(); responses.set(i, newItemFailure(concreteSingleIndex, item.type(), item.id(), new RoutingMissingException(concreteSingleIndex, item.type(), item.id()))); continue; responses.set(i, newItemFailure(item.index(), item.type(), item.id(), e)); continue; listener.onResponse(new MultiGetResponse(responses.toArray(new MultiGetItemResponse[responses.length()])));
private void innerRun() throws IOException { final int numShards = context.getNumShards(); final boolean isScrollSearch = context.getRequest().scroll() != null; List<SearchPhaseResult> phaseResults = queryResults.asList(); String scrollId = isScrollSearch ? TransportSearchHelper.buildScrollId(queryResults) : null; final SearchPhaseController.ReducedQueryPhase reducedQueryPhase = resultConsumer.reduce(); final boolean queryAndFetchOptimization = queryResults.length() == 1; final Runnable finishPhase = () -> moveToNextPhase(searchPhaseController, scrollId, reducedQueryPhase, queryAndFetchOptimization ? searchPhaseController.getLastEmittedDocPerShard(reducedQueryPhase, numShards) : null; final CountedCollector<FetchSearchResult> counter = new CountedCollector<>(r -> fetchResults.set(r.getShardIndex(), r), SearchPhaseResult queryResult = queryResults.get(i); if (entry == null) { // no results for this shard ID if (queryResult != null) {
@Override public void run() { final SearchPhaseController.ReducedQueryPhase reducedQueryPhase = searchPhaseController.reducedScrollQueryPhase( queryResults.asList()); ScoreDoc[] scoreDocs = reducedQueryPhase.sortedTopDocs.scoreDocs; if (scoreDocs.length == 0) { final IntArrayList[] docIdsToLoad = searchPhaseController.fillDocIdsToLoad(queryResults.length(), scoreDocs); final ScoreDoc[] lastEmittedDocPerShard = searchPhaseController.getLastEmittedDocPerShard(reducedQueryPhase, queryResults.length()); final CountDown counter = new CountDown(docIdsToLoad.length); for (int i = 0; i < docIdsToLoad.length; i++) { final IntArrayList docIds = docIdsToLoad[index]; if (docIds != null) { final QuerySearchResult querySearchResult = queryResults.get(index); ScoreDoc lastEmittedDoc = lastEmittedDocPerShard[index]; ShardFetchRequest shardFetchRequest = new ShardFetchRequest(querySearchResult.getRequestId(), docIds,
ArraySearchPhaseResults(int size) { super(size); this.results = new AtomicArray<>(size); }
docWriteRequest.id(), e); BulkItemResponse bulkItemResponse = new BulkItemResponse(i, docWriteRequest.opType(), failure); responses.set(i, bulkItemResponse); listener.onResponse(new BulkResponse(responses.toArray(new BulkItemResponse[responses.length()]), buildTookInMillis(startTimeNanos))); return;
private void handleResponse(final int responseSlot, final MultiSearchResponse.Item item) { responses.set(responseSlot, item); if (responseCounter.decrementAndGet() == 0) { assert requests.isEmpty(); finish(); } else { if (thread == Thread.currentThread()) { // we are on the same thread, we need to fork to another thread to avoid recursive stack overflow on a single thread threadPool.generic().execute(() -> executeSearch(requests, responses, responseCounter, listener)); } else { // we are on a different thread (we went asynchronous), it's safe to recurse executeSearch(requests, responses, responseCounter, listener); } } }
@Override protected void onFirstPhaseResult(int shardId, ScrollQueryFetchSearchResult result) { queryFetchResults.setOnce(shardId, result.result()); } }
private void recordSliceCompletionAndRespondIfAllDone(ActionListener<BulkByScrollResponse> listener) { if (runningSubtasks.decrementAndGet() != 0) { return; } List<BulkByScrollResponse> responses = new ArrayList<>(results.length()); Exception exception = null; for (Result t : results.asList()) { if (t.response == null) { assert t.failure != null : "exception shouldn't be null if value is null"; if (exception == null) { exception = t.failure; } else { exception.addSuppressed(t.failure); } } else { assert t.failure == null : "exception should be null if response is not null"; responses.add(t.response); } } if (exception == null) { listener.onResponse(new BulkByScrollResponse(responses, task.getReasonCancelled())); } else { listener.onFailure(exception); } }
void finish() { MultiPercolateResponse.Item[] finalResponse = new MultiPercolateResponse.Item[reducedResponses.length()]; for (int slot = 0; slot < reducedResponses.length(); slot++) { Object element = reducedResponses.get(slot); assert element != null : "Element[" + slot + "] shouldn't be null"; if (element instanceof PercolateResponse) { finalResponse[slot] = new MultiPercolateResponse.Item((PercolateResponse) element); } else if (element instanceof Throwable) { finalResponse[slot] = new MultiPercolateResponse.Item((Throwable)element); } else if (element instanceof MultiGetResponse.Failure) { finalResponse[slot] = new MultiPercolateResponse.Item(((MultiGetResponse.Failure)element).getFailure()); } } finalListener.onResponse(new MultiPercolateResponse(finalResponse)); }
/** * Get the combined statuses of sliced subtasks */ public BulkByScrollTask.Status getStatus() { return getStatus(Arrays.asList(new BulkByScrollTask.StatusOrException[results.length()])); }
/** * Releases shard targets that are not used in the docsIdsToLoad. */ protected void releaseIrrelevantSearchContexts(AtomicArray<? extends QuerySearchResultProvider> queryResults, AtomicArray<IntArrayList> docIdsToLoad) { if (docIdsToLoad == null) { return; } // we only release search context that we did not fetch from if we are not scrolling if (request.scroll() == null) { for (AtomicArray.Entry<? extends QuerySearchResultProvider> entry : queryResults.asList()) { final TopDocs topDocs = entry.value.queryResult().queryResult().topDocs(); if (topDocs != null && topDocs.scoreDocs.length > 0 // the shard had matches && docIdsToLoad.get(entry.index) == null) { // but none of them made it to the global top docs try { DiscoveryNode node = nodes.get(entry.value.queryResult().shardTarget().nodeId()); sendReleaseSearchContext(entry.value.queryResult().id(), node); } catch (Throwable t1) { logger.trace("failed to release context", t1); } } } } }
boolean hasResult(int shardIndex) { return results.get(shardIndex) != null; }
final AtomicArray<MultiTermVectorsItemResponse> responses = new AtomicArray<>(request.requests.size()); .resolveIndexRouting(termVectorsRequest.parent(), termVectorsRequest.routing(), termVectorsRequest.index())); if (!clusterState.metaData().hasConcreteIndex(termVectorsRequest.index())) { responses.set(i, new MultiTermVectorsItemResponse(null, new MultiTermVectorsResponse.Failure(termVectorsRequest.index(), termVectorsRequest.type(), termVectorsRequest.id(), new IndexNotFoundException(termVectorsRequest.index())))); if (termVectorsRequest.routing() == null && clusterState.getMetaData().routingRequired(concreteSingleIndex, termVectorsRequest.type())) { responses.set(i, new MultiTermVectorsItemResponse(null, new MultiTermVectorsResponse.Failure(concreteSingleIndex, termVectorsRequest.type(), termVectorsRequest.id(), new RoutingMissingException(concreteSingleIndex, termVectorsRequest.type(), termVectorsRequest.id())))); listener.onResponse(new MultiTermVectorsResponse(responses.toArray(new MultiTermVectorsItemResponse[responses.length()])));
void innerExecuteFetchPhase() throws Exception { boolean useScroll = request.scroll() != null; sortedShardList = searchPhaseController.sortDocs(useScroll, queryResults); searchPhaseController.fillDocIdsToLoad(docIdsToLoad, sortedShardList); if (docIdsToLoad.asList().isEmpty()) { finishHim(); return; } final ScoreDoc[] lastEmittedDocPerShard = searchPhaseController.getLastEmittedDocPerShard( request, sortedShardList, firstResults.length() ); final AtomicInteger counter = new AtomicInteger(docIdsToLoad.asList().size()); for (final AtomicArray.Entry<IntArrayList> entry : docIdsToLoad.asList()) { QuerySearchResult queryResult = queryResults.get(entry.index); DiscoveryNode node = nodes.get(queryResult.shardTarget().nodeId()); ShardFetchSearchRequest fetchSearchRequest = createFetchRequest(queryResult, entry, lastEmittedDocPerShard); executeFetch(entry.index, queryResult.shardTarget(), counter, fetchSearchRequest, node); } }
/** * Builds an array, with potential null elements, with docs to load. */ public void fillDocIdsToLoad(AtomicArray<IntArrayList> docsIdsToLoad, ScoreDoc[] shardDocs) { for (ScoreDoc shardDoc : shardDocs) { IntArrayList list = docsIdsToLoad.get(shardDoc.shardIndex); if (list == null) { list = new IntArrayList(); // can't be shared!, uses unsafe on it later on docsIdsToLoad.set(shardDoc.shardIndex, list); } list.add(shardDoc.doc); } }