This commit is contained in:
Mike Farah 2021-01-18 10:15:31 +11:00
parent c63801a8a5
commit 76bd1896e9
4 changed files with 44 additions and 27 deletions

View File

@ -15,6 +15,9 @@ type CandidateNode struct {
Document uint // the document index of this node
Filename string
FileIndex int
// when performing op against all nodes given, this will treat all the nodes as one
// (e.g. top level cross document merge). This property does not propegate to child nodes.
EvaluateTogether bool
}
func (n *CandidateNode) GetKey() string {

View File

@ -10,38 +10,49 @@ import (
type crossFunctionCalculation func(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error)
func crossFunction(d *dataTreeNavigator, matchingNodes *list.List, expressionNode *ExpressionNode, calculation crossFunctionCalculation) (*list.List, error) {
func doCrossFunc(d *dataTreeNavigator, contextList *list.List, expressionNode *ExpressionNode, calculation crossFunctionCalculation) (*list.List, error) {
var results = list.New()
lhs, err := d.GetMatchingNodes(contextList, expressionNode.Lhs)
if err != nil {
return nil, err
}
log.Debugf("crossFunction LHS len: %v", lhs.Len())
rhs, err := d.GetMatchingNodes(contextList, expressionNode.Rhs)
if err != nil {
return nil, err
}
for el := lhs.Front(); el != nil; el = el.Next() {
lhsCandidate := el.Value.(*CandidateNode)
for rightEl := rhs.Front(); rightEl != nil; rightEl = rightEl.Next() {
log.Debugf("Applying calc")
rhsCandidate := rightEl.Value.(*CandidateNode)
resultCandidate, err := calculation(d, lhsCandidate, rhsCandidate)
if err != nil {
return nil, err
}
results.PushBack(resultCandidate)
}
}
return results, nil
}
func crossFunction(d *dataTreeNavigator, matchingNodes *list.List, expressionNode *ExpressionNode, calculation crossFunctionCalculation) (*list.List, error) {
var results = list.New()
for matchEl := matchingNodes.Front(); matchEl != nil; matchEl = matchEl.Next() {
contextList := nodeToMap(matchEl.Value.(*CandidateNode))
lhs, err := d.GetMatchingNodes(contextList, expressionNode.Lhs)
if err != nil {
return nil, err
}
log.Debugf("crossFunction LHS len: %v", lhs.Len())
rhs, err := d.GetMatchingNodes(contextList, expressionNode.Rhs)
innerResults, err := doCrossFunc(d, contextList, expressionNode, calculation)
if err != nil {
return nil, err
}
for el := lhs.Front(); el != nil; el = el.Next() {
lhsCandidate := el.Value.(*CandidateNode)
for rightEl := rhs.Front(); rightEl != nil; rightEl = rightEl.Next() {
log.Debugf("Applying calc")
rhsCandidate := rightEl.Value.(*CandidateNode)
resultCandidate, err := calculation(d, lhsCandidate, rhsCandidate)
if err != nil {
return nil, err
}
results.PushBack(resultCandidate)
}
}
results.PushBackList(innerResults)
}

View File

@ -12,6 +12,8 @@ import (
// d0a d1a d0b d1b
// run it for (d0a d1a) x (d0b d1b) - noting that we dont do (d0a x d1a) nor (d0b d1b)
// I think this will work for eval-all correctly then..
//alternative, like jq, eval-all puts all docs in an single array.
var multiplyOperatorScenarios = []expressionScenario{
{
skipDoc: true,
@ -25,7 +27,7 @@ var multiplyOperatorScenarios = []expressionScenario{
skipDoc: true,
document: `a: {also: [1]}`,
document2: `b: {also: me}`,
expression: `. * {"a" : .b}`,
expression: `.a * .b`,
expected: []string{
"D0, P[], (!!map)::{a: {also: me}, b: {also: me}}\n",
},

View File

@ -36,10 +36,11 @@ func readDocuments(reader io.Reader, filename string, fileIndex int) (*list.List
return nil, errorReading
}
candidateNode := &CandidateNode{
Document: currentIndex,
Filename: filename,
Node: &dataBucket,
FileIndex: fileIndex,
Document: currentIndex,
Filename: filename,
Node: &dataBucket,
FileIndex: fileIndex,
EvaluateTogether: true,
}
inputList.PushBack(candidateNode)