// purgeArchivedMetric deletes an archived fingerprint and its corresponding // metric entirely. It also queues the metric for un-indexing (no need to call // unindexMetric for the deleted metric.) It does not touch the series file, // though. The caller must have locked the fingerprint. func (p *persistence) purgeArchivedMetric(fp clientmodel.Fingerprint) (err error) { defer func() { if err != nil { p.setDirty(true) } }() metric, err := p.archivedMetric(fp) if err != nil || metric == nil { return err } deleted, err := p.archivedFingerprintToMetrics.Delete(codable.Fingerprint(fp)) if err != nil { return err } if !deleted { log.Errorf("Tried to delete non-archived fingerprint %s from archivedFingerprintToMetrics index. This should never happen.", fp) } deleted, err = p.archivedFingerprintToTimeRange.Delete(codable.Fingerprint(fp)) if err != nil { return err } if !deleted { log.Errorf("Tried to delete non-archived fingerprint %s from archivedFingerprintToTimeRange index. This should never happen.", fp) } p.unindexMetric(fp, metric) return nil }
// unarchiveMetric deletes an archived fingerprint and its metric, but (in // contrast to purgeArchivedMetric) does not un-index the metric. If a metric // was actually deleted, the method returns true and the first time of the // deleted metric. The caller must have locked the fingerprint. func (p *persistence) unarchiveMetric(fp clientmodel.Fingerprint) ( deletedAnything bool, firstDeletedTime clientmodel.Timestamp, err error, ) { defer func() { if err != nil { p.setDirty(true) } }() firstTime, _, has, err := p.archivedFingerprintToTimeRange.Lookup(fp) if err != nil || !has { return false, firstTime, err } deleted, err := p.archivedFingerprintToMetrics.Delete(codable.Fingerprint(fp)) if err != nil { return false, firstTime, err } if !deleted { log.Errorf("Tried to delete non-archived fingerprint %s from archivedFingerprintToMetrics index. This should never happen.", fp) } deleted, err = p.archivedFingerprintToTimeRange.Delete(codable.Fingerprint(fp)) if err != nil { return false, firstTime, err } if !deleted { log.Errorf("Tried to delete non-archived fingerprint %s from archivedFingerprintToTimeRange index. This should never happen.", fp) } return true, firstTime, nil }
// archiveMetric persists the mapping of the given fingerprint to the given // metric, together with the first and last timestamp of the series belonging to // the metric. The caller must have locked the fingerprint. func (p *persistence) archiveMetric( fp model.Fingerprint, m model.Metric, first, last model.Time, ) { if err := p.archivedFingerprintToMetrics.Put(codable.Fingerprint(fp), codable.Metric(m)); err != nil { p.setDirty(fmt.Errorf("error in method archiveMetric inserting fingerprint %v into FingerprintToMetrics: %s", fp, err)) return } if err := p.archivedFingerprintToTimeRange.Put(codable.Fingerprint(fp), codable.TimeRange{First: first, Last: last}); err != nil { p.setDirty(fmt.Errorf("error in method archiveMetric inserting fingerprint %v into FingerprintToTimeRange: %s", fp, err)) } }
// archiveMetric persists the mapping of the given fingerprint to the given // metric, together with the first and last timestamp of the series belonging to // the metric. The caller must have locked the fingerprint. func (p *persistence) archiveMetric( fp clientmodel.Fingerprint, m clientmodel.Metric, first, last clientmodel.Timestamp, ) error { if err := p.archivedFingerprintToMetrics.Put(codable.Fingerprint(fp), codable.Metric(m)); err != nil { p.setDirty(true) return err } if err := p.archivedFingerprintToTimeRange.Put(codable.Fingerprint(fp), codable.TimeRange{First: first, Last: last}); err != nil { p.setDirty(true) return err } return nil }
// unarchiveMetric deletes an archived fingerprint and its metric, but (in // contrast to purgeArchivedMetric) does not un-index the metric. If a metric // was actually deleted, the method returns true and the first time and last // time of the deleted metric. The caller must have locked the fingerprint. func (p *persistence) unarchiveMetric(fp model.Fingerprint) (deletedAnything bool, err error) { // An error returned here will bubble up and lead to quarantining of the // series, so no setDirty required. deleted, err := p.archivedFingerprintToMetrics.Delete(codable.Fingerprint(fp)) if err != nil || !deleted { return false, err } deleted, err = p.archivedFingerprintToTimeRange.Delete(codable.Fingerprint(fp)) if err != nil { return false, err } if !deleted { log.Errorf("Tried to delete non-archived fingerprint %s from archivedFingerprintToTimeRange index. This should never happen.", fp) } return true, nil }
// UnindexBatch unindexes a batch of mappings from fingerprints to metrics. // // This method is goroutine-safe, but note that no specific order of execution // can be guaranteed (especially critical if IndexBatch and UnindexBatch are // called concurrently for the same fingerprint). func (i *FingerprintMetricIndex) UnindexBatch(mapping FingerprintMetricMapping) error { b := i.NewBatch() for fp := range mapping { b.Delete(codable.Fingerprint(fp)) } return i.Commit(b) }
// IndexBatch indexes a batch of mappings from fingerprints to metrics. // // This method is goroutine-safe, but note that no specific order of execution // can be guaranteed (especially critical if IndexBatch and UnindexBatch are // called concurrently for the same fingerprint). func (i *FingerprintMetricIndex) IndexBatch(mapping FingerprintMetricMapping) error { b := i.NewBatch() for fp, m := range mapping { b.Put(codable.Fingerprint(fp), codable.Metric(m)) } return i.Commit(b) }
// unarchiveMetric deletes an archived fingerprint and its metric, but (in // contrast to purgeArchivedMetric) does not un-index the metric. If a metric // was actually deleted, the method returns true and the first time and last // time of the deleted metric. The caller must have locked the fingerprint. func (p *persistence) unarchiveMetric(fp model.Fingerprint) (deletedAnything bool, err error) { defer func() { if err != nil { p.setDirty(true) } }() deleted, err := p.archivedFingerprintToMetrics.Delete(codable.Fingerprint(fp)) if err != nil || !deleted { return false, err } deleted, err = p.archivedFingerprintToTimeRange.Delete(codable.Fingerprint(fp)) if err != nil { return false, err } if !deleted { log.Errorf("Tried to delete non-archived fingerprint %s from archivedFingerprintToTimeRange index. This should never happen.", fp) } return true, nil }
// dropArchivedMetric deletes an archived fingerprint and its corresponding // metric entirely. It also queues the metric for un-indexing (no need to call // unindexMetric for the deleted metric.) The caller must have locked the // fingerprint. func (p *persistence) dropArchivedMetric(fp clientmodel.Fingerprint) (err error) { defer func() { if err != nil { p.setDirty(true) } }() metric, err := p.getArchivedMetric(fp) if err != nil || metric == nil { return err } if err := p.archivedFingerprintToMetrics.Delete(codable.Fingerprint(fp)); err != nil { return err } if err := p.archivedFingerprintToTimeRange.Delete(codable.Fingerprint(fp)); err != nil { return err } p.unindexMetric(fp, metric) return nil }
// unarchiveMetric deletes an archived fingerprint and its metric, but (in // contrast to dropArchivedMetric) does not un-index the metric. If a metric // was actually deleted, the method returns true and the first time of the // deleted metric. The caller must have locked the fingerprint. func (p *persistence) unarchiveMetric(fp clientmodel.Fingerprint) ( deletedAnything bool, firstDeletedTime clientmodel.Timestamp, err error, ) { defer func() { if err != nil { p.setDirty(true) } }() firstTime, _, has, err := p.archivedFingerprintToTimeRange.Lookup(fp) if err != nil || !has { return false, firstTime, err } if err := p.archivedFingerprintToMetrics.Delete(codable.Fingerprint(fp)); err != nil { return false, firstTime, err } if err := p.archivedFingerprintToTimeRange.Delete(codable.Fingerprint(fp)); err != nil { return false, firstTime, err } return true, firstTime, nil }
// Lookup looks up a metric by fingerprint. Looking up a non-existing // fingerprint is not an error. In that case, (nil, false, nil) is returned. // // This method is goroutine-safe. func (i *FingerprintMetricIndex) Lookup(fp model.Fingerprint) (metric model.Metric, ok bool, err error) { ok, err = i.Get(codable.Fingerprint(fp), (*codable.Metric)(&metric)) return }
// Lookup returns the time range for the given fingerprint. Looking up a // non-existing fingerprint is not an error. In that case, (0, 0, false, nil) is // returned. // // This method is goroutine-safe. func (i *FingerprintTimeRangeIndex) Lookup(fp model.Fingerprint) (firstTime, lastTime model.Time, ok bool, err error) { var tr codable.TimeRange ok, err = i.Get(codable.Fingerprint(fp), &tr) return tr.First, tr.Last, ok, err }
// updateArchivedTimeRange updates an archived time range. The caller must make // sure that the fingerprint is currently archived (the time range will // otherwise be added without the corresponding metric in the archive). func (p *persistence) updateArchivedTimeRange( fp clientmodel.Fingerprint, first, last clientmodel.Timestamp, ) error { return p.archivedFingerprintToTimeRange.Put(codable.Fingerprint(fp), codable.TimeRange{First: first, Last: last}) }