diff --git a/accounts/accounts.go b/accounts/accounts.go index cdf00ab17..77714c3a9 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -78,6 +78,8 @@ func (aS *AccountS) matchingAccountsForEvent(ctx *context.Context, tnt string, c aS.cfg.AccountSCfg().StringIndexedFields, aS.cfg.AccountSCfg().PrefixIndexedFields, aS.cfg.AccountSCfg().SuffixIndexedFields, + aS.cfg.AccountSCfg().ExistsIndexedFields, + aS.cfg.AccountSCfg().NotExistsIndexedFields, aS.dm, utils.CacheAccountsFilterIndexes, tnt, diff --git a/actions/actions.go b/actions/actions.go index 84d6d3d2f..ba656eaa0 100644 --- a/actions/actions.go +++ b/actions/actions.go @@ -154,6 +154,8 @@ func (aS *ActionS) matchingActionProfilesForEvent(ctx *context.Context, tnt stri aS.cfg.ActionSCfg().StringIndexedFields, aS.cfg.ActionSCfg().PrefixIndexedFields, aS.cfg.ActionSCfg().SuffixIndexedFields, + aS.cfg.ActionSCfg().ExistsIndexedFields, + aS.cfg.ActionSCfg().NotExistsIndexedFields, aS.dm, utils.CacheActionProfilesFilterIndexes, tnt, diff --git a/dispatchers/dispatchers.go b/dispatchers/dispatchers.go index deaa3aa24..a0bc3f273 100644 --- a/dispatchers/dispatchers.go +++ b/dispatchers/dispatchers.go @@ -107,6 +107,8 @@ func (dS *DispatcherService) dispatcherProfilesForEvent(ctx *context.Context, tn dS.cfg.DispatcherSCfg().StringIndexedFields, dS.cfg.DispatcherSCfg().PrefixIndexedFields, dS.cfg.DispatcherSCfg().SuffixIndexedFields, + dS.cfg.DispatcherSCfg().ExistsIndexedFields, + dS.cfg.DispatcherSCfg().NotExistsIndexedFields, dS.dm, utils.CacheDispatcherFilterIndexes, tnt, dS.cfg.DispatcherSCfg().IndexedSelects, dS.cfg.DispatcherSCfg().NestedFields, diff --git a/engine/attributes.go b/engine/attributes.go index 3917505a7..e74ecbba6 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -63,6 +63,8 @@ func (alS *AttributeS) attributeProfileForEvent(ctx *context.Context, tnt string alS.cfg.AttributeSCfg().StringIndexedFields, alS.cfg.AttributeSCfg().PrefixIndexedFields, alS.cfg.AttributeSCfg().SuffixIndexedFields, + alS.cfg.AccountSCfg().ExistsIndexedFields, + alS.cfg.AccountSCfg().NotExistsIndexedFields, alS.dm, utils.CacheAttributeFilterIndexes, tnt, alS.cfg.AttributeSCfg().IndexedSelects, alS.cfg.AttributeSCfg().NestedFields, diff --git a/engine/chargers.go b/engine/chargers.go index 0798d0926..77a9a04af 100644 --- a/engine/chargers.go +++ b/engine/chargers.go @@ -56,6 +56,8 @@ func (cS *ChargerS) matchingChargerProfilesForEvent(ctx *context.Context, tnt st cS.cfg.ChargerSCfg().StringIndexedFields, cS.cfg.ChargerSCfg().PrefixIndexedFields, cS.cfg.ChargerSCfg().SuffixIndexedFields, + cS.cfg.ChargerSCfg().ExistsIndexedFields, + cS.cfg.ChargerSCfg().NotExistsIndexedFields, cS.dm, utils.CacheChargerFilterIndexes, tnt, cS.cfg.ChargerSCfg().IndexedSelects, cS.cfg.ChargerSCfg().NestedFields, diff --git a/engine/filterhelpers.go b/engine/filterhelpers.go index ccf248c39..cbbcb9187 100644 --- a/engine/filterhelpers.go +++ b/engine/filterhelpers.go @@ -28,11 +28,11 @@ import ( // MatchingItemIDsForEvent returns the list of item IDs matching fieldName/fieldValue for an event // fieldIDs limits the fields which are checked against indexes // helper on top of dataDB.GetIndexes, adding utils.MetaAny to list of fields queried -func MatchingItemIDsForEvent(ctx *context.Context, ev utils.MapStorage, stringFldIDs, prefixFldIDs, suffixFldIDs *[]string, +func MatchingItemIDsForEvent(ctx *context.Context, ev utils.MapStorage, stringFldIDs, prefixFldIDs, suffixFldIDs, existsFldIDs, notExistsFldIDs *[]string, 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 || suffixFldIDs == nil) { + if indexedSelects && (stringFldIDs == nil || prefixFldIDs == nil || suffixFldIDs == nil || existsFldIDs == nil || notExistsFldIDs == nil) { allFieldIDs = ev.GetKeys(nestedFields, 2, utils.EmptyString) } // Guard will protect the function with automatic locking @@ -50,9 +50,9 @@ func MatchingItemIDsForEvent(ctx *context.Context, ev utils.MapStorage, stringFl itemIDs = utils.NewStringSet(sliceIDs) return } - stringFieldVals := map[string]string{utils.MetaAny: utils.MetaAny} // cache here field string values, start with default one - filterIndexTypes := []string{utils.MetaString, utils.MetaPrefix, utils.MetaSuffix, utils.MetaNone} // the MetaNone is used for all items that do not have filters - for i, fieldIDs := range []*[]string{stringFldIDs, prefixFldIDs, suffixFldIDs, {utils.MetaAny}} { // same routine for both string and prefix filter types + stringFieldVals := map[string]string{utils.MetaAny: utils.MetaAny} // cache here field string values, start with default one + filterIndexTypes := []string{utils.MetaString, utils.MetaPrefix, utils.MetaSuffix, utils.MetaExists, utils.MetaNotExists, utils.MetaNone} // the MetaNone is used for all items that do not have filters + for i, fieldIDs := range []*[]string{stringFldIDs, prefixFldIDs, suffixFldIDs, existsFldIDs, notExistsFldIDs, {utils.MetaAny}} { // same routine for both string and prefix filter types if fieldIDs == nil { fieldIDs = &allFieldIDs } diff --git a/engine/resources.go b/engine/resources.go index 171c15305..76ae2a48a 100644 --- a/engine/resources.go +++ b/engine/resources.go @@ -581,6 +581,8 @@ func (rS *ResourceS) matchingResourcesForEvent(ctx *context.Context, tnt string, rS.cfg.ResourceSCfg().StringIndexedFields, rS.cfg.ResourceSCfg().PrefixIndexedFields, rS.cfg.ResourceSCfg().SuffixIndexedFields, + rS.cfg.ResourceSCfg().ExistsIndexedFields, + rS.cfg.ResourceSCfg().NotExistsIndexedFields, rS.dm, utils.CacheResourceFilterIndexes, tnt, rS.cfg.ResourceSCfg().IndexedSelects, rS.cfg.ResourceSCfg().NestedFields, diff --git a/engine/routes.go b/engine/routes.go index a2a2f3f4b..1820b5f12 100644 --- a/engine/routes.go +++ b/engine/routes.go @@ -146,6 +146,8 @@ func (rpS *RouteS) matchingRouteProfilesForEvent(ctx *context.Context, tnt strin rpS.cfg.RouteSCfg().StringIndexedFields, rpS.cfg.RouteSCfg().PrefixIndexedFields, rpS.cfg.RouteSCfg().SuffixIndexedFields, + rpS.cfg.RouteSCfg().ExistsIndexedFields, + rpS.cfg.RouteSCfg().NotExistsIndexedFields, rpS.dm, utils.CacheRouteFilterIndexes, tnt, rpS.cfg.RouteSCfg().IndexedSelects, rpS.cfg.RouteSCfg().NestedFields, diff --git a/engine/stats.go b/engine/stats.go index 55fc8f237..a661677b9 100644 --- a/engine/stats.go +++ b/engine/stats.go @@ -165,6 +165,8 @@ func (sS *StatS) matchingStatQueuesForEvent(ctx *context.Context, tnt string, st sS.cfg.StatSCfg().StringIndexedFields, sS.cfg.StatSCfg().PrefixIndexedFields, sS.cfg.StatSCfg().SuffixIndexedFields, + sS.cfg.StatSCfg().ExistsIndexedFields, + sS.cfg.StatSCfg().NotExistsIndexedFields, sS.dm, utils.CacheStatFilterIndexes, tnt, sS.cfg.StatSCfg().IndexedSelects, sS.cfg.StatSCfg().NestedFields, diff --git a/engine/thresholds.go b/engine/thresholds.go index d5ca139d6..d8d31f4dc 100644 --- a/engine/thresholds.go +++ b/engine/thresholds.go @@ -347,6 +347,8 @@ func (tS *ThresholdS) matchingThresholdsForEvent(ctx *context.Context, tnt strin tS.cfg.ThresholdSCfg().StringIndexedFields, tS.cfg.ThresholdSCfg().PrefixIndexedFields, tS.cfg.ThresholdSCfg().SuffixIndexedFields, + tS.cfg.ThresholdSCfg().ExistsIndexedFields, + tS.cfg.ThresholdSCfg().NotExistsIndexedFields, tS.dm, utils.CacheThresholdFilterIndexes, tnt, tS.cfg.ThresholdSCfg().IndexedSelects, tS.cfg.ThresholdSCfg().NestedFields, diff --git a/engine/z_filterhelpers_test.go b/engine/z_filterhelpers_test.go index 67b6e11bf..faaa1678e 100644 --- a/engine/z_filterhelpers_test.go +++ b/engine/z_filterhelpers_test.go @@ -101,7 +101,7 @@ func TestFilterMatchingItemIDsForEvent(t *testing.T) { utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC), "Field": "profile", }} - aPrflIDs, err := MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, + aPrflIDs, err := MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, nil, nil, dmMatch, utils.CacheAttributeFilterIndexes, tntCtx, true, false) if err != nil { t.Errorf("Error: %+v", err) @@ -114,7 +114,7 @@ func TestFilterMatchingItemIDsForEvent(t *testing.T) { matchEV = utils.MapStorage{utils.MetaReq: map[string]interface{}{ "Field": "profilePrefix", }} - aPrflIDs, err = MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, + aPrflIDs, err = MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, nil, nil, dmMatch, utils.CacheAttributeFilterIndexes, tntCtx, true, false) if err != nil { t.Errorf("Error: %+v", err) @@ -127,7 +127,7 @@ func TestFilterMatchingItemIDsForEvent(t *testing.T) { matchEV = utils.MapStorage{utils.MetaReq: map[string]interface{}{ "Field": "profilePrefix", }} - aPrflIDs, err = MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, + aPrflIDs, err = MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, nil, nil, dmMatch, utils.CacheAttributeFilterIndexes, tntCtx, true, false) if err != nil { t.Errorf("Error: %+v", err) @@ -194,7 +194,7 @@ func TestFilterMatchingItemIDsForEvent2(t *testing.T) { utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC), "CallCost": map[string]interface{}{"Account": 1001}, }} - aPrflIDs, err := MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, + aPrflIDs, err := MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, nil, nil, dmMatch, utils.CacheAttributeFilterIndexes, tntCtx, true, true) if err != nil { t.Errorf("Error: %+v", err) @@ -206,7 +206,7 @@ func TestFilterMatchingItemIDsForEvent2(t *testing.T) { matchEV = utils.MapStorage{utils.MetaReq: map[string]interface{}{ "CallCost": map[string]interface{}{"Field": "profilePrefix"}, }} - aPrflIDs, err = MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, + aPrflIDs, err = MatchingItemIDsForEvent(context.TODO(), matchEV, nil, nil, nil, nil, nil, dmMatch, utils.CacheAttributeFilterIndexes, tntCtx, true, true) if err != nil { t.Errorf("Error: %+v", err) diff --git a/rates/rates.go b/rates/rates.go index f183a51bf..1ae82f991 100644 --- a/rates/rates.go +++ b/rates/rates.go @@ -80,6 +80,8 @@ func (rS *RateS) matchingRateProfileForEvent(ctx *context.Context, tnt string, r rS.cfg.RateSCfg().StringIndexedFields, rS.cfg.RateSCfg().PrefixIndexedFields, rS.cfg.RateSCfg().SuffixIndexedFields, + rS.cfg.RateSCfg().ExistsIndexedFields, + rS.cfg.RateSCfg().NotExistsIndexedFields, rS.dm, utils.CacheRateProfilesFilterIndexes, tnt, @@ -138,6 +140,8 @@ func (rS *RateS) rateProfileCostForEvent(ctx *context.Context, rtPfl *utils.Rate rS.cfg.RateSCfg().RateStringIndexedFields, rS.cfg.RateSCfg().RatePrefixIndexedFields, rS.cfg.RateSCfg().RateSuffixIndexedFields, + rS.cfg.RateSCfg().RateExistsIndexedFields, + rS.cfg.RateSCfg().RateNotExistsIndexedFields, rS.dm, utils.CacheRateFilterIndexes, utils.ConcatenatedKey(args.Tenant, rtPfl.ID),