Skip to content

Commit adb800c

Browse files
committed
get rule values in parallel
1 parent 40fdc8c commit adb800c

File tree

4 files changed

+40
-9
lines changed

4 files changed

+40
-9
lines changed

querybuilder/operator/equal_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ func TestEqual(t *testing.T) {
1818
{value: 1.55, input: 1.56, want: false},
1919
}
2020

21+
// testar nil
22+
2123
for _, input := range inputs {
2224
got := Equal.Evaluate(input.value, input.input)
2325
if got != input.want {

querybuilder/operator/operator.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Operator package contains the operators used in rules
12
// Reference: https://golang.org/ref/spec#Comparison_operators
23
package operator
34

@@ -8,10 +9,13 @@ type Operator struct {
89

910
var operators = make(map[string]*Operator)
1011

12+
// AddOperator allow add operator in the operators collection
13+
// This method should be called in init function
1114
func AddOperator(opr *Operator) {
1215
operators[opr.Name] = opr
1316
}
1417

18+
// GetOperator get the operator by name
1519
func GetOperator(name string) (*Operator, bool) {
1620
opr, ok := operators[name]
1721
return opr, ok

querybuilder/rule.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package querybuilder
33
import (
44
"reflect"
55
"strings"
6+
"sync"
67

78
"github.com/enjoei/pkg/querybuilder/operator"
89
)
@@ -16,33 +17,57 @@ type Rule struct {
1617
Value interface{}
1718
}
1819

20+
// Evaluate function checks whether the dataset matches with rule
1921
func (r *Rule) Evaluate(dataset map[string]interface{}) bool {
22+
var wg sync.WaitGroup
23+
var input, value interface{}
24+
2025
opr, ok := operator.GetOperator(r.Operator)
2126
if !ok {
2227
return false
2328
}
2429

25-
return opr.Evaluate(r.getInputValue(dataset), r.getValue())
30+
wg.Add(2)
31+
go func() {
32+
input = r.getInputValue(dataset)
33+
wg.Done()
34+
}()
35+
36+
go func() {
37+
value = r.getValue()
38+
wg.Done()
39+
}()
40+
41+
wg.Wait()
42+
return opr.Evaluate(input, value)
2643
}
2744

2845
func (r *Rule) getValue() interface{} {
2946
return r.parseValue(r.Value)
3047
}
3148

3249
func (r *Rule) getInputValue(dataset map[string]interface{}) interface{} {
50+
var rdataset = make(map[string]interface{})
3351
var result interface{}
3452
var ok bool
53+
54+
for k, v := range dataset {
55+
rdataset[k] = v
56+
}
57+
3558
field := strings.Split(r.Field, ".")
3659
steps := len(field)
3760

3861
for i := 0; i < steps; i++ {
39-
result, ok = dataset[field[i]]
62+
result, ok = rdataset[field[i]]
4063
if !ok {
4164
return nil
4265
}
4366

4467
rresult := reflect.ValueOf(result)
45-
if rresult.Kind() == reflect.Slice && i != (steps-1) {
68+
if rresult.Kind() == reflect.Map {
69+
rdataset = result.(map[string]interface{})
70+
} else if rresult.Kind() == reflect.Slice && i != (steps-1) {
4671
result = rresult.Index(0)
4772
}
4873

querybuilder/rule_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ func TestRuleEvaluate(t *testing.T) {
88
want bool
99
}{
1010
{&Rule{ID: "float_equal", Field: "float_equal", Type: "double", Input: "text", Operator: "equal", Value: 1.2}, true},
11-
{&Rule{ID: "float_equal_f", Field: "float_equal_f", Type: "double", Input: "text", Operator: "equal", Value: 1.3}, false},
11+
{&Rule{ID: "float_equal_f", Field: "float_equal", Type: "double", Input: "text", Operator: "equal", Value: 1.3}, false},
12+
{&Rule{ID: "float_field_equal", Field: "float_field.equal", Type: "double", Input: "text", Operator: "equal", Value: 3.7}, true},
1213
{&Rule{ID: "int_greater", Field: "int_greater", Type: "integer", Input: "text", Operator: "greater", Value: 1.0}, true},
13-
{&Rule{ID: "int_greater_f", Field: "int_greater_f", Type: "integer", Input: "text", Operator: "greater", Value: 3.0}, false},
14+
{&Rule{ID: "int_greater_f", Field: "int_greater", Type: "integer", Input: "text", Operator: "greater", Value: 3.0}, false},
1415
{&Rule{ID: "int_not_field", Field: "int_not_field", Type: "integer", Input: "text", Operator: "greater", Value: 2.0}, false},
1516
}
1617

1718
dataset := map[string]interface{}{
18-
"float_equal": 1.2,
19-
"float_equal_f": 1.2,
20-
"int_greater": 2.0,
21-
"int_greater_f": 2.0,
19+
"float_equal": 1.2,
20+
"int_greater": 2.0,
21+
"float_field": map[string]interface{}{"equal": 3.7, "greater": 5.0},
2222
}
2323

2424
for _, i := range inputs {

0 commit comments

Comments
 (0)