Optimized the automated index fields matching

This commit is contained in:
Trial97
2021-02-03 16:22:05 +02:00
committed by Dan Christian Bogos
parent ccc894c93f
commit 0f967e4ac0
3 changed files with 18 additions and 99 deletions

View File

@@ -139,6 +139,7 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium
* [ApierS] Correct handle error in case of APIerSv1.GetActionTriggers
* [SessionS] Added extra condition to determine if the increment is considered the roundIncrement
* [SessionS] Cloned the charging interval added on EventCost merge
* [FilterS] Optimized the automated index fields matching
-- DanB <danb@cgrates.org> Wed, 19 Feb 2020 13:25:52 +0200

View File

@@ -232,18 +232,22 @@ func (ms MapStorage) GetKeys(nested bool, nestedLimit int, prefix string) (keys
return
}
for k, v := range ms { // in case of nested on false we take in consideraton the nestedLimit
keys = append(keys, prefix+k)
//keys = append(keys, prefix+k)
switch rv := v.(type) { // and for performance we only take in consideration a limited set of types for nested false
case dataStorage:
keys = append(keys, rv.GetKeys(nested, nestedLimit-1, prefix+k)...)
case map[string]interface{}:
keys = append(keys, MapStorage(rv).GetKeys(nested, nestedLimit-1, prefix+k)...)
case nil, int, int32, int64, uint32, uint64, bool, float32, float64, []uint8, time.Duration, time.Time, string:
keys = append(keys, prefix+k)
default:
keys = append(keys, prefix+k)
}
}
return
}
for k, v := range ms {
keys = append(keys, prefix+k)
//keys = append(keys, prefix+k)
switch rv := v.(type) {
case dataStorage:
keys = append(keys, rv.GetKeys(nested, nestedLimit, prefix+k)...)
@@ -252,19 +256,19 @@ func (ms MapStorage) GetKeys(nested bool, nestedLimit int, prefix string) (keys
case []MapStorage:
for i, dp := range rv {
pref := prefix + k + fmt.Sprintf("[%v]", i)
keys = append(keys, pref)
// keys = append(keys, pref)
keys = append(keys, dp.GetKeys(nested, nestedLimit, pref)...)
}
case []dataStorage:
for i, dp := range rv {
pref := prefix + k + fmt.Sprintf("[%v]", i)
keys = append(keys, pref)
// keys = append(keys, pref)
keys = append(keys, dp.GetKeys(nested, nestedLimit, pref)...)
}
case []map[string]interface{}:
for i, dp := range rv {
pref := prefix + k + fmt.Sprintf("[%v]", i)
keys = append(keys, pref)
// keys = append(keys, pref)
keys = append(keys, MapStorage(dp).GetKeys(nested, nestedLimit, pref)...)
}
case []interface{}:
@@ -275,9 +279,11 @@ func (ms MapStorage) GetKeys(nested bool, nestedLimit int, prefix string) (keys
for i := range rv {
keys = append(keys, prefix+k+fmt.Sprintf("[%v]", i))
}
case nil, int, int32, int64, uint32, uint64, bool, float32, float64, []uint8, time.Duration, time.Time, string:
keys = append(keys, prefix+k)
default:
// ToDo:should not be called
keys = append(keys, getPathFromInterface(v, prefix+k+NestingSep)...)
keys = append(keys, getPathFromValue(reflect.ValueOf(v), prefix+k+NestingSep)...)
}
}
return
@@ -327,7 +333,7 @@ func (ms MapStorage) Clone() (msClone MapStorage) {
return
}
// ToDo: remove the following functions
// used only in extreme cases where the dataprovider is an object that doesn't implement the dataStorage interface
func getPathFromValue(in reflect.Value, prefix string) (out []string) {
switch in.Kind() {
case reflect.Ptr:
@@ -336,61 +342,26 @@ func getPathFromValue(in reflect.Value, prefix string) (out []string) {
prefix = strings.TrimSuffix(prefix, NestingSep)
for i := 0; i < in.Len(); i++ {
pref := fmt.Sprintf("%s[%v]", prefix, i)
out = append(out, pref)
// out = append(out, pref)
out = append(out, getPathFromValue(in.Index(i), pref+NestingSep)...)
}
case reflect.Map:
iter := in.MapRange()
for iter.Next() {
pref := prefix + iter.Key().String()
out = append(out, pref)
// out = append(out, pref)
out = append(out, getPathFromValue(iter.Value(), pref+NestingSep)...)
}
case reflect.Struct:
inType := in.Type()
for i := 0; i < in.NumField(); i++ {
pref := prefix + inType.Field(i).Name
out = append(out, pref)
// out = append(out, pref)
out = append(out, getPathFromValue(in.Field(i), pref+NestingSep)...)
}
case reflect.Invalid, reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String, reflect.Chan, reflect.Func, reflect.UnsafePointer, reflect.Interface:
out = append(out, strings.TrimSuffix(prefix, NestingSep))
default:
}
return
}
// used by MapStorage2 GetKeys to return all values
func getPathFromInterface(in interface{}, prefix string) (out []string) {
switch vin := in.(type) {
case map[string]interface{}:
for k, val := range vin {
pref := prefix + k
out = append(out, pref)
out = append(out, getPathFromInterface(val, pref+NestingSep)...)
}
case []map[string]interface{}:
prefix = strings.TrimSuffix(prefix, NestingSep)
for i, val := range vin {
pref := fmt.Sprintf("%s[%v]", prefix, i)
out = append(out, pref)
out = append(out, getPathFromInterface(val, pref+NestingSep)...)
}
case []interface{}:
prefix = strings.TrimSuffix(prefix, NestingSep)
for i, val := range vin {
pref := fmt.Sprintf("%s[%v]", prefix, i)
out = append(out, pref)
out = append(out, getPathFromInterface(val, pref+NestingSep)...)
}
case []string:
prefix = strings.TrimSuffix(prefix, NestingSep)
for i := range vin {
pref := fmt.Sprintf("%s[%v]", prefix, i)
out = append(out, pref)
}
case nil, int, int32, int64, uint32, uint64, bool, float32, float64, []uint8, time.Duration, time.Time, string: //no path
default: //reflect based
out = getPathFromValue(reflect.ValueOf(vin), prefix)
}
return
}

View File

@@ -323,21 +323,13 @@ func TestNavMapGetKeys(t *testing.T) {
"Field6": []string{"1", "2"},
}
expKeys := []string{
"FirstLevel",
"FirstLevel.SecondLevel",
"FirstLevel.SecondLevel.ThirdLevel",
"FirstLevel.SecondLevel.ThirdLevel.Fld1",
"FistLever2",
"FistLever2.SecondLevel2",
"FistLever2.SecondLevel2.Field2",
"FistLever2.Field3",
"FistLever2.Field4",
"FistLever2.Field4.Item1",
"FistLever2.Field4.Item2",
"Field5",
"Field5.Item1",
"Field5.Item2",
"Field6",
"Field6[0]",
"Field6[1]",
}
@@ -362,9 +354,7 @@ func TestNavMapGetKeys(t *testing.T) {
}
expKeys = []string{
"FirstLevel",
"FirstLevel.SecondLevel",
"FistLever2",
"FistLever2.SecondLevel2",
"FistLever2.Field3",
"FistLever2.Field4",
@@ -676,34 +666,19 @@ func TestNavMapGetKeys2(t *testing.T) {
"Field10": []map[string]interface{}{{"A": 1}},
}
expKeys := []string{
"FirstLevel",
"FirstLevel.SecondLevel",
"FirstLevel.SecondLevel.ThirdLevel",
"FirstLevel.SecondLevel.ThirdLevel.Fld1",
"FistLever2",
"FistLever2.SecondLevel2",
"FistLever2.SecondLevel2.Field2",
"FistLever2.Field3",
"FistLever2.Field4",
"FistLever2.Field4.Item1",
"FistLever2.Field4.Item2",
"Field5",
"Field5.Item1",
"Field5.Item2",
"Field6",
"Field6[0]",
"Field6[1]",
"Field7",
"Field7[0]",
"Field7[1]",
"Field8",
"Field8[0]",
"Field8[0].A",
"Field9",
"Field9[0]",
"Field9[0].A",
"Field10",
"Field10[0]",
"Field10[0].A",
}
keys := navMp.GetKeys(true, 0, EmptyString)
@@ -714,34 +689,6 @@ func TestNavMapGetKeys2(t *testing.T) {
}
}
func TestGetPathFromInterface(t *testing.T) {
var navMp interface{} = []map[string]interface{}{{
"A": "B",
"C": []string{"1"},
"D": []interface{}{"1"},
"E": []struct{}{{}},
"F": map[string]struct{}{"A": {}},
}}
expKeys := []string{
"L[0]",
"L[0].A",
"L[0].C",
"L[0].C[0]",
"L[0].D",
"L[0].D[0]",
"L[0].E",
"L[0].E[0]",
"L[0].F",
"L[0].F.A",
}
keys := getPathFromInterface(navMp, "L")
sort.Strings(expKeys)
sort.Strings(keys)
if !reflect.DeepEqual(expKeys, keys) {
t.Errorf("Expecting: %+v, received: %+v", ToJSON(expKeys), ToJSON(keys))
}
}
func TestMapStorageCloneNil(t *testing.T) {
var test MapStorage
if !reflect.DeepEqual(test, test.Clone()) {