From a6a63b8f043ac1f54826748fa9dd9cd8e65076c9 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Sat, 18 Aug 2012 18:31:46 +0300 Subject: [PATCH] use destination id instead of prefix in rating profile --- timespans/csvreader.go | 22 ++++++++++------------ timespans/destinations.go | 17 +++++++---------- timespans/destinations_test.go | 13 +++++++++++-- timespans/ratingprofile.go | 28 ++++++++++++++++------------ timespans/units_counter.go | 2 +- timespans/userbalance.go | 3 +-- 6 files changed, 46 insertions(+), 39 deletions(-) diff --git a/timespans/csvreader.go b/timespans/csvreader.go index 6fe1b28b8..c78eba732 100644 --- a/timespans/csvreader.go +++ b/timespans/csvreader.go @@ -288,18 +288,16 @@ func (csvr *CSVReader) LoadRatingProfiles(fn string, comma rune) (err error) { csvr.ratingProfiles[key] = rp } for _, d := range csvr.destinations { - for _, p := range d.Prefixes { //destinations - ap, exists := csvr.activationPeriods[record[5]] - if !exists { - return errors.New(fmt.Sprintf("Could not load ratinTiming for tag: ", record[5])) - } - newAP := &ActivationPeriod{ActivationTime: at} - //copy(newAP.Intervals, ap.Intervals) - newAP.Intervals = append(newAP.Intervals, ap.Intervals...) - rp.AddActivationPeriodIfNotPresent(p, newAP) - if fallbacksubject != "" { - rp.FallbackKey = fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fallbacksubject) - } + ap, exists := csvr.activationPeriods[record[5]] + if !exists { + return errors.New(fmt.Sprintf("Could not load ratinTiming for tag: ", record[5])) + } + newAP := &ActivationPeriod{ActivationTime: at} + //copy(newAP.Intervals, ap.Intervals) + newAP.Intervals = append(newAP.Intervals, ap.Intervals...) + rp.AddActivationPeriodIfNotPresent(d.Id, newAP) + if fallbacksubject != "" { + rp.FallbackKey = fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fallbacksubject) } } } diff --git a/timespans/destinations.go b/timespans/destinations.go index e011101a0..aff74e278 100644 --- a/timespans/destinations.go +++ b/timespans/destinations.go @@ -48,20 +48,17 @@ func GetDestination(dId string) (d *Destination, err error) { /* De-serializes the destination for the storage. Used for key-value storages. */ -func (d *Destination) containsPrefix(prefix string) (bool, int) { +func (d *Destination) containsPrefix(prefix string) (precision int, ok bool) { if d == nil { - return false, 0 + return } - for i := len(prefix); i >= MIN_PREFIX_LENGTH; { - for _, p := range d.Prefixes { - if p == prefix[:i] { - return true, i - } + for _, p := range d.Prefixes { + if strings.Index(prefix, p) == 0 && len(p) > precision { + precision = len(p) + ok = true } - i-- } - - return false, 0 + return } func (d *Destination) String() (result string) { diff --git a/timespans/destinations_test.go b/timespans/destinations_test.go index 09805c885..82b2e0a4d 100644 --- a/timespans/destinations_test.go +++ b/timespans/destinations_test.go @@ -48,8 +48,17 @@ func TestDestinationStorageStore(t *testing.T) { func TestDestinationContainsPrefix(t *testing.T) { nationale := &Destination{Id: "nat", Prefixes: []string{"0257", "0256", "0723"}} - contains, precision := nationale.containsPrefix("0256") - if !contains || precision != len("0256") { + precision, ok := nationale.containsPrefix("0256") + if !ok || precision != len("0256") { + t.Error("Should contain prefix: ", nationale) + } + +} + +func TestDestinationContainsPrefixLong(t *testing.T) { + nationale := &Destination{Id: "nat", Prefixes: []string{"0257", "0256", "0723"}} + precision, ok := nationale.containsPrefix("0256723045") + if !ok || precision != len("0256") { t.Error("Should contain prefix: ", nationale) } diff --git a/timespans/ratingprofile.go b/timespans/ratingprofile.go index 0c663f693..f00be0240 100644 --- a/timespans/ratingprofile.go +++ b/timespans/ratingprofile.go @@ -20,6 +20,7 @@ package timespans import ( "errors" + "fmt" "strings" ) @@ -87,19 +88,22 @@ func (rp *RatingProfile) AddActivationPeriodIfNotPresent(destInfo string, aps .. } func (rp *RatingProfile) GetActivationPeriodsForPrefix(destPrefix string) (foundPrefix string, aps []*ActivationPeriod, err error) { - var found = false - foundPrefix = destPrefix - for i := len(foundPrefix); !found; { - if i >= MIN_PREFIX_LENGTH { - foundPrefix = foundPrefix[:i] - } else { - break + bestPrecision := 0 + for k, v := range rp.DestinationMap { + d, err := GetDestination(k) + if err != nil { + Logger.Err(fmt.Sprintf("Cannot find destination with id: ", k)) + continue + } + if precision, ok := d.containsPrefix(destPrefix); ok && precision > bestPrecision { + bestPrecision = precision + aps = v } - aps, found = rp.DestinationMap[foundPrefix] - i-- } - if !found { - return "", nil, errors.New("not found") + + if bestPrecision > 0 { + return destPrefix[:bestPrecision], aps, nil } - return + + return "", nil, errors.New("not found") } diff --git a/timespans/units_counter.go b/timespans/units_counter.go index 3b5d4263d..df3d129fa 100644 --- a/timespans/units_counter.go +++ b/timespans/units_counter.go @@ -57,7 +57,7 @@ func (uc *UnitsCounter) addMinutes(amount float64, prefix string) { Logger.Err(fmt.Sprintf("Minutes counter: unknown destination: ", mb.DestinationId)) continue } - if ok, _ := d.containsPrefix(prefix); ok { + if _, ok := d.containsPrefix(prefix); ok { mb.Seconds += amount break } diff --git a/timespans/userbalance.go b/timespans/userbalance.go index cb3694620..f5c9b0888 100644 --- a/timespans/userbalance.go +++ b/timespans/userbalance.go @@ -76,8 +76,7 @@ func (ub *UserBalance) getSecondsForPrefix(prefix string) (seconds, credit float if err != nil { continue } - contains, precision := d.containsPrefix(prefix) - if contains { + if precision, ok := d.containsPrefix(prefix); ok { mb.precision = precision if mb.Seconds > 0 { bucketList = append(bucketList, mb)