diff --git a/engine/rateprofile.go b/engine/rateprofile.go index a357413b0..5d2f42fa6 100644 --- a/engine/rateprofile.go +++ b/engine/rateprofile.go @@ -184,6 +184,17 @@ func (rpp *RateProfile) Sort() { // CompressEquals compares two RateSIntervals for Compress function func (rIv *RateSInterval) CompressEquals(rIv2 *RateSInterval) (eq bool) { + if rIv.UsageStart != rIv2.UsageStart { + return + } + if len(rIv.Increments) != len(rIv2.Increments) { + return + } + for i, rIcr := range rIv.Increments { + if !rIcr.CompressEquals(rIv2.Increments[i], true) { + return + } + } return } @@ -198,14 +209,17 @@ func (rIv *RateSInterval) Cost() *utils.Decimal { } // CompressEquals compares two RateSIncrement for Compress function -func (rIcr *RateSIncrement) CompressEquals(rIcr2 *RateSIncrement) (eq bool) { - if rIcr.Rate.UID() != rIcr2.Rate.UID() { +func (rIcr *RateSIncrement) CompressEquals(rIcr2 *RateSIncrement, full bool) (eq bool) { + if rIcr.UsageStart != rIcr2.UsageStart { return } if rIcr.Usage != rIcr2.Usage { return } - if rIcr.CompressFactor != rIcr2.CompressFactor { + if rIcr.Rate.UID() != rIcr2.Rate.UID() { + return + } + if full && rIcr.IntervalRateIndex != rIcr2.IntervalRateIndex { return } return true diff --git a/rates/librates.go b/rates/librates.go index cbe0cc3a9..c76996e40 100644 --- a/rates/librates.go +++ b/rates/librates.go @@ -178,10 +178,10 @@ func orderRatesOnIntervals(aRts []*engine.Rate, sTime time.Time, usage time.Dura } // computeRateSIntervals will give out the cost projection for the given orderedRates and usage -func computeRateSIntervals(rts []*orderedRate, usageStart, usage time.Duration) (rtIvls []*engine.RateSInterval, err error) { +func computeRateSIntervals(rts []*orderedRate, intervalStart, usage time.Duration) (rtIvls []*engine.RateSInterval, err error) { totalUsage := usage - if usageStart != 0 { - totalUsage = usage + usageStart + if intervalStart != 0 { + totalUsage = usage + intervalStart } for i, rt := range rts { isLastRt := i == len(rts)-1 @@ -192,7 +192,7 @@ func computeRateSIntervals(rts []*orderedRate, usageStart, usage time.Duration) rtUsageEIdx = totalUsage } var rIcmts []*engine.RateSIncrement - iRtUsageSIdx := usageStart + iRtUsageSIdx := intervalStart iRtUsageEIdx := rtUsageEIdx for j, iRt := range rt.IntervalRates { if iRtUsageSIdx >= rtUsageEIdx { // charged enough for interval @@ -234,19 +234,27 @@ func computeRateSIntervals(rts []*orderedRate, usageStart, usage time.Duration) IntervalRateIndex: j, CompressFactor: cmpFactor, } - rIcmts = append(rIcmts, rIcrm) + if len(rIcmts) != 0 && rIcrm.CompressEquals(rIcmts[len(rIcmts)-1], false) { + rIcmts[len(rIcmts)-1].CompressFactor += rIcrm.CompressFactor + } else { + rIcmts = append(rIcmts, rIcrm) + } iRtUsageSIdx += iRtUsage } - rtIvls = append(rtIvls, - &engine.RateSInterval{ - UsageStart: usageStart, - Increments: rIcmts, - CompressFactor: 1}) + rIvl := &engine.RateSInterval{ + UsageStart: intervalStart, + Increments: rIcmts, + CompressFactor: 1} + if len(rtIvls) != 0 && rIvl.CompressEquals(rtIvls[len(rtIvls)-1]) { + rtIvls[len(rtIvls)-1].CompressFactor += rIvl.CompressFactor + } else { + rtIvls = append(rtIvls, rIvl) + } if iRtUsageSIdx >= totalUsage { // charged enough for the usage break } - usageStart = rtUsageEIdx // continue for the next interval + intervalStart = rtUsageEIdx // continue for the next interval } return }