Addded NavigableMap.GetKeys()

This commit is contained in:
Trial97
2020-01-09 15:52:59 +02:00
parent ff8a7f23f0
commit 533e2d6048
3 changed files with 100 additions and 17 deletions

View File

@@ -534,7 +534,7 @@ const CGRATES_CFG_JSON = `
"indexed_selects":true, // enable profile matching exclusively on indexes
//"string_indexed_fields": [], // query indexes based on these fields for faster processing
"prefix_indexed_fields": [], // query indexes based on these fields for faster processing
"nested_fields":false, // applies when indexed fields is not defined
"nested_fields": false, // applies when indexed fields is not defined
"process_runs": 1, // number of run loops when processing event
},
@@ -545,7 +545,7 @@ const CGRATES_CFG_JSON = `
"indexed_selects":true, // enable profile matching exclusively on indexes
//"string_indexed_fields": [], // query indexes based on these fields for faster processing
"prefix_indexed_fields": [], // query indexes based on these fields for faster processing
"nested_fields":false, // applies when indexed fields is not defined
"nested_fields": false, // applies when indexed fields is not defined
},
@@ -556,7 +556,7 @@ const CGRATES_CFG_JSON = `
"indexed_selects":true, // enable profile matching exclusively on indexes
//"string_indexed_fields": [], // query indexes based on these fields for faster processing
"prefix_indexed_fields": [], // query indexes based on these fields for faster processing
"nested_fields":false, // applies when indexed fields is not defined
"nested_fields": false, // applies when indexed fields is not defined
},
@@ -568,7 +568,7 @@ const CGRATES_CFG_JSON = `
"indexed_selects":true, // enable profile matching exclusively on indexes
//"string_indexed_fields": [], // query indexes based on these fields for faster processing
"prefix_indexed_fields": [], // query indexes based on these fields for faster processing
"nested_fields":false, // applies when indexed fields is not defined
"nested_fields": false, // applies when indexed fields is not defined
},
@@ -578,7 +578,7 @@ const CGRATES_CFG_JSON = `
"indexed_selects":true, // enable profile matching exclusively on indexes
//"string_indexed_fields": [], // query indexes based on these fields for faster processing
"prefix_indexed_fields": [], // query indexes based on these fields for faster processing
"nested_fields":false, // applies when indexed fields is not defined
"nested_fields": false, // applies when indexed fields is not defined
},
@@ -587,7 +587,7 @@ const CGRATES_CFG_JSON = `
"indexed_selects":true, // enable profile matching exclusively on indexes
//"string_indexed_fields": [], // query indexes based on these fields for faster processing
"prefix_indexed_fields": [], // query indexes based on these fields for faster processing
"nested_fields":false, // applies when indexed fields is not defined
"nested_fields": false, // applies when indexed fields is not defined
"attributes_conns": [], // connections to AttributeS for altering events before supplier queries: <""|*internal|127.0.0.1:2013>
"resources_conns": [], // connections to ResourceS for *res sorting, empty to disable functionality: <""|*internal|x.y.z.y:1234>
"stats_conns": [], // connections to StatS for *stats sorting, empty to disable stats functionality: <""|*internal|x.y.z.y:1234>
@@ -831,7 +831,7 @@ const CGRATES_CFG_JSON = `
"indexed_selects":true, // enable profile matching exclusively on indexes
//"string_indexed_fields": [], // query indexes based on these fields for faster processing
"prefix_indexed_fields": [], // query indexes based on these fields for faster processing
"nested_fields":false, // applies when indexed fields is not defined
"nested_fields": false, // applies when indexed fields is not defined
"attributes_conns": [], // connections to AttributeS for API authorization, empty to disable auth functionality: <""|*internal|x.y.z.y:1234>
},

View File

@@ -309,7 +309,7 @@ func (nM *NavigableMap) Merge(nM2 *NavigableMap) {
val, _ := nM2.FieldAsInterface(path)
if valItms, isItms := val.([]*NMItem); isItms {
pathStr := strings.Join(path, utils.NestingSep)
pathIdx[pathStr] += 1
pathIdx[pathStr]++
if pathIdx[pathStr] > len(valItms) {
val = valItms[len(valItms)-1:] // slice with only last element in, so we can set it unlimited
} else {
@@ -449,3 +449,79 @@ func (nM *NavigableMap) AsXMLElements() (ents []*XMLElement, err error) {
}
return
}
func getPathFromValue(in reflect.Value, prefix string) (out []string) {
switch in.Kind() {
case reflect.Ptr:
return getPathFromValue(in.Elem(), prefix)
case reflect.Array, reflect.Slice:
prefix = strings.TrimSuffix(prefix, ".")
for i := 0; i < in.Len(); i++ {
pref := fmt.Sprintf("%s[%v]", prefix, i)
out = append(out, pref)
out = append(out, getPathFromValue(in.Index(i), pref+".")...)
}
case reflect.Map:
iter := reflect.ValueOf(in).MapRange()
for iter.Next() {
pref := prefix + iter.Key().String()
out = append(out, pref)
out = append(out, getPathFromValue(iter.Value(), pref+".")...)
}
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, getPathFromValue(in.Field(i), pref+".")...)
}
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:
default:
}
return
}
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+".")...)
}
case []map[string]interface{}:
prefix = strings.TrimSuffix(prefix, ".")
for i, val := range vin {
pref := fmt.Sprintf("%s[%v]", prefix, i)
out = append(out, pref)
out = append(out, getPathFromInterface(val, pref+".")...)
}
case []interface{}:
prefix = strings.TrimSuffix(prefix, ".")
for i, val := range vin {
pref := fmt.Sprintf("%s[%v]", prefix, i)
out = append(out, pref)
out = append(out, getPathFromInterface(val, pref+".")...)
}
case []string:
prefix = strings.TrimSuffix(prefix, ".")
for i, val := range vin {
pref := fmt.Sprintf("%s[%v]", prefix, i)
out = append(out, pref)
out = append(out, getPathFromInterface(val, 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
}
// GetKeys returns all posibble keys
func (nM *NavigableMap) GetKeys() (keys []string) {
for k, val := range nM.data {
keys = append(keys, k)
keys = append(keys, getPathFromInterface(val, k+".")...)
}
return
}

View File

@@ -32,7 +32,20 @@ import (
func MatchingItemIDsForEvent(ev map[string]interface{}, stringFldIDs, prefixFldIDs *[]string,
dm *DataManager, cacheID, itemIDPrefix string, indexedSelects, nestedFields bool) (itemIDs utils.StringMap, err error) {
itemIDs = make(utils.StringMap)
var allFieldIDs []string
navEv := config.NewNavigableMap(ev)
if indexedSelects && (stringFldIDs == nil || prefixFldIDs == nil) {
if !nestedFields {
allFieldIDs = make([]string, len(ev))
i := 0
for fldID := range ev {
allFieldIDs[i] = fldID
i++
}
} else {
allFieldIDs = navEv.GetKeys()
}
}
// Guard will protect the function with automatic locking
lockID := utils.CacheInstanceToPrefix[cacheID] + itemIDPrefix
guardian.Guardian.Guard(func() (gRes interface{}, gErr error) {
@@ -48,12 +61,6 @@ func MatchingItemIDsForEvent(ev map[string]interface{}, stringFldIDs, prefixFldI
itemIDs = utils.StringMapFromSlice(sliceIDs)
return
}
allFieldIDs := make([]string, len(ev))
i := 0
for fldID := range ev {
allFieldIDs[i] = fldID
i++
}
stringFieldVals := map[string]string{utils.ANY: utils.ANY} // cache here field string values, start with default one
filterIndexTypes := []string{utils.MetaString, utils.MetaPrefix, utils.META_NONE} // the META_NONE is used for all items that do not have filters
for i, fieldIDs := range []*[]string{stringFldIDs, prefixFldIDs, &[]string{utils.ANY}} { // same routine for both string and prefix filter types
@@ -61,8 +68,8 @@ func MatchingItemIDsForEvent(ev map[string]interface{}, stringFldIDs, prefixFldI
fieldIDs = &allFieldIDs
}
for _, fldName := range *fieldIDs {
fieldValIf, has := ev[fldName]
if !has && filterIndexTypes[i] != utils.META_NONE {
fieldValIf, err := navEv.FieldAsInterface(strings.Split(fldName, utils.NestingSep))
if err != nil && filterIndexTypes[i] != utils.META_NONE {
continue
}
if _, cached := stringFieldVals[fldName]; !cached {