From f71a295449a694328672d8bef3cf2aa26617450c Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 24 Feb 2012 15:07:48 +0200 Subject: [PATCH] if no credit returns available free seconds (GetMaxSessionTime) --- timespans/calldesc.go | 12 +++++++-- timespans/calldesc_test.go | 42 ++++++++++++++++++++------------ timespans/test.kch | Bin 6298792 -> 6298864 bytes timespans/test_userbudgets.json | 3 +++ timespans/userbudget_test.go | 13 +++++++++- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/timespans/calldesc.go b/timespans/calldesc.go index 31fb5bb24..437f460b0 100644 --- a/timespans/calldesc.go +++ b/timespans/calldesc.go @@ -205,17 +205,25 @@ func (cd *CallDescriptor) getPresentSecondCost() (cost float64, err error) { } /* -Returns the cost of a second in the present time conditions. +Returns the aproximate max allowed session for user budget. It will try the max amount received in the call descriptor +and will decrease it by 10% for nine times. So if the user has little credit it will still allow 10% of the initial amount. +If the user has no credit then it will return 0. */ func (cd *CallDescriptor) GetMaxSessionTime() (seconds float64, err error) { _, err = cd.RestoreFromStorage() now := time.Now() - availableCredit := 0.0 + availableCredit, availableSeconds := 0.0, 0.0 if userBudget, err := cd.StorageGetter.GetUserBudget(cd.Subject); err == nil && userBudget != nil { availableCredit = userBudget.Credit + availableSeconds, _ = userBudget.getSecondsForPrefix(cd.StorageGetter, cd.DestinationPrefix) } else { return cd.Amount, err } + // check for zero budget + if availableCredit == 0 { + return availableSeconds, nil + } + maxSessionSeconds := cd.Amount for i := 0; i < 10; i++ { maxDuration, _ := time.ParseDuration(fmt.Sprintf("%vs", maxSessionSeconds)) diff --git a/timespans/calldesc_test.go b/timespans/calldesc_test.go index ac58bdea8..b271c321b 100644 --- a/timespans/calldesc_test.go +++ b/timespans/calldesc_test.go @@ -186,8 +186,8 @@ func TestMinutesCost(t *testing.T) { func TestMaxSessionTimeNoUserBudget(t *testing.T) { getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0723", StorageGetter: getter} - result, err := cd.GetMaxSessionTime(1000) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0723", StorageGetter: getter, Amount: 1000} + result, err := cd.GetMaxSessionTime() if result != 1000 || err != nil { t.Errorf("Expected %v was %v", 1000, result) } @@ -196,13 +196,23 @@ func TestMaxSessionTimeNoUserBudget(t *testing.T) { func TestMaxSessionTimeWithUserBudget(t *testing.T) { getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} - result, err := cd.GetMaxSessionTime(5400) + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} + result, err := cd.GetMaxSessionTime() if result != 1080 || err != nil { t.Errorf("Expected %v was %v", 1080, result) } } +func TestMaxSessionTimeNoCredit(t *testing.T) { + getter, _ := NewRedisStorage("tcp:127.0.0.1:6379", 10) + defer getter.Close() + cd := &CallDescriptor{CstmId: "vdf", Subject: "broker", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} + result, err := cd.GetMaxSessionTime() + if result != 100 || err != nil { + t.Errorf("Expected %v was %v", 100, result) + } +} + /*********************************** BENCHMARKS ***************************************/ func BenchmarkRedisGetting(b *testing.B) { b.StopTimer() @@ -336,10 +346,10 @@ func BenchmarkKyotoSingleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewKyotoStorage("test.kch") defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 100} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(100) + cd.GetMaxSessionTime() } } @@ -347,10 +357,10 @@ func BenchmarkKyotoMultipleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewKyotoStorage("test.kch") defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(5400) + cd.GetMaxSessionTime() } } @@ -358,10 +368,10 @@ func BenchmarkRedisSingleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewRedisStorage("", 10) defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 100} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(100) + cd.GetMaxSessionTime() } } @@ -369,10 +379,10 @@ func BenchmarkRedisMultipleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewRedisStorage("", 10) defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(5400) + cd.GetMaxSessionTime() } } @@ -380,10 +390,10 @@ func BenchmarkMongoSingleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewMongoStorage("127.0.0.1", "test") defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 100} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(100) + cd.GetMaxSessionTime() } } @@ -391,9 +401,9 @@ func BenchmarkMongoMultipleGetSessionTime(b *testing.B) { b.StopTimer() getter, _ := NewMongoStorage("127.0.0.1", "test") defer getter.Close() - cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter} + cd := &CallDescriptor{CstmId: "vdf", Subject: "minutosu", DestinationPrefix: "0723", StorageGetter: getter, Amount: 5400} b.StartTimer() for i := 0; i < b.N; i++ { - cd.GetMaxSessionTime(5400) + cd.GetMaxSessionTime() } } diff --git a/timespans/test.kch b/timespans/test.kch index 33669ac51b55a468222808efb46ec9fe039ac02e..31ae4235eb135fba89fccda989f051de07ebee9d 100644 GIT binary patch delta 367 zcmXYtM^0M-00sG&=1>D6G}DVAl#EG2GrdD-rnki>5(~rv$=PHXFJ>PW5m(>>7UB*Z zg9C5`ig?n@dh~AZ|3;o(_!p0s<-9J8J!OzUawQ^pk}m~PC`A&L4^k{8QYvLqE*0`o zDy2$3Nws{I8mW~!sh0+cNuxALv$RO7v`M>kNT+m3T)L%4zDTe1NxuxpS9$44$e?_a z@A5;2WLQRIRK_GJ<1!(WG9}Y8BeOCm^Rgg|vLws0BCGOK)?{5aWK*^zCEKziyRs+y zav+CtB*$`+<+S-CQWE)}Ntp_=sodG?OqdOW$Hu!qwIO+J55e1e?&(DQ2p delta 323 zcmWm8H&Q|Y002=522{)e6~v6$Rm=%<&N&so^#+zwY_GTA0*vFWtgOYIdHw!;zefrs zADLLZ?7tvc$Ri;MOGKhlE)`NKRT7hGsgYWVOP$n9gEUH$G)s%LN}IGxLOP^Vx+Ezn z>6WzgNU!uszYNHr3`s_YWkg10OvYtGCS^)WKhrWJS(%kNnU@7wlqFe~6$fG>TbCH+yYd$at6@zg0 QGanR#&~NJNEfEm?10LvMv;Y7A diff --git a/timespans/test_userbudgets.json b/timespans/test_userbudgets.json index 36056a68e..21cbf1db2 100644 --- a/timespans/test_userbudgets.json +++ b/timespans/test_userbudgets.json @@ -1,5 +1,8 @@ [ {"Id":"minutosu","Credit":21,"SmsCredit":0,"ResetDayOfTheMonth":10,"TariffPlanId":"seara","MinuteBuckets": + [{"Seconds":10,"Priority":10,"Price":0.01,"DestinationId":"nationale"}, + {"Seconds":100,"Priority":20,"Price":0,"DestinationId":"retea"}]}, +{"Id":"broker","Credit":0,"SmsCredit":0,"ResetDayOfTheMonth":10,"TariffPlanId":"seara","MinuteBuckets": [{"Seconds":10,"Priority":10,"Price":0.01,"DestinationId":"nationale"}, {"Seconds":100,"Priority":20,"Price":0,"DestinationId":"retea"}]} ] diff --git a/timespans/userbudget_test.go b/timespans/userbudget_test.go index 2ac8b6718..6349c6416 100644 --- a/timespans/userbudget_test.go +++ b/timespans/userbudget_test.go @@ -10,7 +10,7 @@ var ( retea = &Destination{Id: "retea", Prefixes: []string{"0723", "0724"}} ) -func TestGetSeconds(t *testing.T) { +func TestGetSecondsForPrefix(t *testing.T) { b1 := &MinuteBucket{Seconds: 10, Priority: 10, destination: nationale} b2 := &MinuteBucket{Seconds: 100, Priority: 20, destination: retea} tf1 := &TariffPlan{MinuteBuckets: []*MinuteBucket{b1, b2}} @@ -305,3 +305,14 @@ func BenchmarkUserBudgetMongoStoreRestore(b *testing.B) { getter.GetUserBudget(rifsBudget.Id) } } + +func BenchmarkGetSecondsForPrefix(b *testing.B) { + b1 := &MinuteBucket{Seconds: 10, Priority: 10, destination: nationale} + b2 := &MinuteBucket{Seconds: 100, Priority: 20, destination: retea} + tf1 := &TariffPlan{MinuteBuckets: []*MinuteBucket{b1, b2}} + + ub1 := &UserBudget{Id: "rif", MinuteBuckets: []*MinuteBucket{b1, b2}, Credit: 200, tariffPlan: tf1, ResetDayOfTheMonth: 10} + for i := 0; i < b.N; i++ { + ub1.getSecondsForPrefix(nil, "0723") + } +}