diff --git a/code/functions/search-query/api/java/nu/marginalia/api/searchquery/QueryProtobufCodec.java b/code/functions/search-query/api/java/nu/marginalia/api/searchquery/QueryProtobufCodec.java index e6e68431..e6e62dc3 100644 --- a/code/functions/search-query/api/java/nu/marginalia/api/searchquery/QueryProtobufCodec.java +++ b/code/functions/search-query/api/java/nu/marginalia/api/searchquery/QueryProtobufCodec.java @@ -257,6 +257,7 @@ public class QueryProtobufCodec { rawItem.getHtmlFeatures(), keywordScores, rawItem.getHasPriorityTerms(), + 0, // Not set null, // Not set Double.NaN // Not set ); diff --git a/code/functions/search-query/api/java/nu/marginalia/api/searchquery/model/results/SearchResultItem.java b/code/functions/search-query/api/java/nu/marginalia/api/searchquery/model/results/SearchResultItem.java index 6a70625c..f7662fa6 100644 --- a/code/functions/search-query/api/java/nu/marginalia/api/searchquery/model/results/SearchResultItem.java +++ b/code/functions/search-query/api/java/nu/marginalia/api/searchquery/model/results/SearchResultItem.java @@ -28,14 +28,18 @@ public class SearchResultItem implements Comparable { public boolean hasPrioTerm; + public long bestPositions; + public DebugRankingFactors debugRankingFactors; public SearchResultItem(long combinedId, long encodedDocMetadata, int htmlFeatures, - double score) { + double score, + long bestPositions) { this.combinedId = combinedId; this.encodedDocMetadata = encodedDocMetadata; + this.bestPositions = bestPositions; this.keywordScores = new ArrayList<>(); this.htmlFeatures = htmlFeatures; this.scoreValue = score; diff --git a/code/index/java/nu/marginalia/index/results/IndexResultRankingService.java b/code/index/java/nu/marginalia/index/results/IndexResultRankingService.java index 8de176bf..88ad26a1 100644 --- a/code/index/java/nu/marginalia/index/results/IndexResultRankingService.java +++ b/code/index/java/nu/marginalia/index/results/IndexResultRankingService.java @@ -179,7 +179,7 @@ public class IndexResultRankingService { LongOpenHashSet seenDocumentHashes = new LongOpenHashSet(resultsList.size()); // Decorate the results with the document details - for (var result : resultsList) { + for (SearchResultItem result : resultsList) { final long id = result.getDocumentId(); final DocdbUrlDetail docData = detailsById.get(id); @@ -219,7 +219,7 @@ public class IndexResultRankingService { .setUrl(docData.url().toString()) .setUrlQuality(docData.urlQuality()) .setWordsTotal(docData.wordsTotal()) - .setBestPositions(0 /* FIXME */) + .setBestPositions(result.getBestPositions()) .setResultsFromDomain(domainCountFilter.getCount(result)) .setRawItem(rawItem); diff --git a/code/index/java/nu/marginalia/index/results/IndexResultScoreCalculator.java b/code/index/java/nu/marginalia/index/results/IndexResultScoreCalculator.java index 76ac060f..1989c74f 100644 --- a/code/index/java/nu/marginalia/index/results/IndexResultScoreCalculator.java +++ b/code/index/java/nu/marginalia/index/results/IndexResultScoreCalculator.java @@ -106,7 +106,35 @@ public class IndexResultScoreCalculator { searchTerms.phraseConstraints, rankingContext); - return new SearchResultItem(combinedId, docMetadata, htmlFeatures, score); + return new SearchResultItem(combinedId, + docMetadata, + htmlFeatures, + score, + calculatePositionsMask(positions) + ); + } + + /** Calculate a bitmask illustrating the intersected positions of the search terms in the document. + * This is used in the GUI. + * */ + private long calculatePositionsMask(CodedSequence[] positions) { + IntIterator[] iters = new IntIterator[rankingContext.regularMask.cardinality()]; + for (int i = 0, j = 0; i < positions.length; i++) { + if (rankingContext.regularMask.get(i)) { + iters[j++] = positions[i].iterator(); + } + } + IntIterator intersection = SequenceOperations.findIntersections(iters).intIterator(); + + long result = 0; + int bit = 0; + + while (intersection.hasNext() && bit < 64) { + bit = (int) (Math.sqrt(intersection.nextInt())); + result |= 1L << bit; + } + + return result; } private boolean meetsQueryStrategyRequirements(CompiledQueryLong queryGraphScores, diff --git a/code/libraries/coded-sequence/java/nu/marginalia/sequence/SequenceOperations.java b/code/libraries/coded-sequence/java/nu/marginalia/sequence/SequenceOperations.java index 64ee2b5a..6a5e76b0 100644 --- a/code/libraries/coded-sequence/java/nu/marginalia/sequence/SequenceOperations.java +++ b/code/libraries/coded-sequence/java/nu/marginalia/sequence/SequenceOperations.java @@ -55,7 +55,7 @@ public class SequenceOperations { public static IntList findIntersections(IntIterator... sequences) { - if (sequences.length <= 1) + if (sequences.length < 1) return IntList.of(); // Initialize values and find the maximum value diff --git a/code/services-application/search-service/java/nu/marginalia/search/svc/SearchQueryIndexService.java b/code/services-application/search-service/java/nu/marginalia/search/svc/SearchQueryIndexService.java index c7214060..d5813549 100644 --- a/code/services-application/search-service/java/nu/marginalia/search/svc/SearchQueryIndexService.java +++ b/code/services-application/search-service/java/nu/marginalia/search/svc/SearchQueryIndexService.java @@ -2,14 +2,12 @@ package nu.marginalia.search.svc; import com.google.inject.Inject; import com.google.inject.Singleton; -import it.unimi.dsi.fastutil.ints.Int2LongArrayMap; import lombok.SneakyThrows; -import nu.marginalia.bbpc.BrailleBlockPunchCards; +import nu.marginalia.api.searchquery.model.query.QueryResponse; import nu.marginalia.api.searchquery.model.query.SearchSpecification; import nu.marginalia.api.searchquery.model.results.DecoratedSearchResultItem; -import nu.marginalia.api.searchquery.model.results.SearchResultItem; +import nu.marginalia.bbpc.BrailleBlockPunchCards; import nu.marginalia.model.crawl.DomainIndexingState; -import nu.marginalia.api.searchquery.model.query.QueryResponse; import nu.marginalia.search.model.UrlDetails; import nu.marginalia.search.results.UrlDeduplicator; import org.slf4j.Logger; @@ -17,7 +15,9 @@ import org.slf4j.LoggerFactory; import org.slf4j.Marker; import org.slf4j.MarkerFactory; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; @Singleton public class SearchQueryIndexService { @@ -99,7 +99,7 @@ public class SearchQueryIndexService { } private String getPositionsString(DecoratedSearchResultItem resultItem) { - return BrailleBlockPunchCards.printBits(resultItem.bestPositions, 56); + return BrailleBlockPunchCards.printBits(resultItem.bestPositions, 64); } }