github.com/m3db/m3@v1.5.0/src/query/block/lazy.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 block
    22  
    23  type lazyBlock struct {
    24  	block Block
    25  	opts  LazyOptions
    26  }
    27  
    28  // NewLazyBlock creates a lazy block wrapping another block with lazy options.
    29  func NewLazyBlock(block Block, opts LazyOptions) Block {
    30  	return &lazyBlock{
    31  		block: block,
    32  		opts:  opts,
    33  	}
    34  }
    35  
    36  func (b *lazyBlock) Info() BlockInfo {
    37  	return NewWrappedBlockInfo(BlockLazy, b.block.Info())
    38  }
    39  
    40  func (b *lazyBlock) Close() error { return b.block.Close() }
    41  
    42  func (b *lazyBlock) Meta() Metadata {
    43  	mt := b.opts.MetaTransform()
    44  	return mt(b.block.Meta())
    45  }
    46  
    47  // StepIter returns a StepIterator
    48  func (b *lazyBlock) StepIter() (StepIter, error) {
    49  	iter, err := b.block.StepIter()
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	return &lazyStepIter{
    55  		it:   iter,
    56  		opts: b.opts,
    57  	}, nil
    58  }
    59  
    60  type lazyStepIter struct {
    61  	it   StepIter
    62  	opts LazyOptions
    63  }
    64  
    65  func (it *lazyStepIter) Close()         { it.it.Close() }
    66  func (it *lazyStepIter) Err() error     { return it.it.Err() }
    67  func (it *lazyStepIter) StepCount() int { return it.it.StepCount() }
    68  func (it *lazyStepIter) Next() bool     { return it.it.Next() }
    69  
    70  func (it *lazyStepIter) SeriesMeta() []SeriesMeta {
    71  	mt := it.opts.SeriesMetaTransform()
    72  	return mt(it.it.SeriesMeta())
    73  }
    74  
    75  func (it *lazyStepIter) Current() Step {
    76  	var (
    77  		c        = it.it.Current()
    78  		tt, vt   = it.opts.TimeTransform(), it.opts.ValueTransform()
    79  		stepVals = c.Values()
    80  	)
    81  
    82  	vals := make([]float64, 0, len(stepVals))
    83  	for _, val := range stepVals {
    84  		vals = append(vals, vt(val))
    85  	}
    86  
    87  	return ColStep{
    88  		time:   tt(c.Time()),
    89  		values: vals,
    90  	}
    91  }
    92  
    93  func (b *lazyBlock) SeriesIter() (SeriesIter, error) {
    94  	seriesIter, err := b.block.SeriesIter()
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  
    99  	return &lazySeriesIter{
   100  		it:   seriesIter,
   101  		opts: b.opts,
   102  	}, nil
   103  }
   104  
   105  type lazySeriesIter struct {
   106  	it   SeriesIter
   107  	opts LazyOptions
   108  }
   109  
   110  func (it *lazySeriesIter) Close()           { it.it.Close() }
   111  func (it *lazySeriesIter) Err() error       { return it.it.Err() }
   112  func (it *lazySeriesIter) SeriesCount() int { return it.it.SeriesCount() }
   113  func (it *lazySeriesIter) Next() bool       { return it.it.Next() }
   114  
   115  func (it *lazySeriesIter) SeriesMeta() []SeriesMeta {
   116  	mt := it.opts.SeriesMetaTransform()
   117  	return mt(it.it.SeriesMeta())
   118  }
   119  
   120  func (it *lazySeriesIter) Current() UnconsolidatedSeries {
   121  	var (
   122  		c      = it.it.Current()
   123  		values = c.datapoints
   124  		tt, vt = it.opts.TimeTransform(), it.opts.ValueTransform()
   125  	)
   126  
   127  	for i, v := range values {
   128  		c.datapoints[i].Timestamp = tt(v.Timestamp)
   129  		c.datapoints[i].Value = vt(v.Value)
   130  	}
   131  
   132  	return c
   133  }
   134  
   135  func (b *lazyBlock) MultiSeriesIter(
   136  	concurrency int,
   137  ) ([]SeriesIterBatch, error) {
   138  	batches, err := b.block.MultiSeriesIter(concurrency)
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  
   143  	for i, batch := range batches {
   144  		batches[i].Iter = &lazySeriesIter{
   145  			it:   batch.Iter,
   146  			opts: b.opts,
   147  		}
   148  	}
   149  
   150  	return batches, err
   151  }