Repository: prometheus/alertmanager
File: inhibit/inhibit.go (Go)

Code before:
	for _, ln := range cr.Equal {
		equal[model.LabelName(ln)] = struct{}{}
	}

	rule := &InhibitRule{
		Name:           cr.Name,
		SourceMatchers: sourcem,
		TargetMatchers: targetm,
		Equal:          equal,
		scache:         store.NewAlerts(),
		sindex:         newIndex(),
	}

	if rule.Name == "" {
		// Set the name of the rule to its fingerprint.
		rule.Name = rule.fingerprint().String()
	}

	rule.scache.SetGCCallback(rule.gcCallback)

	return rule
}

// fingerprint returns the fingerprint of the inhibit rule.
func (r *InhibitRule) fingerprint() model.Fingerprint {
	sum := xxhash.New()
	fmt.Fprintf(sum, "%v\n", r.SourceMatchers)
	fmt.Fprintf(sum, "%v\n", r.TargetMatchers)
	fmt.Fprintf(sum, "%v", slices.Sorted(maps.Keys(r.Equal)))
	return model.Fingerprint(sum.Sum64())
}

// fingerprintEquals returns the fingerprint of the equal labels of the given label set.
func (r *InhibitRule) fingerprintEquals(lset model.LabelSet) model.Fingerprint {
	equalSet := model.LabelSet{}
	for n := range r.Equal {
		equalSet[n] = lset[n]
	}
	return equalSet.Fingerprint()
}

// updateIndex updates the source alert index if necessary.
func (r *InhibitRule) updateIndex(alert *types.Alert) {
	fp := alert.Fingerprint()
	// Calculate source labelset subset which is in equals.
	eq := r.fingerprintEquals(alert.Labels)

	// Check if the equal labelset is already in the index.
	indexed, ok := r.sindex.Get(eq)
	if !ok {
		// If not, add it.

Review comment (bug):
Since this is only loaded at config load time, do we need to use a third party library here?

~~What's wrong with using `model.FingerprintFromString()`?~~

Oops, that function is not what I was thinking.

Bah, it looks like the common/model hash function is not public.

Code after:
	rule := &InhibitRule{
		Name:           cr.Name,
		SourceMatchers: sourcem,
		TargetMatchers: targetm,
		Equal:          equal,
		scache:         store.NewAlerts(),
		sindex:         newIndex(),
	}

	rule.scache.SetGCCallback(rule.gcCallback)

	return rule
}

// fingerprintEquals returns the fingerprint of the equal labels of the given label set.
func (r *InhibitRule) fingerprintEquals(lset model.LabelSet) model.Fingerprint {
	equalSet := model.LabelSet{}
	for n := range r.Equal {
		equalSet[n] = lset[n]
	}
	return equalSet.Fingerprint()
}

// updateIndex updates the source alert index if necessary.
func (r *InhibitRule) updateIndex(alert *types.Alert) {
	fp := alert.Fingerprint()
	// Calculate source labelset subset which is in equals.
	eq := r.fingerprintEquals(alert.Labels)

	// Check if the equal labelset is already in the index.
	indexed, ok := r.sindex.Get(eq)
	if !ok {
		// If not, add it.
		r.sindex.Set(eq, fp)
		return
	}
	// If the indexed fingerprint is the same as the new fingerprint, do nothing.
	if indexed == fp {
		return
	}

	// New alert and existing index are not the same, compare them.
	existing, err := r.scache.Get(indexed)
	if err != nil {
		// failed to get the existing alert, overwrite the index.
		r.sindex.Set(eq, fp)
		return
	}

	// If the new alert resolves after the existing alert, replace the index.
	if existing.ResolvedAt(alert.EndsAt) {