github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/index/fields.go (about) 1 package index 2 3 import ( 4 . "github.com/balzaczyy/golucene/core/index/model" 5 ) 6 7 type MultiFields struct { 8 subs []Fields 9 subSlices []ReaderSlice 10 termsMap map[string]Terms // synchronized 11 } 12 13 func NewMultiFields(subs []Fields, subSlices []ReaderSlice) MultiFields { 14 return MultiFields{subs, subSlices, make(map[string]Terms)} 15 } 16 17 func (mf MultiFields) Terms(field string) Terms { 18 if ans, ok := mf.termsMap[field]; ok { 19 return ans 20 } 21 22 // Lazy init: first time this field is requested, we 23 // create & add to terms: 24 subs2 := make([]Terms, 0) 25 slices2 := make([]ReaderSlice, 0) 26 27 // Gather all sub-readers that share this field 28 for i, v := range mf.subs { 29 terms := v.Terms(field) 30 if terms.Iterator != nil { 31 subs2 = append(subs2, terms) 32 slices2 = append(slices2, mf.subSlices[i]) 33 } 34 } 35 if len(subs2) == 0 { 36 return nil 37 // don't cache this case with an unbounded cache, since the number of fields that don't exist 38 // is unbounded. 39 } 40 ans := NewMultiTerms(subs2, slices2) 41 mf.termsMap[field] = ans 42 return ans 43 } 44 45 func GetMultiFields(r IndexReader) Fields { 46 // log.Print("Obtaining MultiFields from ", r) 47 leaves := r.Leaves() 48 switch len(leaves) { 49 case 0: 50 // log.Print("No fields are found.") 51 // no fields 52 return nil 53 case 1: 54 // already an atomic reader / reader with one leave 55 return leaves[0].Reader().(AtomicReader).Fields() 56 default: 57 fields := make([]Fields, 0) 58 slices := make([]ReaderSlice, 0) 59 for _, ctx := range leaves { 60 f := ctx.Reader().(AtomicReader).Fields() 61 if f == nil { 62 continue 63 } 64 fields = append(fields, f) 65 slices = append(slices, ReaderSlice{ctx.DocBase, r.MaxDoc(), len(fields)}) 66 } 67 // log.Printf("Found %v fields in %v slices.", len(fields), len(slices)) 68 switch len(fields) { 69 case 0: 70 return nil 71 case 1: 72 return fields[0] 73 default: 74 return NewMultiFields(fields, slices) 75 } 76 } 77 } 78 79 func GetMultiTerms(r IndexReader, field string) Terms { 80 // log.Printf("Loading field '%v' from %v", field, r) 81 fields := GetMultiFields(r) 82 if fields.Terms == nil { 83 return nil 84 } 85 return fields.Terms(field) 86 }