github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/dbnode/integration/generate/generate.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 generate
    22  
    23  import (
    24  	"bytes"
    25  	"math/rand"
    26  	"sort"
    27  	"time"
    28  
    29  	"github.com/m3db/m3/src/dbnode/encoding/testgen"
    30  	"github.com/m3db/m3/src/dbnode/ts"
    31  	"github.com/m3db/m3/src/m3ninx/doc"
    32  	"github.com/m3db/m3/src/x/ident"
    33  	xtime "github.com/m3db/m3/src/x/time"
    34  )
    35  
    36  // Making SeriesBlock sortable
    37  func (l SeriesBlock) Len() int      { return len(l) }
    38  func (l SeriesBlock) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
    39  func (l SeriesBlock) Less(i, j int) bool {
    40  	return bytes.Compare(l[i].ID.Bytes(), l[j].ID.Bytes()) < 0
    41  }
    42  
    43  // Block generates a SeriesBlock based on provided config
    44  func Block(conf BlockConfig) SeriesBlock {
    45  	if conf.NumPoints <= 0 {
    46  		return nil
    47  	}
    48  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
    49  	testData := make(SeriesBlock, len(conf.IDs))
    50  
    51  	for i, name := range conf.IDs {
    52  		datapoints := make([]TestValue, 0, conf.NumPoints)
    53  		for j := 0; j < conf.NumPoints; j++ {
    54  			timestamp := conf.Start.Add(time.Duration(j) * time.Second)
    55  			if conf.AnnGen == nil {
    56  				datapoints = append(datapoints, TestValue{
    57  					Datapoint: ts.Datapoint{
    58  						TimestampNanos: timestamp,
    59  						Value:          testgen.GenerateFloatVal(r, 3, 1),
    60  					},
    61  				})
    62  			} else {
    63  				datapoints = append(datapoints, TestValue{
    64  					Datapoint: ts.Datapoint{
    65  						TimestampNanos: timestamp,
    66  						Value:          0,
    67  					},
    68  					Annotation: conf.AnnGen.Next(),
    69  				})
    70  			}
    71  		}
    72  		testData[i] = Series{
    73  			ID:   ident.StringID(name),
    74  			Tags: conf.Tags,
    75  			Data: datapoints,
    76  		}
    77  	}
    78  	return testData
    79  }
    80  
    81  // BlocksByStart generates a map of SeriesBlocks keyed by Start time
    82  // for the provided configs
    83  func BlocksByStart(confs []BlockConfig) SeriesBlocksByStart {
    84  	seriesMaps := make(map[xtime.UnixNano]SeriesBlock)
    85  	for _, conf := range confs {
    86  		key := conf.Start
    87  		seriesMaps[key] = append(seriesMaps[key], Block(conf)...)
    88  	}
    89  	return seriesMaps
    90  }
    91  
    92  // ToPointsByTime converts a SeriesBlocksByStart to SeriesDataPointsByTime
    93  func ToPointsByTime(seriesMaps SeriesBlocksByStart) SeriesDataPointsByTime {
    94  	var pointsByTime SeriesDataPointsByTime
    95  	for _, blks := range seriesMaps {
    96  		for _, blk := range blks {
    97  			for _, dp := range blk.Data {
    98  				pointsByTime = append(pointsByTime, SeriesDataPoint{
    99  					ID:    blk.ID,
   100  					Value: dp,
   101  				})
   102  			}
   103  		}
   104  	}
   105  	sort.Sort(pointsByTime)
   106  	return pointsByTime
   107  }
   108  
   109  // ToDocMetadata converts a SeriesBlock to []doc.Metadata
   110  func ToDocMetadata(seriesBlock SeriesBlock) []doc.Metadata {
   111  	docs := make([]doc.Metadata, 0)
   112  	for _, series := range seriesBlock {
   113  		fields := make([]doc.Field, 0)
   114  		for _, t := range series.Tags.Values() {
   115  			fields = append(fields, doc.Field{
   116  				Name:  t.Name.Bytes(),
   117  				Value: t.Value.Bytes(),
   118  			})
   119  		}
   120  		docs = append(docs, doc.Metadata{
   121  			ID:     series.ID.Bytes(),
   122  			Fields: fields,
   123  		})
   124  	}
   125  	return docs
   126  }
   127  
   128  // Dearrange de-arranges the list by the defined percent.
   129  func (l SeriesDataPointsByTime) Dearrange(percent float64) SeriesDataPointsByTime {
   130  	numDis := percent * float64(len(l))
   131  	disEvery := int(float64(len(l)) / numDis)
   132  
   133  	newArr := make(SeriesDataPointsByTime, 0, len(l))
   134  	for i := 0; i < len(l); i += disEvery {
   135  		ti := i + disEvery
   136  		if ti >= len(l) {
   137  			newArr = append(newArr, l[i:]...)
   138  			break
   139  		}
   140  
   141  		newArr = append(newArr, l[ti])
   142  		newArr = append(newArr, l[i:ti]...)
   143  	}
   144  
   145  	return newArr
   146  }
   147  
   148  // Making SeriesDataPointsByTimes sortable
   149  
   150  func (l SeriesDataPointsByTime) Len() int      { return len(l) }
   151  func (l SeriesDataPointsByTime) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
   152  func (l SeriesDataPointsByTime) Less(i, j int) bool {
   153  	if l[i].Value.TimestampNanos != l[j].Value.TimestampNanos {
   154  		return l[i].Value.TimestampNanos.Before(l[j].Value.TimestampNanos)
   155  	}
   156  	return bytes.Compare(l[i].ID.Bytes(), l[j].ID.Bytes()) < 0
   157  }