diff options
| author | mae <mae@maestoso.online> | 2026-03-04 22:50:58 -0600 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-05-02 05:05:56 +0900 |
| commit | 1d5d063d6a443c9d4a1206d2743e4824411da956 (patch) | |
| tree | b32105cf3896f394be91099cfbfb67785de39385 /cmd/mbf/internal/pkgserver/search.go | |
| parent | e61628a34ecccae0feb5e059a2f808977261fa0e (diff) | |
cmd/mbf: package status dashboard
This displays package metadata with optional status from a report.
Diffstat (limited to 'cmd/mbf/internal/pkgserver/search.go')
| -rw-r--r-- | cmd/mbf/internal/pkgserver/search.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/cmd/mbf/internal/pkgserver/search.go b/cmd/mbf/internal/pkgserver/search.go new file mode 100644 index 00000000..5756512f --- /dev/null +++ b/cmd/mbf/internal/pkgserver/search.go @@ -0,0 +1,81 @@ +package pkgserver + +import ( + "cmp" + "maps" + "regexp" + "slices" + "time" +) + +type searchCache map[string]searchCacheEntry +type searchResult struct { + NameIndices [][]int `json:"name_matches"` + DescIndices [][]int `json:"desc_matches,omitempty"` + Score float64 `json:"score"` + *metadata +} +type searchCacheEntry struct { + query string + results []searchResult + expiry time.Time +} + +func (index *packageIndex) performSearchQuery(limit int, i int, search string, desc bool) (int, []searchResult, error) { + query := search + if desc { + query += ";withDesc" + } + entry, ok := index.search[query] + if ok && len(entry.results) > 0 { + return len(entry.results), entry.results[min(i, len(entry.results)-1):min(i+limit, len(entry.results))], nil + } + + regex, err := regexp.Compile(search) + if err != nil { + return 0, make([]searchResult, 0), err + } + res := make([]searchResult, 0) + for p := range maps.Values(index.names) { + nameIndices := regex.FindAllIndex([]byte(p.Name), -1) + var descIndices [][]int = nil + if desc { + descIndices = regex.FindAllIndex([]byte(p.Description), -1) + } + if nameIndices == nil && descIndices == nil { + continue + } + score := float64(indexsum(nameIndices)) / (float64(len(nameIndices)) + 1) + if desc { + score += float64(indexsum(descIndices)) / (float64(len(descIndices)) + 1) / 10.0 + } + res = append(res, searchResult{ + NameIndices: nameIndices, + DescIndices: descIndices, + Score: score, + metadata: p, + }) + } + slices.SortFunc(res[:], func(a, b searchResult) int { return -cmp.Compare(a.Score, b.Score) }) + expiry := time.Now().Add(1 * time.Minute) + entry = searchCacheEntry{ + query: search, + results: res, + expiry: expiry, + } + index.search[query] = entry + + return len(res), res[i:min(i+limit, len(entry.results))], nil +} +func (s *searchCache) clean() { + maps.DeleteFunc(*s, func(_ string, v searchCacheEntry) bool { + return v.expiry.Before(time.Now()) + }) +} +func indexsum(in [][]int) int { + sum := 0 + for i := 0; i < len(in); i++ { + sum += in[i][1] - in[i][0] + } + return sum +} |
