mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
first lcr algo
This commit is contained in:
@@ -206,3 +206,21 @@ func XCountEntries(prefix string) (result int) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetEntriesKeys(prefix string) (keys []string) {
|
||||
for key, _ := range cache {
|
||||
if strings.HasPrefix(key, prefix) {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func XGetEntriesKeys(prefix string) (keys []string) {
|
||||
for key, _ := range xcache {
|
||||
if strings.HasPrefix(key, prefix) {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -296,10 +296,12 @@ func (cd *CallDescriptor) GetAccountKey() string {
|
||||
return fmt.Sprintf("%s:%s:%s", cd.Direction, cd.Tenant, subj)
|
||||
}
|
||||
|
||||
func (cd *CallDescriptor) GetLCRKey() string {
|
||||
subj := cd.Subject
|
||||
if cd.Account != "" {
|
||||
subj = cd.Account
|
||||
func (cd *CallDescriptor) GetLCRKey(subj string) string {
|
||||
if subj == "" {
|
||||
subj = cd.Subject
|
||||
if cd.Account != "" {
|
||||
subj = cd.Account
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%s:%s:%s", cd.Direction, cd.Tenant, subj)
|
||||
}
|
||||
@@ -713,9 +715,12 @@ func (cd *CallDescriptor) Clone() *CallDescriptor {
|
||||
}
|
||||
|
||||
func (cd *CallDescriptor) GetLCR() (*LCRCost, error) {
|
||||
lcr, err := dataStorage.GetLCR(cd.GetLCRKey(), false)
|
||||
lcr, err := dataStorage.GetLCR(cd.GetLCRKey(""), false)
|
||||
if err != nil || lcr == nil {
|
||||
return nil, err
|
||||
// try the *any customer
|
||||
if lcr, err = dataStorage.GetLCR(cd.GetLCRKey(utils.ANY), false); err != nil || lcr == nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
lcr.Sort()
|
||||
lcrCost := &LCRCost{
|
||||
@@ -757,6 +762,25 @@ func (cd *CallDescriptor) GetLCR() (*LCRCost, error) {
|
||||
}
|
||||
} else {
|
||||
// find rating profiles
|
||||
ratingProfileSearchKey := fmt.Sprintf("%s:%s:%s:", lcr.Direction, lcr.Tenant, ts.Entry.TOR)
|
||||
suppliers := cache2go.GetEntriesKeys(LCR_PREFIX + ratingProfileSearchKey)
|
||||
for _, supplier := range suppliers {
|
||||
split := strings.Split(supplier, ":")
|
||||
supplier = split[len(split)-1]
|
||||
lcrCD := cd.Clone()
|
||||
lcrCD.Subject = supplier
|
||||
if cc, err := lcrCD.GetCost(); err != nil || cc == nil {
|
||||
ts.SupplierCosts = append(ts.SupplierCosts, &LCRSupplierCost{
|
||||
Supplier: supplier,
|
||||
Error: err,
|
||||
})
|
||||
} else {
|
||||
ts.SupplierCosts = append(ts.SupplierCosts, &LCRSupplierCost{
|
||||
Supplier: supplier,
|
||||
Cost: cc.Cost,
|
||||
})
|
||||
}
|
||||
}
|
||||
// sort according to strategy
|
||||
ts.Sort()
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/cache2go"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -41,10 +44,12 @@ type LCRActivation struct {
|
||||
Entries []*LCREntry
|
||||
}
|
||||
type LCREntry struct {
|
||||
Destination string
|
||||
TOR string
|
||||
Strategy string
|
||||
Suppliers string
|
||||
DestinationId string
|
||||
TOR string
|
||||
Strategy string
|
||||
Suppliers string
|
||||
Weight float64
|
||||
precision int
|
||||
}
|
||||
|
||||
type LCRCost struct {
|
||||
@@ -83,7 +88,52 @@ func (lcr *LCR) Sort() {
|
||||
sort.Sort(lcr)
|
||||
}
|
||||
|
||||
func (lcra *LCRActivation) GetLCREntryForPrefix(prefix string) *LCREntry {
|
||||
type LCREntriesSorter []*LCREntry
|
||||
|
||||
func (es LCREntriesSorter) Len() int {
|
||||
return len(es)
|
||||
}
|
||||
|
||||
func (es LCREntriesSorter) Swap(i, j int) {
|
||||
es[i], es[j] = es[j], es[i]
|
||||
}
|
||||
|
||||
func (es LCREntriesSorter) Less(j, i int) bool {
|
||||
return es[i].precision < es[j].precision ||
|
||||
(es[i].precision == es[j].precision && es[i].Weight < es[j].Weight)
|
||||
|
||||
}
|
||||
|
||||
func (es LCREntriesSorter) Sort() {
|
||||
sort.Sort(es)
|
||||
}
|
||||
|
||||
func (lcra *LCRActivation) GetLCREntryForPrefix(destination string) *LCREntry {
|
||||
var potentials LCREntriesSorter
|
||||
for _, p := range utils.SplitPrefix(destination, MIN_PREFIX_MATCH) {
|
||||
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
|
||||
destIds := x.([]string)
|
||||
for _, dId := range destIds {
|
||||
for _, entry := range lcra.Entries {
|
||||
if entry.DestinationId == dId {
|
||||
entry.precision = len(p)
|
||||
potentials = append(potentials, entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(potentials) > 0 {
|
||||
// sort by precision and weight
|
||||
potentials.Sort()
|
||||
return potentials[0]
|
||||
}
|
||||
// return the *any entry if it exists
|
||||
for _, entry := range lcra.Entries {
|
||||
if entry.DestinationId == utils.ANY {
|
||||
return entry
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user