socumentation and organisation

This commit is contained in:
Radu Ioan Fericean
2012-02-07 13:44:30 +02:00
parent b2d81e141d
commit 60f5b9e897
4 changed files with 163 additions and 120 deletions

View File

@@ -0,0 +1,77 @@
package timespans
import (
"time"
"strings"
"strconv"
)
const LAYOUT = "2006-01-02T15:04:05Z07:00"
/*
The struture that is saved to storage.
*/
type ActivationPeriod struct {
ActivationTime time.Time
Intervals []*Interval
}
/*
Adds one ore more intervals to the internal interval list.
*/
func (ap *ActivationPeriod) AddInterval(is ...*Interval) {
for _, i := range is {
ap.Intervals = append(ap.Intervals, i)
}
}
/*
Serializes the objects for the storage.
*/
func (ap *ActivationPeriod) store() (result string){
result += ap.ActivationTime.Format(LAYOUT) + ";"
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
}
/*
De-serializes the objects for the storage.
*/
func (ap *ActivationPeriod) restore(input string) {
elements := strings.Split(input, ";")
ap.ActivationTime, _ = time.Parse(LAYOUT, elements[0])
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)
}
}

View File

@@ -0,0 +1,65 @@
package timespans
import (
"testing"
"time"
//"log"
)
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 := "2012-02-01T14:30:01Z;2|1|3,4|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 BenchmarkRestore(b *testing.B) {
ap1 := ActivationPeriod{}
for i := 0; i < b.N; i++ {
ap1.restore("1328106601;2|1|3,4|14:30:00|15:00:00|0|0|0|0;")
}
}

View File

@@ -4,70 +4,8 @@ import (
"fmt"
"time"
"strings"
"strconv"
)
const LAYOUT = "2006-01-02T15:04:05Z07:00"
/*
The struture that is saved to storage.
*/
type ActivationPeriod struct {
ActivationTime time.Time
Intervals []*Interval
}
func (ap *ActivationPeriod) AddInterval(is ...*Interval) {
for _, i := range is {
ap.Intervals = append(ap.Intervals, i)
}
}
func (ap *ActivationPeriod) store() (result string){
result += ap.ActivationTime.Format(LAYOUT) + ";"
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, ";")
ap.ActivationTime, _ = time.Parse(LAYOUT, elements[0])
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.
*/
@@ -78,12 +16,19 @@ type CallDescriptor struct {
ActivationPeriods []*ActivationPeriod
}
/*
Adds an activation period that applyes to current call descriptor.
*/
func (cd *CallDescriptor) AddActivationPeriod(aps ...*ActivationPeriod) {
for _, ap := range aps {
cd.ActivationPeriods = append(cd.ActivationPeriods, ap)
}
}
/*
Creates a string ready for storage containing the serialization of all
activation periods held in the internal list.
*/
func (cd *CallDescriptor) EncodeValues() (result string) {
for _, ap := range cd.ActivationPeriods {
result += ap.store() + "\n"
@@ -91,6 +36,9 @@ func (cd *CallDescriptor) EncodeValues() (result string) {
return
}
/*
Restores the activation periods list from a storage string.
*/
func (cd *CallDescriptor) decodeValues(v string) {
for _, aps := range strings.Split(v, "\n") {
if(len(aps)>0){
@@ -101,10 +49,16 @@ func (cd *CallDescriptor) decodeValues(v string) {
}
}
/*
Constructs the key for the storage lookup.
*/
func (cd *CallDescriptor) GetKey() string {
return fmt.Sprintf("%s:%s:%s", cd.CstmId, cd.Subject, cd.DestinationPrefix)
}
/*
Finds the intervals applicable to the call descriptior.
*/
func (cd *CallDescriptor) getActiveIntervals() (is []*Interval) {
now := time.Now()
// add a second in the future to be able to pick the active timestamp
@@ -122,6 +76,9 @@ func (cd *CallDescriptor) getActiveIntervals() (is []*Interval) {
return
}
/*
Splits the call timespan into sub time spans accordin to the received intervals.
*/
func (cd *CallDescriptor) splitInTimeSpans(intervals []*Interval) (timespans []*TimeSpan) {
ts1 := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd}
timespans = append(timespans, ts1)
@@ -138,6 +95,7 @@ func (cd *CallDescriptor) splitInTimeSpans(intervals []*Interval) (timespans []*
}
/*
Creates a CallCost structure with the cost nformation calculated for the received CallDescriptor.
*/
func (cd *CallDescriptor) GetCost(sg StorageGetter) (result *CallCost, err error) {
@@ -170,4 +128,4 @@ type CallCost struct {
CstmId, Subject, DestinationPrefix string
Cost, ConnectFee float64
// ratesInfo *RatingProfile
}
}

View File

@@ -79,57 +79,6 @@ 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 := "2012-02-01T14:30:01Z;2|1|3,4|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")
@@ -216,9 +165,3 @@ func BenchmarkDecoding(b *testing.B) {
}
}
func BenchmarkRestore(b *testing.B) {
ap1 := ActivationPeriod{}
for i := 0; i < b.N; i++ {
ap1.restore("1328106601;2|1|3,4|14:30:00|15:00:00|0|0|0|0;")
}
}