forked from rosa/hakurei
78 lines
1.9 KiB
Go
78 lines
1.9 KiB
Go
package main
|
|
|
|
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) {
|
|
entry, ok := index.search[search]
|
|
if ok {
|
|
return len(entry.results), entry.results[i: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[search] = 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
|
|
}
|