pkg/prompb/sort.go (66 lines of code) (raw):

package prompb import ( "bytes" "sort" ) type Labels []Label func (l Labels) Len() int { return len(l) } func (l Labels) Less(i, j int) bool { return labelLess(l[i].Name, l[j].Name) } func (l Labels) Swap(i, j int) { l[i], l[j] = l[j], l[i] } // IsSorted return true if the labels are sorted according to Sort. func IsSorted(l []*Label) bool { if len(l) == 1 { return true } for i := 1; i < len(l)-1; i++ { if !labelLess(l[i-1].Name, l[i].Name) { return false } } return true } // Sort sorts labels ensuring the __name__ is first the remaining labels or ordered by name. func Sort(l []*Label) { sort.Sort(labelSorter(l)) } type labelSorter []*Label func (ls labelSorter) Len() int { return len(ls) } func (ls labelSorter) Less(i, j int) bool { return labelLess(ls[i].Name, ls[j].Name) } func (ls labelSorter) Swap(i, j int) { ls[i], ls[j] = ls[j], ls[i] } func labelLess(a, b []byte) bool { if bytes.Equal(a, nameBytes) { return true } else if bytes.Equal(b, nameBytes) { return false } return CompareLower(a, b) < 0 } func CompareLower(sa, sb []byte) int { for len(sa) > 0 && len(sb) > 0 { ra := sa[0] rb := sb[0] if ra >= 'A' && ra <= 'Z' { ra += 'a' - 'A' } if rb >= 'A' && rb <= 'Z' { rb += 'a' - 'A' } if ra != rb { if ra < rb { return -1 } return 1 } sa = sa[1:] sb = sb[1:] } if len(sa) == len(sb) { return 0 } if len(sa) < len(sb) { return -1 } return 1 }