github.com/m3db/m3@v1.5.0/src/query/graphite/common/bootstrap.go (about)

     1  // Copyright (c) 2019 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 common
    22  
    23  import (
    24  	"fmt"
    25  	"time"
    26  
    27  	"github.com/m3db/m3/src/query/graphite/ts"
    28  )
    29  
    30  // bootstrapWithIDs mocks fetches for now as the seriesList names are not actually IDs that are fetchable
    31  // NaN vals will be returned for the period of startTime to EndTime
    32  func bootstrapWithIDs(ctx *Context, seriesList ts.SeriesList, startTime, endTime time.Time) (ts.SeriesList, error) {
    33  	bootstrapList := make([]*ts.Series, seriesList.Len())
    34  
    35  	dur := int(endTime.Sub(startTime))
    36  	for i, series := range seriesList.Values {
    37  		numSteps := dur / (series.MillisPerStep() * 1000 * 1000) // convert to ns for step calculation
    38  		vals := ts.NewValues(ctx, series.MillisPerStep(), numSteps)
    39  		bootstrapList[i] = ts.NewSeries(ctx, series.Name(), startTime, vals)
    40  	}
    41  
    42  	seriesList.Values = bootstrapList
    43  	return seriesList, nil
    44  }
    45  
    46  // FetchWithBootstrap requests the same data but with a bootstrap period at the beginning.
    47  func FetchWithBootstrap(ctx *Context, seriesList ts.SeriesList, duration time.Duration) (ts.SeriesList, error) {
    48  	// Fetch bootstrapped series list between startTime and endTime
    49  	startTime := ctx.StartTime.Add(-duration)
    50  	endTime := ctx.StartTime
    51  	bootstrapList, err := bootstrapWithIDs(ctx, seriesList, startTime, endTime)
    52  	if err != nil {
    53  		return ts.NewSeriesList(), fmt.Errorf("unable to fetch bootstrap series, error=%s", err)
    54  	}
    55  
    56  	// Assemble the bootstrapped list
    57  	newSeriesList := make([]*ts.Series, seriesList.Len())
    58  	for i, bootstrap := range bootstrapList.Values {
    59  		original := seriesList.Values[i]
    60  		if bootstrap.MillisPerStep() < original.MillisPerStep() {
    61  			bootstrap, err = bootstrap.IntersectAndResize(bootstrap.StartTime(), bootstrap.EndTime(), original.MillisPerStep(), original.ConsolidationFunc())
    62  			if err != nil {
    63  				return ts.NewSeriesList(), err
    64  			}
    65  		}
    66  		ratio := bootstrap.MillisPerStep() / original.MillisPerStep()
    67  		numBootstrapValues := bootstrap.Len() * ratio
    68  		numCombinedValues := numBootstrapValues + original.Len()
    69  		values := ts.NewValues(ctx, original.MillisPerStep(), numCombinedValues)
    70  		for j := 0; j < bootstrap.Len(); j++ {
    71  			for k := j * ratio; k < (j+1)*ratio; k++ {
    72  				values.SetValueAt(k, bootstrap.ValueAt(j))
    73  			}
    74  		}
    75  		for j := numBootstrapValues; j < numCombinedValues; j++ {
    76  			values.SetValueAt(j, original.ValueAt(j-numBootstrapValues))
    77  		}
    78  		newSeries := ts.NewSeries(ctx, original.Name(), startTime, values)
    79  		newSeries.Specification = original.Specification
    80  		newSeriesList[i] = newSeries
    81  	}
    82  
    83  	seriesList.Values = newSeriesList
    84  	return seriesList, nil
    85  }