diff --git a/engine/filterhelpers.go b/engine/filterhelpers.go index c3509f7bf..fafc01c04 100644 --- a/engine/filterhelpers.go +++ b/engine/filterhelpers.go @@ -33,7 +33,7 @@ func MatchingItemIDsForEvent(ev utils.MapStorage, stringFldIDs, prefixFldIDs, su dm *DataManager, cacheID, itemIDPrefix string, indexedSelects, nestedFields bool) (itemIDs utils.StringSet, err error) { itemIDs = make(utils.StringSet) var allFieldIDs []string - if indexedSelects && (stringFldIDs == nil || prefixFldIDs == nil) { + if indexedSelects && (stringFldIDs == nil || prefixFldIDs == nil || suffixFldIDs == nil) { allFieldIDs = ev.GetKeys(nestedFields, 2, utils.EmptyString) } // Guard will protect the function with automatic locking @@ -51,9 +51,9 @@ func MatchingItemIDsForEvent(ev utils.MapStorage, stringFldIDs, prefixFldIDs, su itemIDs = utils.NewStringSet(sliceIDs) return } - 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, {utils.ANY}} { // same routine for both string and prefix filter types + stringFieldVals := map[string]string{utils.ANY: utils.ANY} // cache here field string values, start with default one + filterIndexTypes := []string{utils.MetaString, utils.MetaPrefix, utils.MetaSuffix, utils.META_NONE} // the META_NONE is used for all items that do not have filters + for i, fieldIDs := range []*[]string{stringFldIDs, prefixFldIDs, suffixFldIDs, {utils.ANY}} { // same routine for both string and prefix filter types if fieldIDs == nil { fieldIDs = &allFieldIDs } @@ -70,6 +70,8 @@ func MatchingItemIDsForEvent(ev utils.MapStorage, stringFldIDs, prefixFldIDs, su // default is only one fieldValue checked if filterIndexTypes[i] == utils.MetaPrefix { fldVals = utils.SplitPrefix(fldVal, 1) // all prefixes till last digit + } else if filterIndexTypes[i] == utils.MetaSuffix { + fldVals = utils.SplitSuffix(fldVal) // all suffix till first digit } var dbItemIDs utils.StringSet // list of items matched in DB for _, val := range fldVals { diff --git a/utils/coreutils.go b/utils/coreutils.go index cdf5a972e..62132b672 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -313,6 +313,16 @@ func SplitPrefix(prefix string, minLength int) []string { return subs } +func SplitSuffix(suffix string) []string { + length := len(suffix) + subs := make([]string, length) + max := len(suffix) - 1 + for i := 0; i < length; i++ { + subs[i] = suffix[max-i:] + } + return subs +} + func CopyHour(src, dest time.Time) time.Time { if src.Hour() == 0 && src.Minute() == 0 && src.Second() == 0 { return src diff --git a/utils/coreutils_test.go b/utils/coreutils_test.go index 2db023681..34a0fd918 100644 --- a/utils/coreutils_test.go +++ b/utils/coreutils_test.go @@ -522,14 +522,35 @@ func TestRoundDuration(t *testing.T) { } func TestSplitPrefix(t *testing.T) { + exp := []string{"0123456789", "012345678", "01234567", "0123456", "012345", "01234", "0123", "012", "01", "0"} if a := SplitPrefix("0123456789", 1); len(a) != 10 { t.Error("Error splitting prefix: ", a) + } else if !reflect.DeepEqual(a, exp) { + t.Errorf("Expecting: %v, received: %v", exp, a) } + exp = []string{"0123456789", "012345678", "01234567", "0123456", "012345", "01234"} if a := SplitPrefix("0123456789", 5); len(a) != 6 { t.Error("Error splitting prefix: ", a) + } else if !reflect.DeepEqual(a, exp) { + t.Errorf("Expecting: %v, received: %v", exp, a) } + exp = []string{} if a := SplitPrefix("", 1); len(a) != 0 { t.Error("Error splitting prefix: ", a) + } else if !reflect.DeepEqual(a, exp) { + t.Errorf("Expecting: %v, received: %v", exp, a) + } +} + +func TestSplitSuffix(t *testing.T) { + exp := []string{"9", "89", "789", "6789", "56789", "456789", "3456789", "23456789", "123456789", "0123456789"} + if a := SplitSuffix("0123456789"); len(a) != 10 { + t.Error("Error splitting prefix: ", ToJSON(a)) + } else if !reflect.DeepEqual(a, exp) { + t.Errorf("Expecting: %v, received: %v", exp, a) + } + if a := SplitSuffix(""); len(a) != 0 { + t.Error("Error splitting prefix: ", a) } }