mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Optimized the automated index fields matching
This commit is contained in:
committed by
Dan Christian Bogos
parent
ccc894c93f
commit
0f967e4ac0
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user