fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

Add ChunkMatch.BestLineMatch to return the best-scoring line (#884)

This PR adds a new field `ChunkMatch.BestLineMatch` with the line number of top-scoring line in the chunk. This will let us address a long-standing issue with our new flexible keyword search, where chunk matches can become very large. Since our search results UX only shows the start of a chunk, the most relevant line may not even be visible. With this information on the best line match, we can adjust the search results UX to center the chunk on the most relevant line.

Relates to [SPLF-188](https://linear.app/sourcegraph/issue/SPLF-188/ensure-the-best-scoring-line-match-is-shown-in-search-results)

+181 -104
+6
api.go
··· 161 161 // beginning of a line (Column will always be 1). 162 162 ContentStart Location 163 163 164 + // Score is the overall relevance score of this chunk. 164 165 Score float64 166 + 167 + // BestLineMatch is the line number of the highest-scoring line match in this chunk. 168 + // The line number represents the index in the full file, and is 1-based. If FileName: true, 169 + // this number will be 0. 170 + BestLineMatch uint32 165 171 } 166 172 167 173 func (cm *ChunkMatch) sizeBytes() (sz uint64) {
+16 -14
api_proto.go
··· 96 96 } 97 97 98 98 return ChunkMatch{ 99 - Content: p.GetContent(), 100 - ContentStart: LocationFromProto(p.GetContentStart()), 101 - FileName: p.GetFileName(), 102 - Ranges: ranges, 103 - SymbolInfo: symbols, 104 - Score: p.GetScore(), 105 - DebugScore: p.GetDebugScore(), 99 + Content: p.GetContent(), 100 + ContentStart: LocationFromProto(p.GetContentStart()), 101 + FileName: p.GetFileName(), 102 + Ranges: ranges, 103 + SymbolInfo: symbols, 104 + Score: p.GetScore(), 105 + BestLineMatch: p.GetBestLineMatch(), 106 + DebugScore: p.GetDebugScore(), 106 107 } 107 108 } 108 109 ··· 118 119 } 119 120 120 121 return &proto.ChunkMatch{ 121 - Content: cm.Content, 122 - ContentStart: cm.ContentStart.ToProto(), 123 - FileName: cm.FileName, 124 - Ranges: ranges, 125 - SymbolInfo: symbolInfo, 126 - Score: cm.Score, 127 - DebugScore: cm.DebugScore, 122 + Content: cm.Content, 123 + ContentStart: cm.ContentStart.ToProto(), 124 + FileName: cm.FileName, 125 + Ranges: ranges, 126 + SymbolInfo: symbolInfo, 127 + Score: cm.Score, 128 + BestLineMatch: cm.BestLineMatch, 129 + DebugScore: cm.DebugScore, 128 130 } 129 131 } 130 132
+1 -1
api_test.go
··· 149 149 size: 256, 150 150 }, { 151 151 v: ChunkMatch{}, 152 - size: 112, 152 + size: 120, 153 153 }, { 154 154 v: candidateMatch{}, 155 155 size: 80,
+48 -5
build/scoring_test.go
··· 27 27 ) 28 28 29 29 type scoreCase struct { 30 - fileName string 31 - content []byte 32 - query query.Q 33 - language string 34 - wantScore float64 30 + fileName string 31 + content []byte 32 + query query.Q 33 + language string 34 + wantScore float64 35 + wantBestLineMatch uint32 35 36 } 36 37 37 38 func TestFileNameMatch(t *testing.T) { ··· 79 80 language: "Java", 80 81 // bm25-score: 0.58 <- sum-termFrequencyScore: 14.00, length-ratio: 1.00 81 82 wantScore: 0.58, 83 + // line 5: private final int exampleField; 84 + wantBestLineMatch: 5, 82 85 }, { 83 86 // Matches only on content 84 87 fileName: "example.java", ··· 91 94 language: "Java", 92 95 // bm25-score: 1.81 <- sum-termFrequencyScore: 116.00, length-ratio: 1.00 93 96 wantScore: 1.81, 97 + // line 3: public class InnerClasses { 98 + wantBestLineMatch: 3, 94 99 }, 95 100 { 96 101 // Matches only on filename ··· 130 135 language: "Java", 131 136 // 5500 (partial symbol at boundary) + 1000 (Java class) + 50 (partial word) 132 137 wantScore: 6550, 138 + // line 37: public class InnerClass implements InnerInterface<Integer, Integer> { 139 + wantBestLineMatch: 37, 133 140 }, 134 141 { 135 142 fileName: "example.java", ··· 138 145 language: "Java", 139 146 // 5500 (partial symbol at boundary) + 1000 (Java class) + 500 (word) 140 147 wantScore: 7000, 148 + // line 32: public static class InnerStaticClass { 149 + wantBestLineMatch: 32, 141 150 }, 142 151 { 143 152 fileName: "example.java", ··· 146 155 language: "Java", 147 156 // 7000 (symbol) + 900 (Java enum) + 500 (word) 148 157 wantScore: 8400, 158 + // line 16: public enum InnerEnum { 159 + wantBestLineMatch: 16, 149 160 }, 150 161 { 151 162 fileName: "example.java", ··· 154 165 language: "Java", 155 166 // 7000 (symbol) + 800 (Java interface) + 500 (word) 156 167 wantScore: 8300, 168 + // line 22: public interface InnerInterface<A, B> { 169 + wantBestLineMatch: 22, 157 170 }, 158 171 { 159 172 fileName: "example.java", ··· 162 175 language: "Java", 163 176 // 7000 (symbol) + 700 (Java method) + 500 (word) 164 177 wantScore: 8200, 178 + // line 44: public void innerMethod() { 179 + wantBestLineMatch: 44, 165 180 }, 166 181 { 167 182 fileName: "example.java", ··· 170 185 language: "Java", 171 186 // 7000 (symbol) + 600 (Java field) + 500 (word) 172 187 wantScore: 8100, 188 + // line 38: private final int field; 189 + wantBestLineMatch: 38, 173 190 }, 174 191 { 175 192 fileName: "example.java", ··· 178 195 language: "Java", 179 196 // 7000 (symbol) + 500 (Java enum constant) + 500 (word) 180 197 wantScore: 8000, 198 + // line 18: B, 199 + wantBestLineMatch: 18, 181 200 }, 182 201 // 2 Atoms (1x content and 1x filename) 183 202 { ··· 187 206 language: "Java", 188 207 // 5500 (edge symbol) + 600 (Java field) + 500 (word) + 200 (atom) 189 208 wantScore: 6800, 209 + // line 5: private final int exampleField; 210 + wantBestLineMatch: 5, 190 211 }, 191 212 // 3 Atoms (2x content, 1x filename) 192 213 { ··· 199 220 language: "Java", 200 221 // 7000 (symbol) + 700 (Java method) + 500 (word) + 266.67 (atom) 201 222 wantScore: 8466, 223 + // line 54: private static <A, B> B runInnerInterface(InnerInterface<A, B> fn, A a) { 224 + wantBestLineMatch: 54, 202 225 }, 203 226 // 4 Atoms (4x content) 204 227 { ··· 213 236 language: "Java", 214 237 // 7000 (symbol) + 900 (Java enum) + 500 (word) + 300 (atom) 215 238 wantScore: 8700, 239 + // line 16: public enum InnerEnum { 240 + wantBestLineMatch: 16, 216 241 }, 217 242 { 218 243 fileName: "example.java", ··· 221 246 language: "Java", 222 247 // 4000 (overlap Symbol) + 700 (Java method) + 50 (partial word) 223 248 wantScore: 4750, 249 + // line 54: private static <A, B> B runInnerInterface(InnerInterface<A, B> fn, A a) { 250 + wantBestLineMatch: 54, 224 251 }, 225 252 { 226 253 fileName: "example.java", ··· 229 256 language: "Java", 230 257 // 7000 (Symbol) + 900 (Java enum) + 500 (word) 231 258 wantScore: 8400, 259 + // line 16: public enum InnerEnum { 260 + wantBestLineMatch: 16, 232 261 }, 233 262 { 234 263 fileName: "example.java", ··· 237 266 language: "Java", 238 267 // 5500 (edge Symbol) + 900 (Java enum) + 500 (word) 239 268 wantScore: 6900, 269 + // line 16: public enum InnerEnum { 270 + wantBestLineMatch: 16, 240 271 }, 241 272 { 242 273 fileName: "example.java", ··· 245 276 language: "Java", 246 277 // 4000 (overlap Symbol) + 900 (Java enum) + 500 (word) 247 278 wantScore: 5400, 279 + // line 16: public enum InnerEnum { 280 + wantBestLineMatch: 16, 248 281 }, 249 282 } 250 283 ··· 638 671 639 672 if got := withoutTiebreaker(srs.Files[0].Score, useBM25); math.Abs(got-c.wantScore) > epsilon { 640 673 t.Fatalf("score: want %f, got %f\ndebug: %s\ndebugscore: %s", c.wantScore, got, srs.Files[0].Debug, srs.Files[0].ChunkMatches[0].DebugScore) 674 + } 675 + 676 + if c.wantBestLineMatch != 0 { 677 + if len(srs.Files[0].ChunkMatches) == 0 { 678 + t.Fatalf("want BestLineMatch %d, but no chunk matches were returned", c.wantBestLineMatch) 679 + } 680 + chunkMatch := srs.Files[0].ChunkMatches[0] 681 + if chunkMatch.BestLineMatch != c.wantBestLineMatch { 682 + t.Fatalf("want BestLineMatch %d, got %d", c.wantBestLineMatch, chunkMatch.BestLineMatch) 683 + } 641 684 } 642 685 643 686 if got := srs.Files[0].Language; got != c.language {
+49 -35
contentprovider.go
··· 164 164 } 165 165 166 166 // Otherwise, we return a single line containing the filematch match. 167 - score, debugScore, _ := p.candidateMatchScore(filenameMatches, language, debug) 167 + bestMatch, _ := p.candidateMatchScore(filenameMatches, language, debug) 168 168 res := LineMatch{ 169 169 Line: p.id.fileName(p.idx), 170 170 FileName: true, 171 - Score: score, 172 - DebugScore: debugScore, 171 + Score: bestMatch.score, 172 + DebugScore: bestMatch.debugScore, 173 173 } 174 174 175 175 for _, m := range ms { ··· 210 210 } 211 211 212 212 // Otherwise, we return a single chunk representing the filename match. 213 - score, debugScore, _ := p.candidateMatchScore(filenameMatches, language, debug) 213 + bestMatch, _ := p.candidateMatchScore(filenameMatches, language, debug) 214 214 fileName := p.id.fileName(p.idx) 215 215 ranges := make([]Range, 0, len(ms)) 216 216 for _, m := range ms { ··· 233 233 ContentStart: Location{ByteOffset: 0, LineNumber: 1, Column: 1}, 234 234 Ranges: ranges, 235 235 FileName: true, 236 - 237 - Score: score, 238 - DebugScore: debugScore, 236 + Score: bestMatch.score, 237 + DebugScore: bestMatch.debugScore, 239 238 }} 240 239 } 241 240 ··· 297 296 finalMatch.After = p.newlines().getLines(data, num+1, num+1+numContextLines) 298 297 } 299 298 300 - score, debugScore, symbolInfo := p.candidateMatchScore(lineCands, language, debug) 301 - finalMatch.Score = score 302 - finalMatch.DebugScore = debugScore 299 + bestMatch, symbolInfo := p.candidateMatchScore(lineCands, language, debug) 300 + finalMatch.Score = bestMatch.score 301 + finalMatch.DebugScore = bestMatch.debugScore 303 302 304 303 for i, m := range lineCands { 305 304 fragment := LineFragmentMatch{ ··· 336 335 chunks := chunkCandidates(ms, newlines, numContextLines) 337 336 chunkMatches := make([]ChunkMatch, 0, len(chunks)) 338 337 for _, chunk := range chunks { 339 - score, debugScore, symbolInfo := p.candidateMatchScore(chunk.candidates, language, debug) 338 + bestMatch, symbolInfo := p.candidateMatchScore(chunk.candidates, language, debug) 340 339 341 340 ranges := make([]Range, 0, len(chunk.candidates)) 342 341 for _, cm := range chunk.candidates { ··· 364 363 } 365 364 firstLineStart := newlines.lineStart(firstLineNumber) 366 365 366 + bestLineMatch := 0 367 + if bestMatch.match != nil { 368 + bestLineMatch = newlines.atOffset(bestMatch.match.byteOffset) 369 + if debug { 370 + bestMatch.debugScore = fmt.Sprintf("%s, (line: %d)", bestMatch.debugScore, bestLineMatch) 371 + } 372 + } 373 + 367 374 chunkMatches = append(chunkMatches, ChunkMatch{ 368 375 Content: newlines.getLines(data, firstLineNumber, int(chunk.lastLine)+numContextLines+1), 369 376 ContentStart: Location{ ··· 371 378 LineNumber: uint32(firstLineNumber), 372 379 Column: 1, 373 380 }, 374 - FileName: false, 375 - Ranges: ranges, 376 - SymbolInfo: symbolInfo, 377 - Score: score, 378 - DebugScore: debugScore, 381 + FileName: false, 382 + Ranges: ranges, 383 + SymbolInfo: symbolInfo, 384 + BestLineMatch: uint32(bestLineMatch), 385 + Score: bestMatch.score, 386 + DebugScore: bestMatch.debugScore, 379 387 }) 380 388 } 381 389 return chunkMatches ··· 658 666 return termFreqs 659 667 } 660 668 661 - func (p *contentProvider) candidateMatchScore(ms []*candidateMatch, language string, debug bool) (float64, string, []*Symbol) { 662 - type debugScore struct { 663 - what string 664 - score float64 665 - } 669 + // scoredMatch holds the score information for a candidate match. 670 + type scoredMatch struct { 671 + score float64 672 + debugScore string 673 + match *candidateMatch 674 + } 666 675 667 - score := &debugScore{} 668 - maxScore := &debugScore{} 676 + // candidateMatchScore scores all candidate matches and returns the best-scoring match plus its score information. 677 + // Invariant: there should be at least one input candidate, len(ms) > 0. 678 + func (p *contentProvider) candidateMatchScore(ms []*candidateMatch, language string, debug bool) (scoredMatch, []*Symbol) { 679 + score := 0.0 680 + what := "" 669 681 670 - addScore := func(what string, s float64) { 682 + addScore := func(w string, s float64) { 671 683 if s != 0 && debug { 672 - score.what += fmt.Sprintf("%s:%.2f, ", what, s) 684 + what += fmt.Sprintf("%s:%.2f, ", w, s) 673 685 } 674 - score.score += s 686 + score += s 675 687 } 676 688 677 689 filename := p.data(true) 678 690 var symbolInfo []*Symbol 679 691 692 + var bestMatch scoredMatch 680 693 for i, m := range ms { 681 694 data := p.data(m.fileName) 682 695 ··· 684 697 startBoundary := m.byteOffset < uint32(len(data)) && (m.byteOffset == 0 || byteClass(data[m.byteOffset-1]) != byteClass(data[m.byteOffset])) 685 698 endBoundary := endOffset > 0 && (endOffset == uint32(len(data)) || byteClass(data[endOffset-1]) != byteClass(data[endOffset])) 686 699 687 - score.score = 0 688 - score.what = "" 700 + score = 0 701 + what = "" 689 702 690 703 if startBoundary && endBoundary { 691 704 addScore("WordMatch", scoreWordMatch) ··· 737 750 738 751 // scoreWeight != 1 means it affects score 739 752 if !epsilonEqualsOne(m.scoreWeight) { 740 - score.score = score.score * m.scoreWeight 753 + score = score * m.scoreWeight 741 754 if debug { 742 - score.what += fmt.Sprintf("boost:%.2f, ", m.scoreWeight) 755 + what += fmt.Sprintf("boost:%.2f, ", m.scoreWeight) 743 756 } 744 757 } 745 758 746 - if score.score > maxScore.score { 747 - maxScore.score = score.score 748 - maxScore.what = score.what 759 + if score > bestMatch.score { 760 + bestMatch.score = score 761 + bestMatch.debugScore = what 762 + bestMatch.match = m 749 763 } 750 764 } 751 765 752 766 if debug { 753 - maxScore.what = fmt.Sprintf("score:%.2f <- %s", maxScore.score, strings.TrimSuffix(maxScore.what, ", ")) 767 + bestMatch.debugScore = fmt.Sprintf("score:%.2f <- %s", bestMatch.score, strings.TrimSuffix(bestMatch.debugScore, ", ")) 754 768 } 755 769 756 - return maxScore.score, maxScore.what, symbolInfo 770 + return bestMatch, symbolInfo 757 771 } 758 772 759 773 // sectionSlice will return data[sec.Start:sec.End] but will clip Start and
+59 -49
grpc/protos/zoekt/webserver/v1/webserver.pb.go
··· 2071 2071 Ranges []*Range `protobuf:"bytes,4,rep,name=ranges,proto3" json:"ranges,omitempty"` 2072 2072 // The symbol information associated with Ranges. If it is non-nil, 2073 2073 // its length will equal that of Ranges. Any of its elements may be nil. 2074 - SymbolInfo []*SymbolInfo `protobuf:"bytes,5,rep,name=symbol_info,json=symbolInfo,proto3" json:"symbol_info,omitempty"` 2075 - Score float64 `protobuf:"fixed64,6,opt,name=score,proto3" json:"score,omitempty"` 2076 - DebugScore string `protobuf:"bytes,7,opt,name=debug_score,json=debugScore,proto3" json:"debug_score,omitempty"` 2074 + SymbolInfo []*SymbolInfo `protobuf:"bytes,5,rep,name=symbol_info,json=symbolInfo,proto3" json:"symbol_info,omitempty"` 2075 + Score float64 `protobuf:"fixed64,6,opt,name=score,proto3" json:"score,omitempty"` 2076 + DebugScore string `protobuf:"bytes,7,opt,name=debug_score,json=debugScore,proto3" json:"debug_score,omitempty"` 2077 + BestLineMatch uint32 `protobuf:"varint,8,opt,name=best_line_match,json=bestLineMatch,proto3" json:"best_line_match,omitempty"` 2077 2078 } 2078 2079 2079 2080 func (x *ChunkMatch) Reset() { ··· 2155 2156 return x.DebugScore 2156 2157 } 2157 2158 return "" 2159 + } 2160 + 2161 + func (x *ChunkMatch) GetBestLineMatch() uint32 { 2162 + if x != nil { 2163 + return x.BestLineMatch 2164 + } 2165 + return 0 2158 2166 } 2159 2167 2160 2168 type Range struct { ··· 2684 2692 0x69, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 2685 2693 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 2686 2694 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 2687 - 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xb1, 0x02, 0x0a, 2695 + 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xd9, 0x02, 0x0a, 2688 2696 0x0a, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 2689 2697 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 2690 2698 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, ··· 2704 2712 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 2705 2713 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x07, 2706 2714 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x53, 0x63, 0x6f, 0x72, 0x65, 2707 - 0x22, 0x6b, 0x0a, 0x05, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 2708 - 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 2709 - 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 2710 - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2e, 0x0a, 2711 - 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x7a, 0x6f, 0x65, 2712 - 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 2713 - 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x64, 0x0a, 2714 - 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, 0x74, 2715 - 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 2716 - 0x62, 0x79, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 2717 - 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 2718 - 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x63, 2719 - 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x63, 0x6f, 0x6c, 2720 - 0x75, 0x6d, 0x6e, 0x2a, 0x8c, 0x01, 0x0a, 0x0b, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x52, 0x65, 0x61, 2721 - 0x73, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x20, 0x46, 0x4c, 0x55, 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, 2722 - 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 2723 - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x46, 0x4c, 0x55, 2724 - 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x52, 0x5f, 2725 - 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x4c, 0x55, 2726 - 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c, 0x5f, 2727 - 0x46, 0x4c, 0x55, 0x53, 0x48, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x4c, 0x55, 0x53, 0x48, 2728 - 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x53, 0x49, 0x5a, 0x45, 2729 - 0x10, 0x03, 0x32, 0x99, 0x02, 0x0a, 0x10, 0x57, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 2730 - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x51, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 2731 - 0x68, 0x12, 0x21, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 2732 - 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 2733 - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 2734 - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 2735 - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x0c, 0x53, 0x74, 2736 - 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x27, 0x2e, 0x7a, 0x6f, 0x65, 2737 - 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 2738 - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 2739 - 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 2740 - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 2741 - 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 2742 - 0x01, 0x12, 0x4b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 2743 - 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 2744 - 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x7a, 0x6f, 0x65, 2745 - 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 2746 - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3d, 2747 - 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 2748 - 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2f, 0x67, 2749 - 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 2750 - 0x2f, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 2751 - 0x72, 0x6f, 0x74, 0x6f, 0x33, 2715 + 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x65, 0x73, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6d, 0x61, 2716 + 0x74, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x62, 0x65, 0x73, 0x74, 0x4c, 2717 + 0x69, 0x6e, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x6b, 0x0a, 0x05, 0x52, 0x61, 0x6e, 0x67, 2718 + 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 2719 + 0x32, 0x1c, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 2720 + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 2721 + 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 2722 + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 2723 + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 2724 + 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x64, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 2725 + 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 2726 + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 2727 + 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 2728 + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 2729 + 0x62, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x03, 0x20, 2730 + 0x01, 0x28, 0x0d, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x2a, 0x8c, 0x01, 0x0a, 0x0b, 2731 + 0x46, 0x6c, 0x75, 0x73, 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x20, 0x46, 2732 + 0x4c, 0x55, 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 2733 + 0x4f, 0x57, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 2734 + 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x46, 0x4c, 0x55, 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 2735 + 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x52, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 2736 + 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x4c, 0x55, 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 2737 + 0x4e, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c, 0x5f, 0x46, 0x4c, 0x55, 0x53, 0x48, 0x10, 0x02, 0x12, 2738 + 0x19, 0x0a, 0x15, 0x46, 0x4c, 0x55, 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 2739 + 0x4d, 0x41, 0x58, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x03, 0x32, 0x99, 0x02, 0x0a, 0x10, 0x57, 2740 + 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 2741 + 0x51, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x21, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 2742 + 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 2743 + 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x7a, 2744 + 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 2745 + 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 2746 + 0x22, 0x00, 0x12, 0x65, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x61, 0x72, 2747 + 0x63, 0x68, 0x12, 0x27, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 2748 + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 2749 + 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x7a, 0x6f, 2750 + 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 2751 + 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 2752 + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x4b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 2753 + 0x74, 0x12, 0x1f, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 2754 + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 2755 + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x65, 2756 + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 2757 + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 2758 + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 2759 + 0x2f, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 2760 + 0x6f, 0x73, 0x2f, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2f, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 2761 + 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 2752 2762 } 2753 2763 2754 2764 var (
+1
grpc/protos/zoekt/webserver/v1/webserver.proto
··· 485 485 486 486 double score = 6; 487 487 string debug_score = 7; 488 + uint32 best_line_match = 8; 488 489 } 489 490 490 491 message Range {
+1
index_test.go
··· 38 38 } 39 39 for j := range r.Files[i].ChunkMatches { 40 40 r.Files[i].ChunkMatches[j].Score = 0.0 41 + r.Files[i].ChunkMatches[j].BestLineMatch = 0 41 42 } 42 43 r.Files[i].Checksum = nil 43 44 r.Files[i].Debug = ""