github.com/m3db/m3@v1.5.0/src/query/test/block.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 test
    22  
    23  import (
    24  	"errors"
    25  	"time"
    26  
    27  	"github.com/m3db/m3/src/query/block"
    28  	"github.com/m3db/m3/src/query/models"
    29  	"github.com/m3db/m3/src/query/storage"
    30  	"github.com/m3db/m3/src/query/ts"
    31  	xtime "github.com/m3db/m3/src/x/time"
    32  )
    33  
    34  type multiSeriesBlock struct {
    35  	consolidated     bool
    36  	lookbackDuration time.Duration
    37  	meta             block.Metadata
    38  	seriesList       ts.SeriesList
    39  	query            *storage.FetchQuery
    40  	enableBatched    bool
    41  }
    42  
    43  func newMultiSeriesBlock(
    44  	fetchResult *storage.FetchResult,
    45  	query *storage.FetchQuery,
    46  	lookbackDuration time.Duration,
    47  	enableBatched bool,
    48  ) block.Block {
    49  	meta := block.Metadata{
    50  		Bounds: models.Bounds{
    51  			Start:    xtime.ToUnixNano(query.Start),
    52  			Duration: query.End.Sub(query.Start),
    53  			StepSize: query.Interval,
    54  		},
    55  
    56  		ResultMetadata: fetchResult.Metadata,
    57  	}
    58  
    59  	return multiSeriesBlock{
    60  		seriesList:       fetchResult.SeriesList,
    61  		meta:             meta,
    62  		lookbackDuration: lookbackDuration,
    63  		enableBatched:    enableBatched,
    64  		query:            query,
    65  	}
    66  }
    67  
    68  func (m multiSeriesBlock) Meta() block.Metadata {
    69  	return m.meta
    70  }
    71  
    72  func (m multiSeriesBlock) StepCount() int {
    73  	// If series has fewer points then it should return NaNs
    74  	return m.meta.Bounds.Steps()
    75  }
    76  
    77  func (m multiSeriesBlock) StepIter() (block.StepIter, error) {
    78  	return nil, errors.New("step iterator is not supported by test block")
    79  }
    80  
    81  func (m multiSeriesBlock) SeriesIter() (block.SeriesIter, error) {
    82  	return newMultiSeriesBlockSeriesIter(m), nil
    83  }
    84  
    85  func (m multiSeriesBlock) MultiSeriesIter(
    86  	concurrency int,
    87  ) ([]block.SeriesIterBatch, error) {
    88  	if !m.enableBatched {
    89  		return nil,
    90  			errors.New("batched iterator is not supported by this test block")
    91  	}
    92  
    93  	batches := make([]ts.SeriesList, 0, concurrency)
    94  	for i := 0; i < concurrency; i++ {
    95  		batches = append(batches, make(ts.SeriesList, 0, 10))
    96  	}
    97  
    98  	// round-robin series.
    99  	for i, seriesList := range m.seriesList {
   100  		batches[i%concurrency] = append(batches[i%concurrency], seriesList)
   101  	}
   102  
   103  	seriesIterBatches := make([]block.SeriesIterBatch, 0, concurrency)
   104  	for _, batch := range batches {
   105  		insideBlock := newMultiSeriesBlock(&storage.FetchResult{
   106  			SeriesList: batch,
   107  			Metadata:   m.meta.ResultMetadata,
   108  		}, m.query, m.lookbackDuration, false)
   109  		it, err := insideBlock.SeriesIter()
   110  		if err != nil {
   111  			return nil, err
   112  		}
   113  
   114  		seriesIterBatches = append(seriesIterBatches, block.SeriesIterBatch{
   115  			Iter: it,
   116  			Size: len(batch),
   117  		})
   118  	}
   119  
   120  	return seriesIterBatches, nil
   121  }
   122  
   123  func (m multiSeriesBlock) SeriesMeta() []block.SeriesMeta {
   124  	metas := make([]block.SeriesMeta, len(m.seriesList))
   125  	for i, s := range m.seriesList {
   126  		metas[i].Tags = s.Tags
   127  		metas[i].Name = s.Name()
   128  	}
   129  
   130  	return metas
   131  }
   132  
   133  func (m multiSeriesBlock) Info() block.BlockInfo {
   134  	return block.NewBlockInfo(block.BlockTest)
   135  }
   136  
   137  // TODO: Actually free up resources
   138  func (m multiSeriesBlock) Close() error {
   139  	return nil
   140  }
   141  
   142  type multiSeriesBlockSeriesIter struct {
   143  	block        multiSeriesBlock
   144  	index        int
   145  	consolidated bool
   146  }
   147  
   148  func (m *multiSeriesBlockSeriesIter) SeriesMeta() []block.SeriesMeta {
   149  	return m.block.SeriesMeta()
   150  }
   151  
   152  func newMultiSeriesBlockSeriesIter(
   153  	block multiSeriesBlock,
   154  ) block.SeriesIter {
   155  	return &multiSeriesBlockSeriesIter{
   156  		block:        block,
   157  		index:        -1,
   158  		consolidated: block.consolidated,
   159  	}
   160  }
   161  
   162  func (m *multiSeriesBlockSeriesIter) SeriesCount() int {
   163  	return len(m.block.seriesList)
   164  }
   165  
   166  func (m *multiSeriesBlockSeriesIter) Next() bool {
   167  	m.index++
   168  	return m.index < m.SeriesCount()
   169  }
   170  
   171  func (m *multiSeriesBlockSeriesIter) Current() block.UnconsolidatedSeries {
   172  	s := m.block.seriesList[m.index]
   173  	return block.NewUnconsolidatedSeries(
   174  		s.Values().Datapoints(),
   175  		block.SeriesMeta{
   176  			Tags: s.Tags,
   177  			Name: s.Name(),
   178  		},
   179  		block.UnconsolidatedSeriesStats{Enabled: true},
   180  	)
   181  }
   182  
   183  func (m *multiSeriesBlockSeriesIter) Err() error {
   184  	return nil
   185  }
   186  
   187  func (m *multiSeriesBlockSeriesIter) Close() {
   188  }