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  }