github.com/m3db/m3@v1.5.0/src/m3ninx/index/segment/fst/fst_terms_postings_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 "github.com/m3db/m3/src/m3ninx/generated/proto/fswriter" 25 sgmt "github.com/m3db/m3/src/m3ninx/index/segment" 26 "github.com/m3db/m3/src/m3ninx/postings" 27 postingsroaring "github.com/m3db/m3/src/m3ninx/postings/roaring" 28 "github.com/m3dbx/pilosa/roaring" 29 ) 30 31 // postingsIterRoaringPoolingConfig uses a configuration that avoids allocating 32 // any containers in the roaring bitmap, since these roaring bitmaps are backed 33 // by mmaps and don't have any native containers themselves. 34 var postingsIterRoaringPoolingConfig = roaring.ContainerPoolingConfiguration{ 35 MaxArraySize: 0, 36 MaxRunsSize: 0, 37 AllocateBitmap: false, 38 MaxCapacity: 0, 39 MaxKeysAndContainersSliceLength: 128 * 10, 40 } 41 42 type fstTermsPostingsIter struct { 43 bitmap *roaring.Bitmap 44 postings postings.List 45 46 seg *fsSegment 47 termsIter *fstTermsIter 48 currTerm []byte 49 err error 50 } 51 52 func newFSTTermsPostingsIter() *fstTermsPostingsIter { 53 bitmap := roaring.NewBitmapWithPooling(postingsIterRoaringPoolingConfig) 54 i := &fstTermsPostingsIter{ 55 bitmap: bitmap, 56 postings: postingsroaring.NewPostingsListFromBitmap(bitmap), 57 } 58 i.clear() 59 return i 60 } 61 62 var _ sgmt.TermsIterator = &fstTermsPostingsIter{} 63 64 func (f *fstTermsPostingsIter) clear() { 65 f.bitmap.Reset() 66 f.seg = nil 67 f.termsIter = nil 68 f.currTerm = nil 69 f.err = nil 70 } 71 72 func (f *fstTermsPostingsIter) reset( 73 seg *fsSegment, 74 termsIter *fstTermsIter, 75 ) { 76 f.clear() 77 78 f.seg = seg 79 f.termsIter = termsIter 80 } 81 82 func (f *fstTermsPostingsIter) Empty() bool { 83 return f.termsIter.Empty() 84 } 85 86 func (f *fstTermsPostingsIter) Next() bool { 87 if f.err != nil { 88 return false 89 } 90 91 next := f.termsIter.Next() 92 if !next { 93 return false 94 } 95 96 f.currTerm = f.termsIter.Current() 97 currOffset := f.termsIter.CurrentOffset() 98 99 f.seg.RLock() 100 if f.termsIter.opts.fieldsFST { 101 var fieldsData fswriter.FieldData 102 fieldsData, f.err = f.seg.unmarshalFieldDataNotClosedMaybeFinalizedWithRLock(currOffset) 103 currOffset = fieldsData.FieldPostingsListOffset 104 } 105 if f.err == nil { 106 // Only attempt if the previous unmarshal definitely succeeded 107 // if we are operating on a fields FST. 108 f.err = f.seg.unmarshalPostingsListBitmapNotClosedMaybeFinalizedWithLock(f.bitmap, 109 currOffset) 110 } 111 f.seg.RUnlock() 112 113 return f.err == nil 114 } 115 116 func (f *fstTermsPostingsIter) Current() ([]byte, postings.List) { 117 return f.currTerm, f.postings 118 } 119 120 func (f *fstTermsPostingsIter) Err() error { 121 return f.err 122 } 123 124 func (f *fstTermsPostingsIter) Close() error { 125 var err error 126 if f.termsIter != nil { 127 err = f.termsIter.Close() 128 } 129 f.clear() 130 return err 131 }