[RouteS] In case of same weight sort random

This commit is contained in:
TeoV
2020-11-11 14:14:20 +02:00
committed by Dan Christian Bogos
parent 2a61ea0de6
commit de513dc99b
4 changed files with 88 additions and 0 deletions

View File

@@ -65,6 +65,9 @@ func (sRoutes *SortedRoutes) RoutesWithParams() (sPs []string) {
// SortWeight is part of sort interface, sort based on Weight
func (sRoutes *SortedRoutes) SortWeight() {
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
})
}
@@ -74,6 +77,9 @@ func (sRoutes *SortedRoutes) SortWeight() {
func (sSpls *SortedRoutes) SortLeastCost() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
if sSpls.SortedRoutes[i].SortingData[utils.Cost].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Cost].(float64) {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return sSpls.SortedRoutes[i].SortingData[utils.Cost].(float64) < sSpls.SortedRoutes[j].SortingData[utils.Cost].(float64)
@@ -85,6 +91,9 @@ func (sSpls *SortedRoutes) SortLeastCost() {
func (sSpls *SortedRoutes) SortHighestCost() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
if sSpls.SortedRoutes[i].SortingData[utils.Cost].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Cost].(float64) {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return sSpls.SortedRoutes[i].SortingData[utils.Cost].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Cost].(float64)
@@ -116,6 +125,9 @@ func (sSpls *SortedRoutes) SortQOS(params []string) {
}
//in case that we have the same value for all params we sort base on weight
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
})
}
@@ -125,6 +137,9 @@ func (sSpls *SortedRoutes) SortQOS(params []string) {
func (sSpls *SortedRoutes) SortResourceAscendent() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
if sSpls.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) == sSpls.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64) {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return sSpls.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) < sSpls.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64)
@@ -136,6 +151,9 @@ func (sSpls *SortedRoutes) SortResourceAscendent() {
func (sSpls *SortedRoutes) SortResourceDescendent() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
if sSpls.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) == sSpls.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64) {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return sSpls.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) > sSpls.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64)
@@ -149,6 +167,9 @@ func (sSpls *SortedRoutes) SortLoadDistribution() {
splIVal := ((sSpls.SortedRoutes[i].SortingData[utils.Ratio].(float64)+sSpls.SortedRoutes[i].SortingData[utils.Load].(float64))/sSpls.SortedRoutes[i].SortingData[utils.Ratio].(float64) - 1.0)
splJVal := ((sSpls.SortedRoutes[j].SortingData[utils.Ratio].(float64)+sSpls.SortedRoutes[j].SortingData[utils.Load].(float64))/sSpls.SortedRoutes[j].SortingData[utils.Ratio].(float64) - 1.0)
if splIVal == splJVal {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return splIVal < splJVal

View File

@@ -671,3 +671,39 @@ func TestLibRoutesSortLoadDistribution(t *testing.T) {
eIds, rcv)
}
}
func BenchmarkRouteSortCost(b *testing.B) {
sSpls := &SortedRoutes{
SortedRoutes: []*SortedRoute{
{
RouteID: "route1",
SortingData: map[string]interface{}{
utils.Cost: 0.1,
utils.Weight: 10.0,
},
RouteParameters: "param1",
},
{
RouteID: "route2",
SortingData: map[string]interface{}{
utils.Cost: 0.1,
utils.Weight: 10.0,
},
RouteParameters: "param2",
},
{
RouteID: "route3",
SortingData: map[string]interface{}{
utils.Cost: 0.1,
utils.Weight: 10.0,
},
RouteParameters: "param3",
},
},
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
sSpls.SortLeastCost()
}
}

View File

@@ -124,6 +124,7 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium
* [General] For only *asap actions don't save AccountIDs withing ActionPlans
* [AnalyzerS] Added AnalyzerSv1.StringQuery API to search over the recorded RPC calls
* [CoreS] Moved the server implementation in the new cores package
* [RouteS] In case of same weight sort random
-- DanB <danb@cgrates.org> Wed, 19 Feb 2020 13:25:52 +0200

View File

@@ -49,6 +49,7 @@ import (
var (
startCGRateSTime time.Time
boolGenerator *boolGen
rfc3339Rule = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.+$`)
sqlRule = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}$`)
@@ -69,6 +70,7 @@ var (
func init() {
startCGRateSTime = time.Now()
math_rand.Seed(startCGRateSTime.UnixNano())
boolGenerator = newBoolGen()
}
// GetStartTime return the Start time of engine (in UNIX format)
@@ -76,6 +78,11 @@ func GetStartTime() string {
return startCGRateSTime.Format(time.UnixDate)
}
// BoolGenerator return the boolean generator
func BoolGenerator() *boolGen {
return boolGenerator
}
func NewCounter(start, limit int64) *Counter {
return &Counter{
value: start,
@@ -1002,3 +1009,26 @@ func VerifyHash(hash string, dataKeys ...string) bool {
[]byte(ConcatenatedKey(dataKeys...)))
return err == nil
}
//newBoolGen initialize an efficient boolean generator
func newBoolGen() *boolGen {
return &boolGen{src: math_rand.NewSource(time.Now().UnixNano())}
}
//boolGen is an efficient boolean generator
type boolGen struct {
src math_rand.Source
cache int64
remaining int
}
//RandomBool generate a random boolean
func (b *boolGen) RandomBool() bool {
if b.remaining == 0 {
b.cache, b.remaining = b.src.Int63(), 63
}
result := b.cache&0x01 == 1
b.cache >>= 1
b.remaining--
return result
}