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 }