| 270 | } |
| 271 | |
| 272 | func cacheKey(seed string, blockID ulid.ULID, ms ...*labels.Matcher) string { |
| 273 | slices.SortFunc(ms, func(i, j *labels.Matcher) int { |
| 274 | if i.Type != j.Type { |
| 275 | return int(i.Type - j.Type) |
| 276 | } |
| 277 | if i.Name != j.Name { |
| 278 | return strings.Compare(i.Name, j.Name) |
| 279 | } |
| 280 | if i.Value != j.Value { |
| 281 | return strings.Compare(i.Value, j.Value) |
| 282 | } |
| 283 | return 0 |
| 284 | }) |
| 285 | |
| 286 | const ( |
| 287 | typeLen = 2 |
| 288 | sepLen = 1 |
| 289 | ) |
| 290 | |
| 291 | size := len(seed) + len(blockID.String()) + 2*sepLen |
| 292 | for _, m := range ms { |
| 293 | size += len(m.Name) + len(m.Value) + typeLen + sepLen |
| 294 | } |
| 295 | sb := strings.Builder{} |
| 296 | sb.Grow(size) |
| 297 | sb.WriteString(seed) |
| 298 | sb.WriteByte('|') |
| 299 | sb.WriteString(blockID.String()) |
| 300 | sb.WriteByte('|') |
| 301 | for _, m := range ms { |
| 302 | sb.WriteString(m.Name) |
| 303 | sb.WriteString(m.Type.String()) |
| 304 | sb.WriteString(m.Value) |
| 305 | sb.WriteByte('|') |
| 306 | } |
| 307 | key := sb.String() |
| 308 | return key |
| 309 | } |
| 310 | |
| 311 | func isHeadBlock(blockID ulid.ULID) bool { |
| 312 | return blockID == rangeHeadULID || blockID == headULID |