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

Configure Feed

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

debug: add debug score for line matches (#351)

We enrich the score of a line match with more detailed information of how it was
calculated. This is similar to what we already do on the level of file matches.

author
Stefan Hengl
committer
GitHub
date (May 24, 2022, 11:08 AM +0200) commit f2bb82f7 parent a3e0a5fd
+48 -23
+3 -1
api.go
··· 89 89 90 90 // The higher the better. Only ranks the quality of the match 91 91 // within the file, does not take rank of file into account 92 - Score float64 92 + Score float64 93 + DebugScore string 94 + 93 95 LineFragments []LineFragmentMatch 94 96 } 95 97
+36 -17
contentprovider.go
··· 16 16 17 17 import ( 18 18 "bytes" 19 + "fmt" 19 20 "log" 20 21 "sort" 22 + "strings" 21 23 "unicode/utf8" 22 24 ) 23 25 ··· 130 132 return byteOff 131 133 } 132 134 133 - func (p *contentProvider) fillMatches(ms []*candidateMatch, numContextLines int, language string) []LineMatch { 135 + func (p *contentProvider) fillMatches(ms []*candidateMatch, numContextLines int, language string, debug bool) []LineMatch { 134 136 var result []LineMatch 135 137 if ms[0].fileName { 136 138 // There is only "line" in a filename. ··· 155 157 156 158 sects := p.docSections() 157 159 for i, m := range result { 158 - result[i].Score = p.matchScore(sects, &m, language) 160 + result[i].Score, result[i].DebugScore = p.matchScore(sects, &m, language, debug) 159 161 } 160 162 161 163 return result ··· 296 298 return 0, false 297 299 } 298 300 299 - func (p *contentProvider) matchScore(secs []DocumentSection, m *LineMatch, language string) float64 { 300 - var maxScore float64 301 + func (p *contentProvider) matchScore(secs []DocumentSection, m *LineMatch, language string, debug bool) (float64, string) { 302 + type debugScore struct { 303 + score float64 304 + what string 305 + } 306 + 307 + score := &debugScore{} 308 + maxScore := &debugScore{} 309 + 310 + addScore := func(what string, s float64) { 311 + if debug { 312 + score.what += fmt.Sprintf("%s:%f, ", what, s) 313 + } 314 + score.score += s 315 + } 316 + 301 317 for _, f := range m.LineFragments { 302 318 startBoundary := f.LineOffset < len(m.Line) && (f.LineOffset == 0 || byteClass(m.Line[f.LineOffset-1]) != byteClass(m.Line[f.LineOffset])) 303 319 304 320 end := int(f.LineOffset) + f.MatchLength 305 321 endBoundary := end > 0 && (end == len(m.Line) || byteClass(m.Line[end-1]) != byteClass(m.Line[end])) 306 322 307 - score := 0.0 323 + score.score = 0 324 + score.what = "" 325 + 308 326 if startBoundary && endBoundary { 309 - score = scoreWordMatch 327 + addScore("WordMatch", scoreWordMatch) 310 328 } else if startBoundary || endBoundary { 311 - score = scorePartialWordMatch 329 + addScore("PartialWordMatch", scorePartialWordMatch) 312 330 } 313 331 314 332 if m.FileName { ··· 316 334 startMatch := sep+1 == f.LineOffset 317 335 endMatch := len(m.Line) == f.LineOffset+f.MatchLength 318 336 if startMatch && endMatch { 319 - score += scoreBase 337 + addScore("Base", scoreBase) 320 338 } else if startMatch || endMatch { 321 - score += (scoreBase + scorePartialBase) / 2 339 + addScore("EdgeBase", (scoreBase+scorePartialBase)/2) 322 340 } else if sep < f.LineOffset { 323 - score += scorePartialBase 341 + addScore("InnerBase", scorePartialBase) 324 342 } 325 343 } else if secIdx, ok := findSection(secs, f.Offset, uint32(f.MatchLength)); ok { 326 344 sec := secs[secIdx] 327 345 startMatch := sec.Start == f.Offset 328 346 endMatch := sec.End == f.Offset+uint32(f.MatchLength) 329 347 if startMatch && endMatch { 330 - score += scoreSymbol 348 + addScore("Symbol", scoreSymbol) 331 349 } else if startMatch || endMatch { 332 - score += (scoreSymbol + scorePartialSymbol) / 2 350 + addScore("EdgeSymbol", (scoreSymbol+scorePartialSymbol)/2) 333 351 } else { 334 - score += scorePartialSymbol 352 + addScore("InnerSymbol", scorePartialSymbol) 335 353 } 336 354 337 355 si := f.SymbolInfo ··· 342 360 } 343 361 if si != nil { 344 362 // the LineFragment may not be on a symbol, then si will be nil. 345 - score += scoreKind(language, si.Kind) 363 + addScore(fmt.Sprintf("kind:%s:%s", language, si.Kind), scoreKind(language, si.Kind)) 346 364 } 347 365 } 348 366 349 - if score > maxScore { 350 - maxScore = score 367 + if score.score > maxScore.score { 368 + maxScore.score = score.score 369 + maxScore.what = score.what 351 370 } 352 371 } 353 - return maxScore 372 + return maxScore.score, strings.TrimRight(maxScore.what, ", ") 354 373 } 355 374 356 375 // scoreKind boosts a match based on the combination of language and kind. The
+3 -2
eval.go
··· 23 23 "strings" 24 24 25 25 enry_data "github.com/go-enry/go-enry/v2/data" 26 + "github.com/grafana/regexp" 27 + 26 28 "github.com/google/zoekt/query" 27 - "github.com/grafana/regexp" 28 29 ) 29 30 30 31 const maxUInt16 = 0xffff ··· 337 338 byteMatchSz: uint32(len(nm)), 338 339 }) 339 340 } 340 - fileMatch.LineMatches = cp.fillMatches(finalCands, opts.NumContextLines, fileMatch.Language) 341 + fileMatch.LineMatches = cp.fillMatches(finalCands, opts.NumContextLines, fileMatch.Language, opts.DebugScore) 341 342 342 343 maxFileScore := 0.0 343 344 for i := range fileMatch.LineMatches {
+2 -1
web/api.go
··· 73 73 After string `json:",omitempty"` 74 74 75 75 // Don't expose to caller of JSON API 76 - Score float64 `json:"-"` 76 + Score float64 `json:"-"` 77 + ScoreDebug string `json:"-"` 77 78 } 78 79 79 80 // Fragment holds data of a single contiguous match within in a line
+3 -1
web/snippets.go
··· 124 124 FileName: f.FileName, 125 125 LineNum: m.LineNumber, 126 126 URL: fMatch.URL + fragment, 127 - Score: m.Score, 127 + 128 + Score: m.Score, 129 + ScoreDebug: m.DebugScore, 128 130 } 129 131 130 132 md.Before = string(m.Before)
+1 -1
web/templates.go
··· 241 241 {{range .Matches}} 242 242 <tr> 243 243 <td style="background-color: rgba(238, 238, 255, 0.6);"> 244 - <pre class="inline-pre"><span class="noselect">{{if .URL}}<a href="{{.URL}}">{{end}}<u>{{.LineNum}}</u>{{if .URL}}</a>{{end}}: </span>{{range .Fragments}}{{LimitPre 100 .Pre}}<b>{{.Match}}</b>{{LimitPost 100 .Post}}{{end}} {{if $showScoreDebug}}<i>(score:{{.Score}})</i>{{end}}</pre> 244 + <pre class="inline-pre"><span class="noselect">{{if .URL}}<a href="{{.URL}}">{{end}}<u>{{.LineNum}}</u>{{if .URL}}</a>{{end}}: </span>{{range .Fragments}}{{LimitPre 100 .Pre}}<b>{{.Match}}</b>{{LimitPost 100 .Post}}{{end}} {{if $showScoreDebug}}<i>(score:{{.Score}} <-- {{.ScoreDebug}})</i>{{end}}</pre> 245 245 </td> 246 246 </tr> 247 247 {{end}}