github.com/m3db/m3@v1.5.0/src/m3ninx/index/segment/fst/fst_terms_iterator.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 fst
    22  
    23  import (
    24  	sgmt "github.com/m3db/m3/src/m3ninx/index/segment"
    25  	xerrors "github.com/m3db/m3/src/x/errors"
    26  
    27  	"github.com/m3dbx/vellum"
    28  )
    29  
    30  type fstTermsIterOpts struct {
    31  	seg         *fsSegment
    32  	fst         *vellum.FST
    33  	finalizeFST bool
    34  	fieldsFST   bool
    35  }
    36  
    37  func (o fstTermsIterOpts) Close() error {
    38  	if o.finalizeFST && o.fst != nil {
    39  		return o.fst.Close()
    40  	}
    41  	return nil
    42  }
    43  
    44  func newFSTTermsIter() *fstTermsIter {
    45  	i := &fstTermsIter{iter: new(vellum.FSTIterator)}
    46  	i.clear()
    47  	return i
    48  }
    49  
    50  type fstTermsIter struct {
    51  	iter         *vellum.FSTIterator
    52  	opts         fstTermsIterOpts
    53  	err          error
    54  	done         bool
    55  	firstNext    bool
    56  	current      []byte
    57  	currentValue uint64
    58  }
    59  
    60  var _ sgmt.OrderedBytesIterator = &fstTermsIter{}
    61  
    62  func (f *fstTermsIter) clear() {
    63  	f.opts = fstTermsIterOpts{}
    64  	f.err = nil
    65  	f.done = false
    66  	f.firstNext = true
    67  	f.current = nil
    68  	f.currentValue = 0
    69  }
    70  
    71  func (f *fstTermsIter) reset(opts fstTermsIterOpts) {
    72  	f.clear()
    73  	f.opts = opts
    74  }
    75  
    76  func (f *fstTermsIter) handleIterErr(err error) {
    77  	if err == vellum.ErrIteratorDone {
    78  		f.done = true
    79  	} else {
    80  		f.err = err
    81  	}
    82  }
    83  
    84  func (f *fstTermsIter) Next() bool {
    85  	if f.done || f.err != nil {
    86  		return false
    87  	}
    88  
    89  	f.opts.seg.RLock()
    90  	defer f.opts.seg.RUnlock()
    91  	if f.opts.seg.finalized {
    92  		f.err = errReaderFinalized
    93  		return false
    94  	}
    95  
    96  	if f.firstNext {
    97  		f.firstNext = false
    98  		if err := f.iter.Reset(f.opts.fst, nil, nil, nil); err != nil {
    99  			f.handleIterErr(err)
   100  			return false
   101  		}
   102  	} else {
   103  		if err := f.iter.Next(); err != nil {
   104  			f.handleIterErr(err)
   105  			return false
   106  		}
   107  	}
   108  
   109  	f.current, f.currentValue = f.iter.Current()
   110  	return true
   111  }
   112  
   113  func (f *fstTermsIter) CurrentOffset() uint64 {
   114  	return f.currentValue
   115  }
   116  
   117  func (f *fstTermsIter) Empty() bool {
   118  	return f.Len() == 0
   119  }
   120  
   121  func (f *fstTermsIter) Current() []byte {
   122  	return f.current
   123  }
   124  
   125  func (f *fstTermsIter) Err() error {
   126  	return f.err
   127  }
   128  
   129  func (f *fstTermsIter) Len() int {
   130  	return f.opts.fst.Len()
   131  }
   132  
   133  func (f *fstTermsIter) Close() error {
   134  	var multiErr xerrors.MultiError
   135  	multiErr = multiErr.Add(f.iter.Close())
   136  	multiErr = multiErr.Add(f.opts.Close())
   137  	f.clear()
   138  	return multiErr.FinalError()
   139  }