mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Addded NavigableMap.GetKeys()
This commit is contained in:
@@ -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>
|
||||
},
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user