Zhipeng Xie 4335408875 atune: init code
upload code to gitee

Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
2019-11-13 17:14:15 +08:00

344 lines
7.5 KiB
Go

package yql
import (
"math"
"sort"
"strconv"
)
const (
opEqual = "="
opNotEqual = "!="
opLarger = ">"
opLargerEqual = ">="
opLess = "<"
opLessEqual = "<="
opInter = "∩"
opNotInter = "!∩"
opIn = "in"
opNotIn = "!in"
)
const (
epsilon = float64(1e-10)
)
func cmpInt(actual, expect int64, op string) bool {
switch op {
case opEqual,opIn:
return actual == expect
case opNotEqual,opNotIn:
return actual != expect
case opLarger:
return actual > expect
case opLargerEqual:
return actual >= expect
case opLess:
return actual < expect
case opLessEqual:
return actual <= expect
default:
return false
}
}
func cmpFloat(actual, expect float64, op string) bool {
switch op {
case opEqual:
return floatEqual(actual, expect)
case opNotEqual:
return !floatEqual(actual, expect)
case opLarger:
return actual > expect
case opLargerEqual:
return !(actual < expect)
case opLess:
return actual < expect
case opLessEqual:
return floatLessEqual(actual, expect)
default:
return false
}
}
func cmpStr(actual, expect string, op string) bool {
switch op {
case opEqual,opIn:
return actual == expect
case opNotEqual,opNotIn:
return actual != expect
case opLarger:
return actual > expect
case opLargerEqual:
return actual >= expect
case opLess:
return actual < expect
case opLessEqual:
return actual <= expect
default:
return false
}
}
func cmpBool(actual, expect bool, op string) bool {
switch op {
case opEqual:
return actual == expect
case opNotEqual:
return actual != expect
default:
return false
}
}
func compareSet(actual interface{}, expect []string, op string) bool {
switch op {
case opEqual, opNotEqual, opInter, opNotInter, opIn, opNotIn:
default:
return false
}
switch actualArr := actual.(type) {
case int:
return cmpIntSet([]int64{int64(actualArr)}, expect, op)
case int64:
return cmpIntSet([]int64{actualArr}, expect, op)
case float64:
return cmpFloatSet([]float64{actualArr}, expect, op)
case string:
return cmpStringSet([]string{actualArr}, expect, op)
case []int:
return cmpIntSet(intArr2i64Arr(actualArr), expect, op)
case []int64:
return cmpIntSet(actualArr, expect, op)
case []float64:
return cmpFloatSet(actualArr, expect, op)
case []string:
return cmpStringSet(actualArr, expect, op)
default:
return false
}
}
func intArr2i64Arr(arr []int) []int64 {
length := len(arr)
if length == 0 {
return nil
}
res := make([]int64, 0, length)
for _, v := range arr {
res = append(res, int64(v))
}
return res
}
var intSetCmpFunc = map[string]func([]int64, []int64) bool{
opInter: intSetInter,
opNotInter: intSetNotInter,
opIn: intSetBelong,
opNotIn: intSetNotBelong,
}
func cmpIntSet(actualVals []int64, expectVals []string, op string) bool {
expectArr := make([]int64, 0, len(expectVals))
for _, expect := range expectVals {
v, err := strconv.ParseInt(removeQuote(expect), 10, 64)
if nil != err {
return false
}
expectArr = append(expectArr, v)
}
cmp, ok := intSetCmpFunc[op]
if ok {
return cmp(actualVals, expectArr)
}
return false
}
var floatSetCmpFunc = map[string]func([]float64, []float64) bool{
opInter: floatSetInter,
opNotInter: floatSetNotInter,
opIn: floatSetBelong,
opNotIn: floatSetNotBelong,
}
func cmpFloatSet(actualVals []float64, expectVals []string, op string) bool {
expectArr := make([]float64, 0, len(expectVals))
for _, expect := range expectVals {
v, err := strconv.ParseFloat(removeQuote(expect), 64)
if nil != err {
return false
}
expectArr = append(expectArr, v)
}
cmp, ok := floatSetCmpFunc[op]
if ok {
return cmp(actualVals, expectArr)
}
return false
}
var stringSetCmpFunc = map[string]func([]string, []string) bool{
opInter: strSetInter,
opNotInter: strSetNotInter,
opIn: strSetBelong,
opNotIn: strSetNotBelong,
}
func cmpStringSet(actual []string, expect []string, op string) bool {
cmp, ok := stringSetCmpFunc[op]
if !ok {
return false
}
expectVals := make([]string, 0, len(expect))
for _, v := range expect {
expectVals = append(expectVals, removeQuote(v))
}
return cmp(actual, expectVals)
}
func intSetBelong(actualVals []int64, expectVals []int64) bool {
length := len(expectVals)
if len(actualVals) == 0 || len(actualVals) > length {
return false
}
expectArr := i64Arr(expectVals)
sort.Sort(expectArr)
for _, actual := range actualVals {
t := sort.Search(length, func(i int) bool {
return actual <= expectArr[i]
})
if t >= length || actual != expectArr[t] {
return false
}
}
return true
}
func intSetNotBelong(actualVals []int64, expectVals []int64) bool {
return !intSetBelong(actualVals, expectVals)
}
func intSetInter(actualVals []int64, expectVals []int64) bool {
length := len(expectVals)
if len(actualVals) == 0 || length == 0 {
return false
}
expectArr := i64Arr(expectVals)
sort.Sort(expectArr)
for _, actual := range actualVals {
t := sort.Search(length, func(i int) bool {
return actual <= expectArr[i]
})
if t < length && actual == expectArr[t] {
return true
}
}
return false
}
func intSetNotInter(actualVals []int64, expectVals []int64) bool {
return !intSetInter(actualVals, expectVals)
}
type i64Arr []int64
func (arr i64Arr) Len() int {
return len(arr)
}
func (arr i64Arr) Less(i, j int) bool {
return arr[i] < arr[j]
}
func (arr i64Arr) Swap(i, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
func floatSetBelong(actualVals []float64, expectVals []float64) bool {
length := len(expectVals)
if len(actualVals) == 0 || len(actualVals) > length {
return false
}
sort.Float64s(expectVals)
for _, actual := range actualVals {
t := sort.Search(length, func(i int) bool {
return floatLessEqual(actual, expectVals[i])
})
if t >= length || !floatEqual(actual, expectVals[t]) {
return false
}
}
return true
}
func floatSetNotBelong(actualVals []float64, expectVals []float64) bool {
return !floatSetBelong(actualVals, expectVals)
}
func floatSetInter(actualVals []float64, expectVals []float64) bool {
length := len(expectVals)
if len(actualVals) == 0 || length == 0 {
return false
}
sort.Float64s(expectVals)
for _, actual := range actualVals {
t := sort.Search(length, func(i int) bool {
return floatLessEqual(actual, expectVals[i])
})
if t < length && floatEqual(actual, expectVals[t]) {
return true
}
}
return false
}
func floatSetNotInter(actualVals []float64, expectVals []float64) bool {
return !floatSetInter(actualVals, expectVals)
}
func strSetBelong(actualVals []string, expectVals []string) bool {
length := len(expectVals)
if len(actualVals) == 0 || len(actualVals) > length {
return false
}
sort.Strings(expectVals)
for _, actual := range actualVals {
t := sort.SearchStrings(expectVals, actual)
if t >= length || actual != expectVals[t] {
return false
}
}
return true
}
func strSetNotBelong(actualVals []string, expectVals []string) bool {
return !strSetBelong(actualVals, expectVals)
}
func strSetInter(actualVals []string, expectVals []string) bool {
length := len(expectVals)
if len(actualVals) == 0 || length == 0 {
return false
}
sort.Strings(expectVals)
for _, actual := range actualVals {
t := sort.SearchStrings(expectVals, actual)
if t < length && actual == expectVals[t] {
return true
}
}
return false
}
func strSetNotInter(actualVals []string, expectVals []string) bool {
return !strSetInter(actualVals, expectVals)
}
func floatEqual(a, b float64) bool {
return math.Abs(a-b) < epsilon
}
func floatLessEqual(a, b float64) bool {
return a < b || floatEqual(a, b)
}