github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/for_result.go (about) 1 package expressions 2 3 import ( 4 "github.com/MontFerret/ferret/pkg/runtime/core" 5 "github.com/MontFerret/ferret/pkg/runtime/values" 6 ) 7 8 type ForResult struct { 9 itemList *values.Array 10 hashTable map[uint64]bool 11 distinct bool 12 spread bool 13 passThrough bool 14 } 15 16 func NewForResult(capacity int) *ForResult { 17 res := new(ForResult) 18 res.itemList = values.NewArray(capacity) 19 20 return res 21 } 22 23 func (f *ForResult) Distinct(distinct bool) *ForResult { 24 f.distinct = distinct 25 26 if f.distinct { 27 f.hashTable = make(map[uint64]bool) 28 } else { 29 f.hashTable = nil 30 } 31 32 return f 33 } 34 35 func (f *ForResult) Spread(spread bool) *ForResult { 36 f.spread = spread 37 38 return f 39 } 40 41 func (f *ForResult) PassThrough(passThrough bool) *ForResult { 42 f.passThrough = passThrough 43 44 return f 45 } 46 47 func (f *ForResult) Push(value core.Value) { 48 if f.passThrough { 49 return 50 } 51 52 if f.distinct { 53 // We need to check whether the value already exists in the result set 54 hash := value.Hash() 55 56 // if already exists 57 // we skip it 58 if f.hashTable[hash] { 59 return 60 } 61 62 f.hashTable[hash] = true 63 } 64 65 if !f.spread { 66 f.itemList.Push(value) 67 68 return 69 } 70 71 elements, ok := value.(*values.Array) 72 73 if !ok { 74 f.itemList.Push(value) 75 76 return 77 } 78 79 elements.ForEach(func(i core.Value, _ int) bool { 80 f.Push(i) 81 82 return true 83 }) 84 } 85 86 func (f *ForResult) ToArray() *values.Array { 87 return f.itemList 88 }