mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Optimize matchItemProfileForEvent functions
This commit is contained in:
@@ -166,6 +166,8 @@ func (rpS *RouteService) matchingRouteProfilesForEvent(ev *utils.CGREvent, singl
|
||||
}
|
||||
if singleResult {
|
||||
matchingRPrf = make([]*RouteProfile, 1)
|
||||
} else {
|
||||
matchingRPrf = make([]*RouteProfile, 0, len(rPrfIDs))
|
||||
}
|
||||
evNm := utils.MapStorage{utils.MetaReq: ev.Event}
|
||||
for lpID := range rPrfIDs {
|
||||
|
||||
@@ -151,12 +151,9 @@ func (sS *StatService) StoreStatQueue(sq *StatQueue) (err error) {
|
||||
|
||||
// matchingStatQueuesForEvent returns ordered list of matching resources which are active by the time of the call
|
||||
func (sS *StatService) matchingStatQueuesForEvent(args *StatsArgsProcessEvent) (sqs StatQueues, err error) {
|
||||
matchingSQs := make(map[string]*StatQueue)
|
||||
var sqIDs []string
|
||||
if len(args.StatIDs) != 0 {
|
||||
sqIDs = args.StatIDs
|
||||
} else {
|
||||
mapIDs, err := MatchingItemIDsForEvent(args.Event,
|
||||
sqIDs := utils.NewStringSet(args.StatIDs)
|
||||
if len(sqIDs) == 0 {
|
||||
sqIDs, err = MatchingItemIDsForEvent(args.Event,
|
||||
sS.cgrcfg.StatSCfg().StringIndexedFields,
|
||||
sS.cgrcfg.StatSCfg().PrefixIndexedFields,
|
||||
sS.dm, utils.CacheStatFilterIndexes, args.Tenant,
|
||||
@@ -164,12 +161,12 @@ func (sS *StatService) matchingStatQueuesForEvent(args *StatsArgsProcessEvent) (
|
||||
sS.cgrcfg.StatSCfg().NestedFields,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
sqIDs = mapIDs.AsSlice()
|
||||
}
|
||||
evNm := utils.MapStorage{utils.MetaReq: args.Event}
|
||||
for _, sqID := range sqIDs {
|
||||
sqs = make(StatQueues, 0, len(sqIDs))
|
||||
for sqID := range sqIDs {
|
||||
sqPrfl, err := sS.dm.GetStatQueueProfile(args.Tenant, sqID, true, true, utils.NonTransactional)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -203,15 +200,12 @@ func (sS *StatService) matchingStatQueuesForEvent(args *StatsArgsProcessEvent) (
|
||||
sq.ttl = utils.DurationPointer(sqPrfl.TTL)
|
||||
}
|
||||
sq.sqPrfl = sqPrfl
|
||||
matchingSQs[sqPrfl.ID] = sq
|
||||
sqs = append(sqs, sq)
|
||||
}
|
||||
if len(sqs) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
// All good, convert from Map to Slice so we can sort
|
||||
sqs = make(StatQueues, len(matchingSQs))
|
||||
i := 0
|
||||
for _, s := range matchingSQs {
|
||||
sqs[i] = s
|
||||
i++
|
||||
}
|
||||
sqs.Sort()
|
||||
for i, s := range sqs {
|
||||
if s.sqPrfl.Blocker { // blocker will stop processing
|
||||
|
||||
@@ -235,12 +235,9 @@ func (tS *ThresholdService) StoreThreshold(t *Threshold) (err error) {
|
||||
|
||||
// matchingThresholdsForEvent returns ordered list of matching thresholds which are active for an Event
|
||||
func (tS *ThresholdService) matchingThresholdsForEvent(args *ArgsProcessEvent) (ts Thresholds, err error) {
|
||||
matchingTs := make(map[string]*Threshold)
|
||||
var tIDs []string
|
||||
if len(args.ThresholdIDs) != 0 {
|
||||
tIDs = args.ThresholdIDs
|
||||
} else {
|
||||
tIDsMap, err := MatchingItemIDsForEvent(args.Event,
|
||||
tIDs := utils.NewStringSet(args.ThresholdIDs)
|
||||
if len(tIDs) == 0 {
|
||||
tIDs, err = MatchingItemIDsForEvent(args.Event,
|
||||
tS.cgrcfg.ThresholdSCfg().StringIndexedFields,
|
||||
tS.cgrcfg.ThresholdSCfg().PrefixIndexedFields,
|
||||
tS.dm, utils.CacheThresholdFilterIndexes, args.Tenant,
|
||||
@@ -250,12 +247,12 @@ func (tS *ThresholdService) matchingThresholdsForEvent(args *ArgsProcessEvent) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tIDs = tIDsMap.AsSlice()
|
||||
}
|
||||
evNm := utils.MapStorage{
|
||||
utils.MetaReq: args.Event,
|
||||
}
|
||||
for _, tID := range tIDs {
|
||||
ts = make(Thresholds, 0, len(tIDs))
|
||||
for tID := range tIDs {
|
||||
tPrfl, err := tS.dm.GetThresholdProfile(args.Tenant, tID, true, true, utils.NonTransactional)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -281,14 +278,11 @@ func (tS *ThresholdService) matchingThresholdsForEvent(args *ArgsProcessEvent) (
|
||||
t.dirty = utils.BoolPointer(false)
|
||||
}
|
||||
t.tPrfl = tPrfl
|
||||
matchingTs[tPrfl.ID] = t
|
||||
ts = append(ts, t)
|
||||
}
|
||||
// All good, convert from Map to Slice so we can sort
|
||||
ts = make(Thresholds, len(matchingTs))
|
||||
i := 0
|
||||
for _, t := range matchingTs {
|
||||
ts[i] = t
|
||||
i++
|
||||
if len(ts) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
ts.Sort()
|
||||
for i, t := range ts {
|
||||
|
||||
@@ -1114,13 +1114,27 @@ func testITIndexRateProfile(t *testing.T) {
|
||||
ID: "FIRST_GI",
|
||||
FilterIDs: []string{"*string:~*req.Category:call"},
|
||||
Weight: 0,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.12,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Minute),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
"SECOND_GI": {
|
||||
ID: "SECOND_GI",
|
||||
FilterIDs: []string{"*string:~*req.Category:voice"},
|
||||
Weight: 10,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.06,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Second),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1161,19 +1175,40 @@ func testITIndexRateProfile(t *testing.T) {
|
||||
ID: "FIRST_GI",
|
||||
FilterIDs: []string{"*string:~*req.Category:call"},
|
||||
Weight: 0,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.12,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Minute),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
"SECOND_GI": {
|
||||
ID: "SECOND_GI",
|
||||
FilterIDs: []string{"*string:~*req.Category:voice"},
|
||||
Weight: 10,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.06,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Second),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
"THIRD_GI": {
|
||||
ID: "THIRD_GI",
|
||||
FilterIDs: []string{"*string:~*req.Category:custom"},
|
||||
Weight: 20,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.06,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Second),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1215,13 +1250,27 @@ func testITIndexRateProfile(t *testing.T) {
|
||||
ID: "CUSTOM_RATE1",
|
||||
FilterIDs: []string{"*string:~*req.Subject:1001"},
|
||||
Weight: 0,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.12,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Minute),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
"CUSTOM_RATE2": {
|
||||
ID: "CUSTOM_RATE2",
|
||||
FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Category:call"},
|
||||
Weight: 10,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.6,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Second),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2162,13 +2162,27 @@ func testOnStorITRateProfile(t *testing.T) {
|
||||
ID: "FIRST_GI",
|
||||
FilterIDs: []string{"*gi:~*req.Usage:0"},
|
||||
Weight: 0,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.12,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Minute),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
"SECOND_GI": &Rate{
|
||||
ID: "SECOND_GI",
|
||||
FilterIDs: []string{"*gi:~*req.Usage:1m"},
|
||||
Weight: 10,
|
||||
Blocker: false,
|
||||
IntervalRates: []*IntervalRate{
|
||||
&IntervalRate{
|
||||
Value: 0.06,
|
||||
Unit: time.Duration(1 * time.Minute),
|
||||
Increment: time.Duration(1 * time.Second),
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package rates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
@@ -89,7 +88,6 @@ func (rS *RateS) matchingRateProfileForEvent(args *ArgsCostForEvent, rPfIDs []st
|
||||
}
|
||||
rPfIDs = rPfIDMp.AsSlice()
|
||||
}
|
||||
matchingRPfs := make([]*engine.RateProfile, 0, len(rPfIDs))
|
||||
evNm := utils.MapStorage{utils.MetaReq: args.CGREvent.Event}
|
||||
var sTime time.Time
|
||||
if sTime, err = args.StartTime(rS.cfg.GeneralCfg().DefaultTimezone); err != nil {
|
||||
@@ -115,15 +113,14 @@ func (rS *RateS) matchingRateProfileForEvent(args *ArgsCostForEvent, rPfIDs []st
|
||||
} else if !pass {
|
||||
continue
|
||||
}
|
||||
matchingRPfs = append(matchingRPfs, rPf)
|
||||
if rtPfl == nil || rtPfl.Weight < rPf.Weight {
|
||||
rtPfl = rPf
|
||||
}
|
||||
}
|
||||
if len(matchingRPfs) == 0 {
|
||||
if rtPfl == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
sort.Slice(matchingRPfs, func(i, j int) bool {
|
||||
return matchingRPfs[i].Weight > matchingRPfs[j].Weight
|
||||
})
|
||||
rtPfl = matchingRPfs[0]
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user