github.com/m3db/m3@v1.5.0/src/query/storage/m3/consolidators/series_consolidator.go (about) 1 // Copyright (c) 2018 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package consolidators 22 23 import ( 24 "math" 25 "time" 26 27 "github.com/m3db/m3/src/dbnode/ts" 28 xtime "github.com/m3db/m3/src/x/time" 29 ) 30 31 // SeriesLookbackConsolidator is a helper for consolidating a full single 32 // series. It has some differences with the step consolidator in that it 33 // collects points for a single series, and is reset when the next series 34 // needs to be consolidated. 35 type SeriesLookbackConsolidator struct { 36 lookbackDuration time.Duration 37 stepSize time.Duration 38 earliestLookback xtime.UnixNano 39 consolidated float64 40 datapoints []ts.Datapoint 41 fn ConsolidationFunc 42 } 43 44 // NewSeriesLookbackConsolidator creates a single value consolidator used for 45 // series iteration with a given lookback. 46 func NewSeriesLookbackConsolidator( 47 lookbackDuration, stepSize time.Duration, 48 startTime xtime.UnixNano, 49 fn ConsolidationFunc, 50 ) *SeriesLookbackConsolidator { 51 datapoints := make([]ts.Datapoint, 0, initLength) 52 return &SeriesLookbackConsolidator{ 53 lookbackDuration: lookbackDuration, 54 stepSize: stepSize, 55 earliestLookback: startTime.Add(-1 * lookbackDuration), 56 consolidated: math.NaN(), 57 datapoints: datapoints, 58 fn: fn, 59 } 60 } 61 62 // AddPoint adds a datapoint if it's within the valid time period; 63 // otherwise drops it silently, which is fine for consolidation. 64 func (c *SeriesLookbackConsolidator) AddPoint( 65 dp ts.Datapoint, 66 ) { 67 if dp.TimestampNanos.Before(c.earliestLookback) { 68 // this datapoint is too far in the past, it can be dropped. 69 return 70 } 71 72 c.datapoints = append(c.datapoints, dp) 73 } 74 75 // ConsolidateAndMoveToNext consolidates the current values and moves the 76 // consolidator to the next given value, purging stale values. 77 func (c *SeriesLookbackConsolidator) ConsolidateAndMoveToNext() float64 { 78 c.earliestLookback = c.earliestLookback.Add(c.stepSize) 79 c.consolidated = c.fn(c.datapoints) 80 c.datapoints = removeStale(c.earliestLookback, c.datapoints) 81 82 // Remove any datapoints not relevant to the next step now. 83 datapointsRelevant := removeStale(c.earliestLookback, c.datapoints) 84 if len(datapointsRelevant) > 0 { 85 // Move them back to the start of the slice to reuse the slice 86 // as best as possible. 87 c.datapoints = c.datapoints[:len(datapointsRelevant)] 88 copy(c.datapoints, datapointsRelevant) 89 } else { 90 // No relevant datapoints, repoint to the start of the buffer. 91 c.datapoints = c.datapoints[:0] 92 } 93 94 return c.consolidated 95 } 96 97 // Empty returns true if there are no datapoints in the consolidator. It 98 // is used to let consumers of the consolidators shortcircuit logic. 99 func (c *SeriesLookbackConsolidator) Empty() bool { 100 return len(c.datapoints) == 0 101 } 102 103 // Reset purges all points from the consolidator. This should be called 104 // when moving to the next series to consolidate. 105 func (c *SeriesLookbackConsolidator) Reset( 106 startTime xtime.UnixNano, 107 ) { 108 c.earliestLookback = startTime.Add(-1 * c.lookbackDuration) 109 c.datapoints = c.datapoints[:0] 110 }