summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2019-09-16 22:56:07 +0200
committerGitHub <noreply@github.com>2019-09-16 22:56:07 +0200
commitecb09fabab58ba8336626e07ab73fabf8ded7199 (patch)
tree3832bee43ce7c2d1df314897dd9071bb15444618
parentc5a2086cf32305c6e9dde031e7b460a04f452c0f (diff)
Revert "Revert "Revert "Use a LeanHit until merging is done." MERGEOK""
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java12
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java63
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java3
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/FastSearcher.java11
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java74
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/InvokerResult.java52
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/LeanHit.java63
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java13
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java50
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java3
-rw-r--r--container-search/src/test/java/com/yahoo/search/dispatch/LeanHitTest.java42
-rw-r--r--container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java16
-rw-r--r--container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java68
14 files changed, 151 insertions, 323 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
index 4ffcc0a4330..e637e168030 100644
--- a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
@@ -184,7 +184,8 @@ public class ClusterSearcher extends Searcher {
: !host.equals(HostName.getLocalhost());
}
- private static ClusterParams makeClusterParams(int searchclusterIndex, int dispatchIndex) {
+ private static ClusterParams makeClusterParams(int searchclusterIndex,
+ int dispatchIndex) {
return new ClusterParams("sc" + searchclusterIndex + ".num" + dispatchIndex);
}
@@ -194,10 +195,11 @@ public class ClusterSearcher extends Searcher {
DocumentdbInfoConfig documentdbInfoConfig,
Backend backend,
Dispatcher dispatcher,
- int dispatcherIndex)
- {
- ClusterParams clusterParams = makeClusterParams(searchclusterIndex, dispatcherIndex);
- return new FastSearcher(backend, fs4ResourcePool, dispatcher, docSumParams, clusterParams, documentdbInfoConfig);
+ int dispatcherIndex) {
+ ClusterParams clusterParams = makeClusterParams(searchclusterIndex,
+ dispatcherIndex);
+ return new FastSearcher(backend, fs4ResourcePool, dispatcher, docSumParams, clusterParams,
+ documentdbInfoConfig);
}
private static VdsStreamingSearcher vdsCluster(String serverId,
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java
index f3867288b29..33715921e6d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java
@@ -18,8 +18,6 @@ import com.yahoo.prelude.ConfigurationException;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
-import com.yahoo.search.dispatch.InvokerResult;
-import com.yahoo.search.dispatch.LeanHit;
import com.yahoo.search.dispatch.ResponseMonitor;
import com.yahoo.search.dispatch.SearchInvoker;
import com.yahoo.search.dispatch.searchcluster.Node;
@@ -91,7 +89,7 @@ public class FS4SearchInvoker extends SearchInvoker implements ResponseMonitor<F
}
@Override
- protected InvokerResult getSearchResult(Execution execution) throws IOException {
+ protected Result getSearchResult(Execution execution) throws IOException {
if (pendingSearchError != null) {
return errorResult(query, pendingSearchError);
}
@@ -119,10 +117,11 @@ public class FS4SearchInvoker extends SearchInvoker implements ResponseMonitor<F
if (query.getPresentation().getSummary() == null)
query.getPresentation().setSummary(searcher.getDefaultDocsumClass());
- InvokerResult result = new InvokerResult(query, resultPacket.getDocumentCount());
+ Result result = new Result(query);
- addMetaInfo(query, queryPacket.getQueryPacketData(), resultPacket, result.getResult());
- addUnfilledHits(result.getLeanHits(), resultPacket.getDocuments(), queryPacket.getQueryPacketData());
+ ensureResultHitCapacity(result, resultPacket);
+ addMetaInfo(query, queryPacket.getQueryPacketData(), resultPacket, result);
+ addUnfilledHits(result, resultPacket.getDocuments(), queryPacket.getQueryPacketData());
return result;
}
@@ -139,6 +138,14 @@ public class FS4SearchInvoker extends SearchInvoker implements ResponseMonitor<F
return queryPacket;
}
+ private void ensureResultHitCapacity(Result result, QueryResultPacket resultPacket) {
+ int hitCount = resultPacket.getDocumentCount();
+ if (resultPacket.getGroupData() != null) {
+ hitCount++;
+ }
+ result.hits().ensureCapacity(hitCount);
+ }
+
private void addMetaInfo(Query query, QueryPacketData queryPacketData, QueryResultPacket resultPacket, Result result) {
result.setTotalHitCount(resultPacket.getTotalDocumentCount());
@@ -185,21 +192,47 @@ public class FS4SearchInvoker extends SearchInvoker implements ResponseMonitor<F
/**
* Creates unfilled hits from a List of DocumentInfo instances.
*/
- private void addUnfilledHits(List<LeanHit> result, List<DocumentInfo> documents, QueryPacketData queryPacketData) {
+ private void addUnfilledHits(Result result, List<DocumentInfo> documents, QueryPacketData queryPacketData) {
+ Query myQuery = result.getQuery();
+ Sorting sorting = myQuery.getRanking().getSorting();
Optional<Integer> channelDistributionKey = distributionKey();
for (DocumentInfo document : documents) {
- byte [] sortData = document.getSortData();
- LeanHit hit = (sortData == null)
- ? new LeanHit(document.getRawGlobalId(), document.getPartId(), channelDistributionKey.orElse(document.getDistributionKey()), document.getMetric())
- : new LeanHit(document.getRawGlobalId(), document.getPartId(), channelDistributionKey.orElse(document.getDistributionKey()), document.getSortData());
- if (queryPacketData != null) {
- hit.setQueryPacketData(queryPacketData);
- }
- result.add(hit);
+
+ try {
+ FastHit hit = new FastHit();
+ hit.setQuery(myQuery);
+ if (queryPacketData != null)
+ hit.setQueryPacketData(queryPacketData);
+
+ hit.setFillable();
+ hit.setCached(false);
+
+ extractDocumentInfo(hit, document, sorting);
+ channelDistributionKey.ifPresent(hit::setDistributionKey);
+
+ result.hits().add(hit);
+ } catch (ConfigurationException e) {
+ log.log(LogLevel.WARNING, "Skipping hit", e);
+ } catch (Exception e) {
+ log.log(LogLevel.ERROR, "Skipping malformed hit", e);
+ }
}
}
+ private void extractDocumentInfo(FastHit hit, DocumentInfo document, Sorting sorting) {
+ hit.setSource(getName());
+
+ Number rank = document.getMetric();
+
+ hit.setRelevance(new Relevance(rank.doubleValue()));
+
+ hit.setDistributionKey(document.getDistributionKey());
+ hit.setGlobalId(document.getRawGlobalId());
+ hit.setPartId(document.getPartId());
+ hit.setSortData(document.getSortData(), sorting);
+ }
+
@Override
public void release() {
if (channel != null) {
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java
index f7f2d08d713..63f3c8acc20 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastHit.java
@@ -75,9 +75,6 @@ public class FastHit extends Hit {
distributionKey = 0;
}
- public FastHit(byte [] gid, double relevance, int partId, int distributionKey) {
- this(gid, new Relevance(relevance), partId, distributionKey);
- }
public FastHit(byte [] gid, Relevance relevance, int partId, int distributionKey) {
super(relevance);
this.globalId = gid;
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastSearcher.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastSearcher.java
index 6b0041a9e86..6d3ae440152 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastSearcher.java
@@ -22,8 +22,6 @@ import com.yahoo.search.grouping.GroupingRequest;
import com.yahoo.search.grouping.request.GroupingOperation;
import com.yahoo.search.query.Ranking;
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 java.io.IOException;
@@ -143,21 +141,12 @@ public class FastSearcher extends VespaBackEndSearcher {
QueryRewrite.rewriteSddocname(query);
}
- private void injectSource(HitGroup hits) {
- for (Hit hit : hits.asUnorderedHits()) {
- if (hit instanceof FastHit) {
- hit.setSource(getName());
- }
- }
- }
-
@Override
public Result doSearch2(Query query, Execution execution) {
if (dispatcher.searchCluster().groupSize() == 1)
forceSinglePassGrouping(query);
try(SearchInvoker invoker = getSearchInvoker(query)) {
Result result = invoker.search(query, execution);
- injectSource(result.hits());
if (query.properties().getBoolean(Ranking.RANKFEATURES, false)) {
// There is currently no correct choice for which
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 84e5e7d747f..388a31d1482 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
@@ -93,9 +93,10 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
}
@Override
- protected InvokerResult getSearchResult(Execution execution) throws IOException {
- InvokerResult result = new InvokerResult(query, query.getHits());
- List<LeanHit> merged = Collections.emptyList();
+ protected Result getSearchResult(Execution execution) throws IOException {
+ Result result = new Result(query);
+ List<Hit> merged = Collections.emptyList();
+ List<Hit> auxiliary = new ArrayList<>();
long nextTimeout = query.getTimeLeft();
try {
while (!invokers.isEmpty() && nextTimeout >= 0) {
@@ -104,7 +105,7 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
log.fine(() -> "Search timed out with " + askedNodes + " requests made, " + answeredNodes + " responses received");
break;
} else {
- merged = mergeResult(result.getResult(), invoker.getSearchResult(execution), merged);
+ merged = mergeResult(result, invoker.getSearchResult(execution), merged, auxiliary);
ejectInvoker(invoker);
}
nextTimeout = nextTimeout();
@@ -113,11 +114,12 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
throw new RuntimeException("Interrupted while waiting for search results", e);
}
- insertNetworkErrors(result.getResult());
- result.getResult().setCoverage(createCoverage());
+ insertNetworkErrors(result);
+ result.setCoverage(createCoverage());
int needed = query.getOffset() + query.getHits();
+ result.hits().addAll(auxiliary);
for (int index = query.getOffset(); (index < merged.size()) && (index < needed); index++) {
- result.getLeanHits().add(merged.get(index));
+ result.hits().add(merged.get(index));
}
query.setOffset(0); // Now we are all trimmed down
return result;
@@ -189,31 +191,43 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
return nextAdaptive;
}
- private List<LeanHit> mergeResult(Result result, InvokerResult partialResult, List<LeanHit> current) {
- collectCoverage(partialResult.getResult().getCoverage(true));
+ private List<Hit> mergeResult(Result result, Result partialResult, List<Hit> current, List<Hit> auxiliaryHits) {
+ collectCoverage(partialResult.getCoverage(true));
- result.mergeWith(partialResult.getResult());
- List<Hit> partialNonLean = partialResult.getResult().hits().asUnorderedHits();
- for(Hit hit : partialNonLean) {
- if (hit.isAuxiliary()) {
- result.hits().add(hit);
- }
- }
+ result.mergeWith(partialResult);
+ List<Hit> partial = partialResult.hits().asUnorderedHits();
if (current.isEmpty() ) {
- return partialResult.getLeanHits();
+ boolean hasAuxillary = false;
+ for(Hit hit : partial) {
+ if (hit.isAuxiliary()) {
+ hasAuxillary = true;
+ break;
+ }
+ }
+ if ( ! hasAuxillary)
+ return partial;
}
- List<LeanHit> partial = partialResult.getLeanHits();
if (partial.isEmpty()) {
return current;
}
int needed = query.getOffset() + query.getHits();
- List<LeanHit> merged = new ArrayList<>(needed);
+ List<Hit> merged = new ArrayList<>(needed);
int indexCurrent = 0;
int indexPartial = 0;
while (indexCurrent < current.size() && indexPartial < partial.size() && merged.size() < needed) {
- LeanHit incommingHit = partial.get(indexPartial);
- LeanHit currentHit = current.get(indexCurrent);
+ Hit incommingHit = partial.get(indexPartial);
+ if (incommingHit.isAuxiliary()) {
+ auxiliaryHits.add(incommingHit);
+ indexPartial++;
+ continue;
+ }
+ Hit currentHit = current.get(indexCurrent);
+ if (currentHit.isAuxiliary()) {
+ auxiliaryHits.add(currentHit);
+ indexCurrent++;
+ continue;
+ }
int cmpRes = currentHit.compareTo(incommingHit);
if (cmpRes < 0) {
@@ -228,11 +242,21 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
indexPartial++;
}
}
- while ((indexCurrent < current.size()) && (merged.size() < needed)) {
- merged.add(current.get(indexCurrent++));
+ while (indexCurrent < current.size()) {
+ Hit h = current.get(indexCurrent++);
+ if (h.isAuxiliary()) {
+ auxiliaryHits.add(h);
+ } else if (merged.size() < needed) {
+ merged.add(h);
+ }
}
- while ((indexPartial < partial.size()) && (merged.size() < needed)) {
- merged.add(partial.get(indexPartial++));
+ while (indexPartial < partial.size()) {
+ Hit h = partial.get(indexPartial++);
+ if (h.isAuxiliary()) {
+ auxiliaryHits.add(h);
+ } else if (merged.size() < needed) {
+ merged.add(h);
+ }
}
return merged;
}
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/InvokerResult.java b/container-search/src/main/java/com/yahoo/search/dispatch/InvokerResult.java
deleted file mode 100644
index cd8228624c5..00000000000
--- a/container-search/src/main/java/com/yahoo/search/dispatch/InvokerResult.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.yahoo.search.dispatch;
-
-import com.yahoo.prelude.fastsearch.FastHit;
-import com.yahoo.search.Query;
-import com.yahoo.search.Result;
-import com.yahoo.search.query.Sorting;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Wraps a Result and a flat, skinny hit list
- */
-public class InvokerResult {
- private final Result result;
- private final List<LeanHit> leanHits;
- public InvokerResult(Result result) {
- this.result = result;
- this.leanHits = Collections.emptyList();
- }
- public InvokerResult(Query query, int expectedHits) {
- result = new Result(query);
- leanHits = new ArrayList<>(expectedHits);
- }
-
- public Result getResult() {
- return result;
- }
-
- public List<LeanHit> getLeanHits() {
- return leanHits;
- }
- void complete() {
- Query query = result.getQuery();
- Sorting sorting = query.getRanking().getSorting();
- for (LeanHit hit : leanHits) {
- FastHit fh = new FastHit(hit.getGid(), hit.getRelevance(), hit.getPartId(), hit.getDistributionKey());
- if (hit.hasSortData()) {
- fh.setSortData(hit.getSortData(), sorting);
- }
- if (hit.getQueryPacketData() != null) {
- fh.setQueryPacketData(hit.getQueryPacketData());
- }
- fh.setQuery(query);
- fh.setFillable();
- fh.setCached(false);
- result.hits().add(fh);
- }
- leanHits.clear();
- }
-}
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/LeanHit.java b/container-search/src/main/java/com/yahoo/search/dispatch/LeanHit.java
deleted file mode 100644
index 6ec0e3f27d1..00000000000
--- a/container-search/src/main/java/com/yahoo/search/dispatch/LeanHit.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.yahoo.search.dispatch;
-
-import com.yahoo.fs4.QueryPacketData;
-
-import java.util.Arrays;
-
-public class LeanHit implements Comparable<LeanHit> {
- private final byte [] gid;
- private final double relevance;
- private final byte [] sortData;
- private final int partId;
- private final int distributionKey;
- //TODO Remove when FS4 is gone
- private QueryPacketData queryPacketData;
- public LeanHit(byte [] gid, int partId, int distributionKey, double relevance) {
- this.gid = gid;
- this.relevance = relevance;
- this.sortData = null;
- this.partId = partId;
- this.distributionKey = distributionKey;
- }
- public LeanHit(byte [] gid, int partId, int distributionKey, byte [] sortData) {
- this.gid = gid;
- this.relevance = Double.NEGATIVE_INFINITY;
- this.sortData = sortData;
- this.partId = partId;
- this.distributionKey = distributionKey;
- }
- public double getRelevance() { return relevance; }
- public byte [] getGid() { return gid; }
- public byte [] getSortData() { return sortData; }
- public boolean hasSortData() { return sortData != null; }
- public int getPartId() { return partId; }
- public int getDistributionKey() { return distributionKey; }
-
- QueryPacketData getQueryPacketData() { return queryPacketData; }
-
- public void setQueryPacketData(QueryPacketData queryPacketData) {
- this.queryPacketData = queryPacketData;
- }
-
- @Override
- public int compareTo(LeanHit o) {
- int res = (sortData != null)
- ? compareData(sortData, o.sortData)
- : Double.compare(o.relevance, relevance);
- return (res != 0) ? res : compareData(gid, o.gid);
- }
-
- private static int compareData(byte [] left, byte [] right) {
- int i = Arrays.mismatch(left, right);
- if (i < 0) {
- return 0;
- }
- int max = Integer.min(left.length, right.length);
- if (i >= max) {
- return left.length - right.length;
- }
- int vl = (int) left[i] & 0xFF;
- int vr = (int) right[i] & 0xFF;
- return vl - vr;
- }
-}
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
index 52a45dc421c..b1d25dddbb8 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
@@ -42,12 +42,12 @@ public class SearchErrorInvoker extends SearchInvoker {
}
@Override
- protected InvokerResult getSearchResult(Execution execution) throws IOException {
+ protected Result getSearchResult(Execution execution) throws IOException {
Result res = new Result(query, message);
if (coverage != null) {
res.setCoverage(coverage);
}
- return new InvokerResult(res);
+ return res;
}
@Override
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
index 77b3df7c83a..3bfb9089457 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
@@ -32,15 +32,14 @@ public abstract class SearchInvoker extends CloseableInvoker {
*/
public Result search(Query query, Execution execution) throws IOException {
sendSearchRequest(query);
- InvokerResult result = getSearchResult(execution);
- setFinalStatus(result.getResult().hits().getError() == null);
- result.complete();
- return result.getResult();
+ Result result = getSearchResult(execution);
+ setFinalStatus(result.hits().getError() == null);
+ return result;
}
protected abstract void sendSearchRequest(Query query) throws IOException;
- protected abstract InvokerResult getSearchResult(Execution execution) throws IOException;
+ protected abstract Result getSearchResult(Execution execution) throws IOException;
protected void setMonitor(ResponseMonitor<SearchInvoker> monitor) {
this.monitor = monitor;
@@ -56,12 +55,12 @@ public abstract class SearchInvoker extends CloseableInvoker {
return node.map(Node::key);
}
- protected InvokerResult errorResult(Query query, ErrorMessage errorMessage) {
+ protected Result errorResult(Query query, ErrorMessage errorMessage) {
Result error = new Result(query, errorMessage);
Coverage errorCoverage = new Coverage(0, 0, 0);
errorCoverage.setNodesTried(1);
error.setCoverage(errorCoverage);
- return new InvokerResult(error);
+ return error;
}
}
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
index 7fd41862212..6039e09bbe1 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
@@ -15,8 +15,6 @@ import com.yahoo.prelude.fastsearch.GroupingListHit;
import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
-import com.yahoo.search.dispatch.InvokerResult;
-import com.yahoo.search.dispatch.LeanHit;
import com.yahoo.search.grouping.vespa.GroupingExecutor;
import com.yahoo.search.query.Model;
import com.yahoo.search.query.QueryTree;
@@ -24,6 +22,7 @@ import com.yahoo.search.query.Ranking;
import com.yahoo.search.query.Sorting;
import com.yahoo.search.query.Sorting.Order;
import com.yahoo.search.result.Coverage;
+import com.yahoo.search.result.Relevance;
import com.yahoo.searchlib.aggregation.Grouping;
import com.yahoo.slime.BinaryFormat;
import com.yahoo.vespa.objects.BufferSerializer;
@@ -181,22 +180,31 @@ public class ProtobufSerialization {
return convertFromResult(searchResult).toByteArray();
}
- static InvokerResult deserializeToSearchResult(byte[] payload, Query query, VespaBackEndSearcher searcher, int partId, int distKey)
+ static Result deserializeToSearchResult(byte[] payload, Query query, VespaBackEndSearcher searcher, int partId, int distKey)
throws InvalidProtocolBufferException {
var protobuf = SearchProtocol.SearchReply.parseFrom(payload);
- return convertToResult(query, protobuf, searcher.getDocumentDatabase(query), partId, distKey);
+ return convertToResult(query, protobuf, searcher.getDocumentDatabase(query), partId, distKey, searcher.getName());
}
- static InvokerResult convertToResult(Query query, SearchProtocol.SearchReply protobuf,
- DocumentDatabase documentDatabase, int partId, int distKey)
- {
- InvokerResult result = new InvokerResult(query, protobuf.getHitsCount());
+ private static Result convertToResult(Query query,
+ SearchProtocol.SearchReply protobuf,
+ DocumentDatabase documentDatabase,
+ int partId,
+ int distKey,
+ String source) {
+ var result = new Result(query);
- result.getResult().setTotalHitCount(protobuf.getTotalHitCount());
- result.getResult().setCoverage(convertToCoverage(protobuf));
+ result.setTotalHitCount(protobuf.getTotalHitCount());
+ result.setCoverage(convertToCoverage(protobuf));
+ int hitItems = protobuf.getHitsCount();
var haveGrouping = protobuf.getGroupingBlob() != null && !protobuf.getGroupingBlob().isEmpty();
if (haveGrouping) {
+ hitItems++;
+ }
+ result.hits().ensureCapacity(hitItems);
+
+ if (haveGrouping) {
BufferSerializer buf = new BufferSerializer(new GrowableByteBuffer(protobuf.getGroupingBlob().asReadOnlyByteBuffer()));
int cnt = buf.getInt(null);
ArrayList<Grouping> list = new ArrayList<>(cnt);
@@ -207,16 +215,26 @@ public class ProtobufSerialization {
}
GroupingListHit hit = new GroupingListHit(list, documentDatabase.getDocsumDefinitionSet());
hit.setQuery(query);
- result.getResult().hits().add(hit);
+ result.hits().add(hit);
}
+ var sorting = query.getRanking().getSorting();
for (var replyHit : protobuf.getHitsList()) {
- LeanHit hit = (replyHit.getSortData().isEmpty())
- ? new LeanHit(replyHit.getGlobalId().toByteArray(), partId, distKey, replyHit.getRelevance())
- : new LeanHit(replyHit.getGlobalId().toByteArray(), partId, distKey, replyHit.getSortData().toByteArray());
- result.getLeanHits().add(hit);
- }
+ FastHit hit = new FastHit(replyHit.getGlobalId().toByteArray(), new Relevance(replyHit.getRelevance()), partId, distKey);
+ hit.setQuery(query);
+ if (!replyHit.getSortData().isEmpty()) {
+ hit.setSortData(replyHit.getSortData().toByteArray(), sorting);
+ }
+ hit.setFillable();
+ hit.setCached(false);
+ hit.setSource(source);
+
+ result.hits().add(hit);
+ }
+ if (sorting != null) {
+ result.hits().setSorted(true);
+ }
var slimeTrace = protobuf.getSlimeTrace();
if (slimeTrace != null && !slimeTrace.isEmpty()) {
var traces = new Value.ArrayValue();
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
index 59f17501c32..9f42e794f5e 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
@@ -6,7 +6,6 @@ import com.yahoo.compress.Compressor;
import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
-import com.yahoo.search.dispatch.InvokerResult;
import com.yahoo.search.dispatch.SearchInvoker;
import com.yahoo.search.dispatch.rpc.Client.ProtobufResponse;
import com.yahoo.search.dispatch.searchcluster.Node;
@@ -61,7 +60,7 @@ public class RpcSearchInvoker extends SearchInvoker implements Client.ResponseRe
}
@Override
- protected InvokerResult getSearchResult(Execution execution) throws IOException {
+ protected Result getSearchResult(Execution execution) throws IOException {
long timeLeftMs = query.getTimeLeft();
if (timeLeftMs <= 0) {
return errorResult(query, ErrorMessage.createTimeout("Timeout while waiting for " + getName()));
diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/LeanHitTest.java b/container-search/src/test/java/com/yahoo/search/dispatch/LeanHitTest.java
deleted file mode 100644
index 3478038e427..00000000000
--- a/container-search/src/test/java/com/yahoo/search/dispatch/LeanHitTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.yahoo.search.dispatch;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-public class LeanHitTest {
- byte [] gidA = {'a'};
- byte [] gidB = {'b'};
- byte [] gidC = {'c'};
- private void verifyTransitiveOrdering(LeanHit a, LeanHit b, LeanHit c) {
- assertTrue(a.compareTo(b) < 0);
- assertTrue(b.compareTo(c) < 0);
- assertTrue(a.compareTo(c) < 0);
- assertTrue(b.compareTo(a) > 0);
- assertTrue(c.compareTo(b) > 0);
- assertTrue(c.compareTo(a) > 0);
- }
- @Test
- public void testOrderingByRelevance() {
- assertEquals(0, new LeanHit(gidA, 0, 0, 1).compareTo(new LeanHit(gidA, 0, 0, 1)));
- verifyTransitiveOrdering(new LeanHit(gidA, 0, 0, 1),
- new LeanHit(gidA, 0, 0, 0),
- new LeanHit(gidA, 0, 0, -1));
- }
- @Test
- public void testOrderingByGid() {
- assertEquals(0, new LeanHit(gidA, 0, 0, 1).compareTo(new LeanHit(gidA, 0, 0, 1)));
-
- verifyTransitiveOrdering(new LeanHit(gidA, 0, 0, 1),
- new LeanHit(gidB, 0, 0, 1),
- new LeanHit(gidC, 0, 0, 1));
- }
- @Test
- public void testOrderingBySortData() {
- assertEquals(0, new LeanHit(gidA, 0, 0, gidA).compareTo(new LeanHit(gidA, 0, 0, gidA)));
- verifyTransitiveOrdering(new LeanHit(gidA, 0, 0, gidA),
- new LeanHit(gidA, 0, 0, gidB),
- new LeanHit(gidA, 0, 0, gidC));
- }
-}
diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java b/container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java
index 2fe434d6f3f..4b2f63d6b89 100644
--- a/container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java
+++ b/container-search/src/test/java/com/yahoo/search/dispatch/MockInvoker.java
@@ -1,7 +1,6 @@
// Copyright 2019 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.dispatch;
-import com.yahoo.prelude.fastsearch.FastHit;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.dispatch.searchcluster.Node;
@@ -38,20 +37,13 @@ class MockInvoker extends SearchInvoker {
}
@Override
- protected InvokerResult getSearchResult(Execution execution) throws IOException {
- InvokerResult ret = new InvokerResult(query, 10);
+ protected Result getSearchResult(Execution execution) throws IOException {
+ Result ret = new Result(query);
if (coverage != null) {
- ret.getResult().setCoverage(coverage);
+ ret.setCoverage(coverage);
}
if (hits != null) {
- for (Hit h : hits) {
- if (h instanceof FastHit) {
- FastHit fh = (FastHit) h;
- ret.getLeanHits().add(new LeanHit(fh.getRawGlobalId(), fh.getPartId(), fh.getDistributionKey(), fh.getRelevance().getScore()));
- } else {
- ret.getResult().hits().add(h);
- }
- }
+ ret.hits().addAll(hits);
}
return ret;
}
diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java b/container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java
index b736ca1e6df..0b1d0d07e7a 100644
--- a/container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java
+++ b/container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java
@@ -2,32 +2,22 @@
package com.yahoo.search.dispatch.rpc;
-import ai.vespa.searchlib.searchprotocol.protobuf.SearchProtocol;
-import com.google.protobuf.ByteString;
import com.yahoo.document.GlobalId;
import com.yahoo.document.idstring.IdString;
import com.yahoo.prelude.fastsearch.FastHit;
import com.yahoo.search.Query;
-import com.yahoo.search.dispatch.InvokerResult;
-import com.yahoo.search.dispatch.LeanHit;
import org.junit.Test;
import java.io.IOException;
import java.util.Collections;
-import java.util.List;
import static org.hamcrest.Matchers.equalTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
/**
* @author ollivir
*/
public class ProtobufSerializationTest {
- static final double DELTA = 0.000000000001;
-
@Test
public void testDocsumSerialization() throws IOException {
Query q = new Query("search/?query=test&hits=10&offset=3");
@@ -39,62 +29,4 @@ public class ProtobufSerializationTest {
assertThat(bytes.length, equalTo(41));
}
-
- SearchProtocol.SearchReply createSearchReply(int numHits, boolean useSorting) {
- SearchProtocol.SearchReply.Builder reply = SearchProtocol.SearchReply.newBuilder();
- reply.setTotalHitCount(7);
-
- for (int i = 0; i < numHits; i++) {
- SearchProtocol.Hit.Builder hit = SearchProtocol.Hit.newBuilder();
- byte [] gid = {'a','a','a','a','a','a','a','a','a','a','a', (byte)i};
- hit.setGlobalId(ByteString.copyFrom(gid));
- if (useSorting) {
- gid[0] = 'b';
- hit.setSortData(ByteString.copyFrom(gid));
- } else {
- hit.setRelevance(numHits - i);
- }
- reply.addHits(hit);
- }
- return reply.build();
- }
- @Test
- public void testSearhReplyDecodingWithRelevance() {
- Query q = new Query("search/?query=test");
- InvokerResult result = ProtobufSerialization.convertToResult(q, createSearchReply(5, false), null, 1, 2);
- assertEquals(result.getResult().getTotalHitCount(), 7);
- List<LeanHit> hits = result.getLeanHits();
- assertEquals(5, hits.size());
- double expectedRelevance = 5;
- int hitNum = 0;
- for (LeanHit hit : hits) {
- assertEquals('a', hit.getGid()[0]);
- assertEquals(hitNum, hit.getGid()[11]);
- assertEquals(expectedRelevance--, hit.getRelevance(), DELTA);
- assertEquals(1, hit.getPartId());
- assertEquals(2, hit.getDistributionKey());
- assertFalse(hit.hasSortData());
- hitNum++;
- }
- }
- @Test
- public void testSearhReplyDecodingWithSortData() {
- Query q = new Query("search/?query=test");
- InvokerResult result = ProtobufSerialization.convertToResult(q, createSearchReply(5, true), null, 1, 2);
- assertEquals(result.getResult().getTotalHitCount(), 7);
- List<LeanHit> hits = result.getLeanHits();
- assertEquals(5, hits.size());
- int hitNum = 0;
- for (LeanHit hit : hits) {
- assertEquals('a', hit.getGid()[0]);
- assertEquals(hitNum, hit.getGid()[11]);
- assertEquals(Double.NEGATIVE_INFINITY, hit.getRelevance(), DELTA);
- assertEquals(1, hit.getPartId());
- assertEquals(2, hit.getDistributionKey());
- assertTrue(hit.hasSortData());
- assertEquals('b', hit.getSortData()[0]);
- assertEquals(hitNum, hit.getSortData()[11]);
- hitNum++;
- }
- }
}