github.com/m3db/m3@v1.5.0/src/query/storage/m3/consolidators/series_fetch_result.go (about)

     1  // Copyright (c) 2020 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  	"fmt"
    25  
    26  	"github.com/m3db/m3/src/dbnode/encoding"
    27  	"github.com/m3db/m3/src/query/block"
    28  	"github.com/m3db/m3/src/query/models"
    29  )
    30  
    31  // NewSeriesFetchResult creates a new series fetch result using the given
    32  // iterators.
    33  func NewSeriesFetchResult(
    34  	iters encoding.SeriesIterators,
    35  	tags []*models.Tags,
    36  	meta block.ResultMetadata,
    37  ) (SeriesFetchResult, error) {
    38  	if iters == nil || iters.Len() == 0 {
    39  		return NewEmptyFetchResult(meta), nil
    40  	}
    41  
    42  	if tags == nil {
    43  		tags = make([]*models.Tags, iters.Len())
    44  	}
    45  
    46  	// NB: explicitly set series count here to get the count post-duplication.
    47  	meta.FetchedSeriesCount = iters.Len()
    48  	return SeriesFetchResult{
    49  		Metadata: meta,
    50  		seriesData: seriesData{
    51  			seriesIterators: iters,
    52  			tags:            tags,
    53  		},
    54  	}, nil
    55  }
    56  
    57  // NewEmptyFetchResult creates a new empty series fetch result.
    58  func NewEmptyFetchResult(
    59  	meta block.ResultMetadata,
    60  ) SeriesFetchResult {
    61  	return SeriesFetchResult{
    62  		Metadata: meta,
    63  		seriesData: seriesData{
    64  			seriesIterators: nil,
    65  			tags:            []*models.Tags{},
    66  		},
    67  	}
    68  }
    69  
    70  // Verify verifies the fetch result is valid.
    71  func (r *SeriesFetchResult) Verify() error {
    72  	if r.seriesData.tags == nil || r.seriesData.seriesIterators == nil {
    73  		return nil
    74  	}
    75  
    76  	tagLen := len(r.seriesData.tags)
    77  	iterLen := r.seriesData.seriesIterators.Len()
    78  	if tagLen != iterLen {
    79  		return fmt.Errorf("tag length %d does not match iterator length %d",
    80  			tagLen, iterLen)
    81  	}
    82  
    83  	return nil
    84  }
    85  
    86  // Count returns the total number of contained series iterators.
    87  func (r *SeriesFetchResult) Count() int {
    88  	if r.seriesData.seriesIterators == nil {
    89  		return 0
    90  	}
    91  
    92  	return r.seriesData.seriesIterators.Len()
    93  }
    94  
    95  // Close no-ops; these should be closed by the enclosing iterator.
    96  func (r *SeriesFetchResult) Close() {
    97  
    98  }
    99  
   100  // IterTagsAtIndex returns the tag iterator and tags at the given index.
   101  func (r *SeriesFetchResult) IterTagsAtIndex(
   102  	idx int, tagOpts models.TagOptions,
   103  ) (encoding.SeriesIterator, models.Tags, error) {
   104  	tags := models.EmptyTags()
   105  	if idx < 0 || idx > len(r.seriesData.tags) {
   106  		return nil, tags, fmt.Errorf("series idx(%d) out of "+
   107  			"bounds %d ", idx, len(r.seriesData.tags))
   108  	}
   109  
   110  	iters := r.seriesData.seriesIterators.Iters()
   111  	if idx < len(r.seriesData.tags) {
   112  		if r.seriesData.tags[idx] == nil {
   113  			var err error
   114  			iter := iters[idx].Tags()
   115  			tags, err = FromIdentTagIteratorToTags(iter, tagOpts)
   116  			if err != nil {
   117  				return nil, models.EmptyTags(), err
   118  			}
   119  
   120  			iter.Rewind()
   121  			r.seriesData.tags[idx] = &tags
   122  		} else {
   123  			tags = *r.seriesData.tags[idx]
   124  		}
   125  	}
   126  
   127  	return iters[idx], tags, nil
   128  }
   129  
   130  // SeriesIterators returns the series iterators.
   131  func (r *SeriesFetchResult) SeriesIterators() []encoding.SeriesIterator {
   132  	if r.seriesData.seriesIterators == nil {
   133  		return []encoding.SeriesIterator{}
   134  	}
   135  
   136  	return r.seriesData.seriesIterators.Iters()
   137  }