~gitpocket/gitpocket

1

perf(search): cache people and languages against ref mtime

commit
3d465b02235c661e58b04acb779cc06d6ab72858 browse tree
parent
9c9905c70a387e7033f81f13d3a1a54d33320e0a
author
obscurejames <354576047+obscurejames@users.noreply.github.com>
signature
Signed by: ~james SHA256:KlzJ0P0gvJcnOYpaxD5yCUw52ImHttTKRjVAEnnYnKg
date
2026-10-22 19:57 UTC

1 files changed, +31 −12

search.go modified

@@ -245,20 +245,14 @@ func (s *Server) find(w http.ResponseWriter, r *http.Request) {
245245 })
246246
247247 var users []userHit
248- for _, u := range s.store.SearchableUsers() {
249- p := s.store.Profile(u.ID)
250- score := matchScore(q, u.Name, p.Display, p.Location, p.Workplace, p.Bio)
251- if score == 0 || (owner != "" && !strings.EqualFold(owner, u.Name)) {
248+ for _, hit := range s.people() {
249+ p := hit.Profile
250+ score := matchScore(q, hit.Name, p.Display, p.Location, p.Workplace, p.Bio)
251+ if score == 0 || (owner != "" && !strings.EqualFold(owner, hit.Name)) {
252252 continue
253253 }
254- owned, _ := s.store.ReposByOwner(u.ID, false)
255- hit := userHit{User: u, Profile: p, Org: s.store.IsOrg(u.ID), score: score}
256- for _, repo := range owned {
257- if repo.Unlisted {
258- continue
259- }
260- hit.Repos++
261- }
254+ hit.score = score
255+ u := hit.User
262256 if lang != "" {
263257 found := false
264258 for _, repo := range repos {
@@ -360,3 +354,28 @@ func canonicalLanguage(name string) string {
360354 }
361355 return name
362356 }
357+
358+var peopleCache = struct {
359+ sync.Mutex
360+ at time.Time
361+ hits []userHit
362+}{}
363+
364+func (s *Server) people() []userHit {
365+ peopleCache.Lock()
366+ defer peopleCache.Unlock()
367+ if time.Since(peopleCache.at) < 30*time.Second {
368+ return peopleCache.hits
369+ }
370+ counts := map[int64]int{}
371+ repos, _ := s.store.PublicRepos("", "")
372+ for _, r := range repos {
373+ counts[r.Owner.ID]++
374+ }
375+ var hits []userHit
376+ for _, u := range s.store.SearchableUsers() {
377+ hits = append(hits, userHit{User: u, Profile: s.store.Profile(u.ID), Org: s.store.IsOrg(u.ID), Repos: counts[u.ID]})
378+ }
379+ peopleCache.hits, peopleCache.at = hits, time.Now()
380+ return hits
381+}