// findTimeSeries searches the supplied engine over the supplied key range, // identifying time series which have stored data in the range, along with the // resolutions at which time series data is stored. A unique name/resolution // pair will only be identified once, even if the range contains keys for that // name/resolution pair at multiple timestamps or from multiple sources. // // An engine snapshot is used, rather than a client, because this function is // intended to be called by a storage queue which can inspect the local data for // a single range without the need for expensive network calls. func findTimeSeries( snapshot engine.Reader, startKey, endKey roachpb.RKey, now hlc.Timestamp, ) ([]timeSeriesResolutionInfo, error) { var results []timeSeriesResolutionInfo iter := snapshot.NewIterator(false) defer iter.Close() // Set start boundary for the search, which is the lesser of the range start // key and the beginning of time series data. start := engine.MakeMVCCMetadataKey(startKey.AsRawKey()) next := engine.MakeMVCCMetadataKey(keys.TimeseriesPrefix) if next.Less(start) { next = start } // Set end boundary for the search, which is the lesser of the range end key // and the end of time series data. end := engine.MakeMVCCMetadataKey(endKey.AsRawKey()) lastTS := engine.MakeMVCCMetadataKey(keys.TimeseriesPrefix.PrefixEnd()) if lastTS.Less(end) { end = lastTS } thresholds := computeThresholds(now.WallTime) for iter.Seek(next); iter.Valid() && iter.Less(end); iter.Seek(next) { foundKey := iter.Key().Key // Extract the name and resolution from the discovered key. name, _, res, tsNanos, err := DecodeDataKey(foundKey) if err != nil { return nil, err } // Skip this time series if there's nothing to prune. We check the // oldest (first) time series record's timestamp against the // pruning threshold. if threshold, ok := thresholds[res]; !ok || threshold > tsNanos { results = append(results, timeSeriesResolutionInfo{ Name: name, Resolution: res, }) } // Set 'next' is initialized to the next possible time series key // which could belong to a previously undiscovered time series. next = engine.MakeMVCCMetadataKey(makeDataKeySeriesPrefix(name, res).PrefixEnd()) } return results, nil }
// NewReplicaDataIterator creates a ReplicaDataIterator for the given replica. func NewReplicaDataIterator( d *roachpb.RangeDescriptor, e engine.Reader, replicatedOnly bool, ) *ReplicaDataIterator { rangeFunc := makeAllKeyRanges if replicatedOnly { rangeFunc = makeReplicatedKeyRanges } ri := &ReplicaDataIterator{ ranges: rangeFunc(d), iterator: e.NewIterator(false), } ri.iterator.Seek(ri.ranges[ri.curIndex].start) ri.advance() return ri }
// ComputeStatsForRange computes the stats for a given range by // iterating over all key ranges for the given range that should // be accounted for in its stats. func ComputeStatsForRange( d *roachpb.RangeDescriptor, e engine.Reader, nowNanos int64, ) (enginepb.MVCCStats, error) { iter := e.NewIterator(false) defer iter.Close() ms := enginepb.MVCCStats{} for _, r := range makeReplicatedKeyRanges(d) { msDelta, err := iter.ComputeStats(r.start, r.end, nowNanos) if err != nil { return enginepb.MVCCStats{}, err } ms.Add(msDelta) } return ms, nil }
// findTimeSeries searches the supplied engine over the supplied key range, // identifying time series which have stored data in the range, along with the // resolutions at which time series data is stored. A unique name/resolution // pair will only be identified once, even if the range contains keys for that // name/resolution pair at multiple timestamps or from multiple sources. // // An engine snapshot is used, rather than a client, because this function is // intended to be called by a storage queue which can inspect the local data for // a single range without the need for expensive network calls. func findTimeSeries( snapshot engine.Reader, startKey, endKey roachpb.RKey, ) ([]timeSeriesResolutionInfo, error) { var results []timeSeriesResolutionInfo iter := snapshot.NewIterator(false) defer iter.Close() // Set start boundary for the search, which is the lesser of the range start // key and the beginning of time series data. start := engine.MakeMVCCMetadataKey(startKey.AsRawKey()) next := engine.MakeMVCCMetadataKey(keys.TimeseriesPrefix) if next.Less(start) { next = start } // Set end boundary for the search, which is the lesser of the range end key // and the end of time series data. end := engine.MakeMVCCMetadataKey(endKey.AsRawKey()) lastTS := engine.MakeMVCCMetadataKey(keys.TimeseriesPrefix.PrefixEnd()) if lastTS.Less(end) { end = lastTS } for iter.Seek(next); iter.Valid() && iter.Less(end); iter.Seek(next) { foundKey := iter.Key().Key // Extract the name and resolution from the discovered key. name, _, res, _, err := DecodeDataKey(foundKey) if err != nil { return nil, err } results = append(results, timeSeriesResolutionInfo{ Name: name, Resolution: res, }) // Set 'next' is initialized to the next possible time series key // which could belong to a previously undiscovered time series. next = engine.MakeMVCCMetadataKey(makeDataKeySeriesPrefix(name, res).PrefixEnd()) } return results, nil }