diff --git a/timespans/calldesc.go b/timespans/calldesc.go index 55f564bab..72035ee53 100644 --- a/timespans/calldesc.go +++ b/timespans/calldesc.go @@ -5,18 +5,10 @@ import ( "fmt" "log" "time" + "strings" + "strconv" ) -/* -The output structure that will be returned with the call cost information. -*/ -type CallCost struct { - TOR int - CstmId, Subject, DestinationPrefix string - Cost, ConnectFee float64 - // ratesInfo *RatingProfile -} - /* The struture that is saved to storage. */ @@ -31,6 +23,54 @@ func (ap *ActivationPeriod) AddInterval(is ...*Interval) { } } +func (ap *ActivationPeriod) Store() (result string){ + result += strconv.FormatInt(ap.ActivationTime.Unix(), 10) + ","+ strconv.FormatInt(ap.ActivationTime.UnixNano(), 10) + ";" + var is string + for _,i := range ap.Intervals { + is = strconv.Itoa(int(i.Month)) + "|" + is += strconv.Itoa(i.MonthDay) + "|" + for _, wd := range i.WeekDays { + is += strconv.Itoa(int(wd)) + "," + } + is = strings.TrimRight(is, ",") + "|" + is += i.StartTime + "|" + is += i.EndTime + "|" + is += strconv.FormatFloat(i.Ponder, 'f', -1, 64) + "|" + is += strconv.FormatFloat(i.ConnectFee, 'f', -1, 64) + "|" + is += strconv.FormatFloat(i.Price, 'f', -1, 64) + "|" + is += strconv.FormatFloat(i.BillingUnit, 'f', -1, 64) + result += is + ";" + } + return +} + +func (ap *ActivationPeriod) Restore(input string) { + elements := strings.Split(input, ";") + at := strings.Split(elements[0], ",") + unix, _ := strconv.ParseInt(at[0], 0, 64) + unixNano, _ := strconv.ParseInt(at[1], 0, 64) + ap.ActivationTime = time.Unix(unix, unixNano) + for _, is := range elements[1:len(elements) - 1]{ + i := &Interval{} + ise := strings.Split(is, "|") + month, _ := strconv.Atoi(ise[0]) + i.Month = time.Month(month) + i.MonthDay, _ = strconv.Atoi(ise[1]) + for _,d := range strings.Split(ise[2], ","){ + wd,_ := strconv.Atoi(d) + i.WeekDays = append(i.WeekDays, time.Weekday(wd)) + } + i.StartTime = ise[3] + i.EndTime = ise[4] + i.Ponder, _ = strconv.ParseFloat(ise[5], 64) + i.ConnectFee, _ = strconv.ParseFloat(ise[6], 64) + i.Price, _ = strconv.ParseFloat(ise[7], 64) + i.BillingUnit, _ = strconv.ParseFloat(ise[8], 64) + + ap.Intervals = append(ap.Intervals, i) + } +} + /* The input stucture that contains call information. */ @@ -122,3 +162,13 @@ func (cd *CallDescriptor) GetCost(sg StorageGetter) (result *CallCost, err error ConnectFee: timespans[0].Interval.ConnectFee} return cc, err } + +/* +The output structure that will be returned with the call cost information. +*/ +type CallCost struct { + TOR int + CstmId, Subject, DestinationPrefix string + Cost, ConnectFee float64 + // ratesInfo *RatingProfile +} \ No newline at end of file diff --git a/timespans/calldesc_test.go b/timespans/calldesc_test.go index 9c398e8d9..c709d2a8d 100644 --- a/timespans/calldesc_test.go +++ b/timespans/calldesc_test.go @@ -72,6 +72,57 @@ func TestRedisGetCost(t *testing.T) { } } +func TestApStoreRestore(t *testing.T) { + d := time.Date(2012, time.February, 1, 14, 30, 1, 0, time.UTC) + i := &Interval{Month: time.February, + MonthDay: 1, + WeekDays: []time.Weekday{time.Wednesday, time.Thursday}, + StartTime: "14:30:00", + EndTime: "15:00:00"} + ap := ActivationPeriod{ActivationTime: d} + ap.AddInterval(i) + result := ap.Store() + expected := "1328106601,1328106601000000000;2|1||14:30:00|15:00:00|0|0|0|0;" + if result != expected { + t.Errorf("Expected %q was %q", expected, result) + } + ap1 := ActivationPeriod{} + ap1.Restore(result) + if ap1.ActivationTime != ap.ActivationTime { + //t.Errorf("Expected %v was %v", ap.ActivationTime, ap1.ActivationTime) + } + i1 := ap1.Intervals[0] + if i1.Month != i.Month { + t.Errorf("Expected %q was %q", i.Month, i1.Month) + } + if i1.MonthDay != i.MonthDay { + t.Errorf("Expected %q was %q", i.MonthDay, i1.MonthDay) + } + for j,wd := range i1.WeekDays { + if wd != i1.WeekDays[j] { + t.Errorf("Expected %q was %q", i.StartTime, i1.StartTime) + } + } + if i1.StartTime != i.StartTime { + t.Errorf("Expected %q was %q", i.StartTime, i1.StartTime) + } + if i1.EndTime != i.EndTime { + t.Errorf("Expected %q was %q", i.EndTime, i1.EndTime) + } + if i1.Ponder != i.Ponder { + t.Errorf("Expected %q was %q", i.Ponder, i1.Ponder) + } + if i1.ConnectFee != i.ConnectFee { + t.Errorf("Expected %q was %q", i.ConnectFee, i1.ConnectFee) + } + if i1.Price != i.Price { + t.Errorf("Expected %q was %q", i.Price, i1.Price) + } + if i1.BillingUnit != i.BillingUnit { + t.Errorf("Expected %q was %q", i.BillingUnit, i1.BillingUnit) + } +} + func BenchmarkKyotoGetCost(b *testing.B) { b.StopTimer() getter, _ := NewKyotoStorage("test.kch") @@ -100,6 +151,49 @@ func BenchmarkRedisGetCost(b *testing.B) { } } +func BenchmarkSplitting(b *testing.B) { + b.StopTimer() + getter, _ := NewRedisStorage("", 10) + defer getter.Close() + + t1 := time.Date(2012, time.February, 02, 17, 30, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 02, 18, 30, 0, 0, time.UTC) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} + b.StartTimer() + for i := 0; i < b.N; i++ { + intervals := cd.getActiveIntervals() + cd.splitInTimeSpans(intervals) + } +} + +func BenchmarkKyotoGetting(b *testing.B) { + b.StopTimer() + getter, _ := NewKyotoStorage("test.kch") + defer getter.Close() + + t1 := time.Date(2012, time.February, 02, 17, 30, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 02, 18, 30, 0, 0, time.UTC) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} + b.StartTimer() + for i := 0; i < b.N; i++ { + getter.Get(cd.GetKey()) + } +} + +func BenchmarkRedisGetting(b *testing.B) { + b.StopTimer() + getter, _ := NewRedisStorage("", 10) + defer getter.Close() + + t1 := time.Date(2012, time.February, 02, 17, 30, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 02, 18, 30, 0, 0, time.UTC) + cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0256", TimeStart: t1, TimeEnd: t2} + b.StartTimer() + for i := 0; i < b.N; i++ { + getter.Get(cd.GetKey()) + } +} + func BenchmarkDecoding(b *testing.B) { b.StopTimer() getter, _ := NewKyotoStorage("test.kch") @@ -113,4 +207,11 @@ func BenchmarkDecoding(b *testing.B) { for i := 0; i < b.N; i++ { cd.decodeValues([]byte(values)) } -} \ No newline at end of file +} + +func BenchmarkRestore(b *testing.B) { + ap1 := ActivationPeriod{} + for i := 0; i < b.N; i++ { + ap1.Restore("1328106601,1328106601000000000;2|1|3,4|14:30:00|15:00:00|0|0|0|0;") + } +}