mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
better rate intervals sorting according to weight
should solve the issue #424
This commit is contained in:
@@ -360,23 +360,6 @@ func (ri *RateInterval) GetMaxCost() (float64, string) {
|
||||
// Structure to store intervals according to weight
|
||||
type RateIntervalList []*RateInterval
|
||||
|
||||
func (il RateIntervalList) Len() int {
|
||||
return len(il)
|
||||
}
|
||||
|
||||
func (il RateIntervalList) Swap(i, j int) {
|
||||
il[i], il[j] = il[j], il[i]
|
||||
}
|
||||
|
||||
// we need higher weights earlyer in the list
|
||||
func (il RateIntervalList) Less(j, i int) bool {
|
||||
return il[i].Weight < il[j].Weight //|| il[i].Timing.StartTime > il[j].Timing.StartTime
|
||||
}
|
||||
|
||||
func (il RateIntervalList) Sort() {
|
||||
sort.Sort(il)
|
||||
}
|
||||
|
||||
// Structure to store intervals according to weight
|
||||
type RateIntervalTimeSorter struct {
|
||||
referenceTime time.Time
|
||||
@@ -393,6 +376,9 @@ func (il *RateIntervalTimeSorter) Swap(i, j int) {
|
||||
|
||||
// we need higher weights earlyer in the list
|
||||
func (il *RateIntervalTimeSorter) Less(j, i int) bool {
|
||||
if il.ris[i].Weight < il.ris[j].Weight {
|
||||
return il.ris[i].Weight < il.ris[j].Weight
|
||||
}
|
||||
t1 := il.ris[i].Timing.getLeftMargin(il.referenceTime)
|
||||
t2 := il.ris[j].Timing.getLeftMargin(il.referenceTime)
|
||||
return t1.After(t2)
|
||||
|
||||
@@ -92,28 +92,36 @@ type RatingInfo struct {
|
||||
|
||||
// SelectRatingIntevalsForTimespan orders rate intervals in time preserving only those which aply to the specified timestamp
|
||||
func (ri RatingInfo) SelectRatingIntevalsForTimespan(ts *TimeSpan) (result RateIntervalList) {
|
||||
ri.RateIntervals.Sort()
|
||||
sorter := &RateIntervalTimeSorter{referenceTime: ts.TimeStart, ris: ri.RateIntervals}
|
||||
rateIntervals := sorter.Sort()
|
||||
// get the rating interval closest to begining of timespan
|
||||
var delta time.Duration = -1
|
||||
var bestRateIntervalIndex int
|
||||
var bestIntervalWeight float64
|
||||
for index, rateInterval := range rateIntervals {
|
||||
if !rateInterval.Contains(ts.TimeStart, false) {
|
||||
continue
|
||||
}
|
||||
if rateInterval.Weight < bestIntervalWeight {
|
||||
break // don't consider lower weights'
|
||||
}
|
||||
startTime := rateInterval.Timing.getLeftMargin(ts.TimeStart)
|
||||
tmpDelta := ts.TimeStart.Sub(startTime)
|
||||
if (startTime.Before(ts.TimeStart) ||
|
||||
startTime.Equal(ts.TimeStart)) &&
|
||||
(delta == -1 || tmpDelta < delta) {
|
||||
bestRateIntervalIndex = index
|
||||
bestIntervalWeight = rateInterval.Weight
|
||||
delta = tmpDelta
|
||||
}
|
||||
}
|
||||
result = append(result, rateIntervals[bestRateIntervalIndex])
|
||||
// check if later rating intervals influence this timespan
|
||||
//log.Print("RIS: ", utils.ToIJSON(rateIntervals))
|
||||
for i := bestRateIntervalIndex + 1; i < len(rateIntervals); i++ {
|
||||
if rateIntervals[i].Weight < bestIntervalWeight {
|
||||
break // don't consider lower weights'
|
||||
}
|
||||
startTime := rateIntervals[i].Timing.getLeftMargin(ts.TimeStart)
|
||||
if startTime.Before(ts.TimeEnd) {
|
||||
result = append(result, rateIntervals[i])
|
||||
|
||||
@@ -285,6 +285,108 @@ func TestRatingProfileYearMonthDay(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRatingProfileWeighted(t *testing.T) {
|
||||
ri := &RatingInfo{
|
||||
RateIntervals: RateIntervalList{
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "09:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "19:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2016},
|
||||
Months: utils.Months{1},
|
||||
MonthDays: utils.MonthDays{6},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 11,
|
||||
},
|
||||
},
|
||||
}
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2016, 1, 6, 23, 40, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2016, 1, 6, 23, 45, 30, 0, time.UTC),
|
||||
}
|
||||
rIntervals := ri.SelectRatingIntevalsForTimespan(ts)
|
||||
if len(rIntervals) != 1 ||
|
||||
rIntervals[0].Timing.StartTime != "00:00:00" ||
|
||||
rIntervals[0].Weight != 11 {
|
||||
t.Error("Wrong interval list: ", utils.ToIJSON(rIntervals))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRatingProfileWeightedMultiple(t *testing.T) {
|
||||
ri := &RatingInfo{
|
||||
RateIntervals: RateIntervalList{
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "09:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "19:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2016},
|
||||
Months: utils.Months{1},
|
||||
MonthDays: utils.MonthDays{6},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 11,
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2016},
|
||||
Months: utils.Months{1},
|
||||
MonthDays: utils.MonthDays{6},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: "18:00:00",
|
||||
},
|
||||
Weight: 11,
|
||||
},
|
||||
},
|
||||
}
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2016, 1, 6, 17, 40, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2016, 1, 6, 23, 45, 30, 0, time.UTC),
|
||||
}
|
||||
rIntervals := ri.SelectRatingIntevalsForTimespan(ts)
|
||||
if len(rIntervals) != 2 ||
|
||||
rIntervals[0].Timing.StartTime != "00:00:00" ||
|
||||
rIntervals[0].Weight != 11 ||
|
||||
rIntervals[1].Timing.StartTime != "18:00:00" ||
|
||||
rIntervals[1].Weight != 11 {
|
||||
t.Error("Wrong interval list: ", utils.ToIJSON(rIntervals))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRatingProfileSubjectPrefixMatching(t *testing.T) {
|
||||
rpSubjectPrefixMatching = true
|
||||
rp, err := RatingProfileSubjectPrefixMatching("*out:cgrates.org:data:rif")
|
||||
|
||||
Reference in New Issue
Block a user