first lcr algo

This commit is contained in:
Radu Ioan Fericean
2014-03-26 11:51:03 +02:00
parent e20605471e
commit 611743d3c5
3 changed files with 103 additions and 11 deletions

View File

@@ -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
}

View File

@@ -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()
}

View File

@@ -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
}