package web import ( "strconv" "bugabinga.net/luci/internal/history" "bugabinga.net/luci/internal/inbox" "bugabinga.net/luci/internal/proquint" "bugabinga.net/luci/internal/runstate" ) // shortener computes jj-style shortest unique prefixes: run ids to proquint // blocks, revisions to leading hex characters. type shortener struct { runShort map[string]string revShort map[string]string } func buildShortener(events []history.Event, pending []inbox.Pending, active []runstate.Active) shortener { ids := map[string]bool{} for _, event := range events { ids[event.RunID] = true } for _, current := range pending { ids[current.ID] = true } for _, current := range active { ids[current.RunID] = true } revs := map[string]bool{} for _, event := range events { if event.Rev != "" { revs[event.Rev] = true } } for _, current := range active { if current.Rev != "" { revs[current.Rev] = true } } runPrefixCounts := map[string]int{} encodedIDs := make(map[string]string, len(ids)) for id := range ids { encoded := proquint.Encode(parseID(id)) encodedIDs[id] = encoded for keep := 1; keep <= 4; keep++ { runPrefixCounts[encoded[:keep*6-1]]++ } } runShort := map[string]string{} for id, encoded := range encodedIDs { for keep := 1; keep <= 4; keep++ { prefix := encoded[:keep*6-1] if runPrefixCounts[prefix] == 1 { runShort[id] = prefix break } } } revPrefixCounts := map[string]int{} for rev := range revs { for length := 4; length <= len(rev); length++ { revPrefixCounts[rev[:length]]++ } } revShort := map[string]string{} for rev := range revs { for length := 4; length <= len(rev); length++ { prefix := rev[:length] if revPrefixCounts[prefix] == 1 { revShort[rev] = prefix break } } } return shortener{runShort: runShort, revShort: revShort} } func parseID(id string) int64 { value, err := strconv.ParseInt(id, 10, 64) if err != nil { return 0 } return value } // apply shortens one view in place, splitting full forms for emphasis. func (s shortener) apply(view *runView) { if short, ok := s.runShort[view.RunID]; ok && view.Pronounce != "" { view.PronounceShort = short if len(short) < len(view.Pronounce) { view.PronounceHead, view.PronounceTail = view.Pronounce[:len(short)], view.Pronounce[len(short):] } else { view.PronounceHead = view.Pronounce } } else if view.Pronounce != "" { view.PronounceShort, view.PronounceHead = view.Pronounce, view.Pronounce } rev := view.FullRev if rev != "" && rev != "\u2014" { if short, ok := s.revShort[rev]; ok { view.Rev = short if len(short) < len(rev) { view.FullHead, view.FullTail = rev[:len(short)], rev[len(short):] } else { view.FullHead = rev } } } }