diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2019-09-10 12:58:19 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2019-09-10 15:31:59 +0200 |
commit | 1b0904eddb1e38b4eb46eea466dd928a95594d06 (patch) | |
tree | 75c43c1ce3c3bb2b9a7fa0a96e63f4961999f5bb /container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java | |
parent | ed9a286551032f1aea6d048e1f3ac30b3da31ac1 (diff) |
HitGroup.sort and hit.compareTo must ensure same ordering...
Do not use the first result as starting point. Start off with a fresh one.
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java')
-rw-r--r-- | container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java index 5b2521f324d..76157175c3d 100644 --- a/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java +++ b/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java @@ -7,7 +7,6 @@ import com.yahoo.search.dispatch.searchcluster.SearchCluster; import com.yahoo.search.result.Coverage; import com.yahoo.search.result.ErrorMessage; import com.yahoo.search.result.Hit; -import com.yahoo.search.result.HitGroup; import com.yahoo.search.searchchain.Execution; import com.yahoo.vespa.config.search.DispatchConfig; @@ -49,8 +48,6 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM private long adaptiveTimeoutMax = 0; private long deadline = 0; - private Result result = null; - private long answeredDocs = 0; private long answeredActiveDocs = 0; private long answeredSoonActiveDocs = 0; @@ -96,7 +93,7 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM @Override protected Result getSearchResult(Execution execution) throws IOException { - + Result result = new Result(query); List<Hit> merged = Collections.emptyList(); long nextTimeout = query.getTimeLeft(); try { @@ -106,7 +103,7 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM log.fine(() -> "Search timed out with " + askedNodes + " requests made, " + answeredNodes + " responses received"); break; } else { - merged = mergeResult(invoker.getSearchResult(execution), merged); + merged = mergeResult(result, invoker.getSearchResult(execution), merged); ejectInvoker(invoker); } nextTimeout = nextTimeout(); @@ -115,21 +112,16 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM throw new RuntimeException("Interrupted while waiting for search results", e); } - if (result == null) { - result = new Result(query); - } - insertNetworkErrors(); + insertNetworkErrors(result); result.setCoverage(createCoverage()); int needed = query.getOffset() + query.getHits(); for (int index = query.getOffset(); (index < merged.size()) && (index < needed); index++) { result.hits().add(merged.get(index)); } - Result ret = result; - result = null; - return ret; + return result; } - private void insertNetworkErrors() { + private void insertNetworkErrors(Result result) { // Network errors will be reported as errors only when all nodes fail, otherwise they are just traced boolean asErrors = answeredNodes == 0; @@ -195,25 +187,31 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM return nextAdaptive; } - private List<Hit> mergeResult(Result partialResult, List<Hit> current) { + private List<Hit> mergeResult(Result result, Result partialResult, List<Hit> current) { collectCoverage(partialResult.getCoverage(true)); - if (result == null) { - result = partialResult; - return result.hits().asUnorderedHits(); - } result.mergeWith(partialResult); - int needed = query.getOffset() + query.getHits(); List<Hit> partial = partialResult.hits().asUnorderedHits(); + if (current.isEmpty() ) { + return partial; + } + if (partial.isEmpty()) { + return current; + } + + int needed = query.getOffset() + query.getHits(); List<Hit> merged = new ArrayList<>(needed); int indexCurrent = 0; int indexPartial = 0; while (indexCurrent < current.size() && indexPartial < partial.size() && merged.size() < needed) { int cmpRes = current.get(indexCurrent).compareTo(partial.get(indexPartial)); - if (cmpRes <= 0) { + if (cmpRes < 0) { merged.add(current.get(indexCurrent++)); - } else { + } else if (cmpRes > 0) { merged.add(partial.get(indexPartial++)); + } else { // Duplicates + merged.add(current.get(indexCurrent++)); + indexPartial++; } } while ((indexCurrent < current.size()) && (merged.size() < needed)) { |