From fbab09d8040bfeb8c85a53f6049ed62277cb85d7 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Thu, 2 Feb 2012 14:38:41 +0200 Subject: [PATCH] new better splitting ;) --- timeslots/interval_test.go | 100 +++++++++++++++++++++---------------- timeslots/intervals.go | 40 +++++++-------- timeslots/timeslots.go | 13 +++++ 3 files changed, 89 insertions(+), 64 deletions(-) diff --git a/timeslots/interval_test.go b/timeslots/interval_test.go index 2d1bc1224..8337afd08 100644 --- a/timeslots/interval_test.go +++ b/timeslots/interval_test.go @@ -2,7 +2,7 @@ package timeslots import ( "time" - "testing" + "testing" ) func TestMonth(t *testing.T){ @@ -120,20 +120,24 @@ func TestRightMargin(t *testing.T){ t1 := time.Date(2012, time.February, 3, 23, 45, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 4, 0, 10, 0, 0, time.UTC) ts := &TimeSpan{TimeStart: t1, TimeEnd: t2} - result := i.Split(ts) - ts1, ts2 := result[0], result[1] - if ts1.TimeStart != t1 || ts1.TimeEnd != time.Date(2012, time.February, 3, 23, 59, 59, 0, time.UTC) { - t.Error("Incorrect first half", ts1) + oldDuration := ts.GetDuration() + nts := i.Split(ts) + if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 23, 59, 59, 0, time.UTC) { + t.Error("Incorrect first half", ts) } - if ts2.TimeStart != time.Date(2012, time.February, 3, 23, 59, 59, 0, time.UTC) || ts2.TimeEnd != t2 { - t.Error("Incorrect second half", ts2) + if nts.TimeStart != time.Date(2012, time.February, 3, 23, 59, 59, 0, time.UTC) || nts.TimeEnd != t2 { + t.Error("Incorrect second half", nts) } - if ts1.Interval != i { + if ts.Interval != i { t.Error("Interval not attached correctly") } - if ts1.GetDuration().Seconds() != 15 * 60 - 1 || ts2.GetDuration().Seconds() != 10 * 60 + 1 { - t.Error("Wrong durations.for Intervals", ts1.GetDuration().Seconds(), ts2.GetDuration().Seconds()) + if ts.GetDuration().Seconds() != 15 * 60 - 1 || nts.GetDuration().Seconds() != 10 * 60 + 1 { + t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), ts.GetDuration().Seconds()) + } + + if ts.GetDuration().Seconds() + nts.GetDuration().Seconds() != oldDuration.Seconds() { + t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) } } @@ -142,20 +146,23 @@ func TestRightHourMargin(t *testing.T){ t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 3, 18, 00, 0, 0, time.UTC) ts := &TimeSpan{TimeStart: t1, TimeEnd: t2} - result := i.Split(ts) - ts1, ts2 := result[0], result[1] - if ts1.TimeStart != t1 || ts1.TimeEnd != time.Date(2012, time.February, 3, 17, 59, 00, 0, time.UTC) { - t.Error("Incorrect first half", ts1) + oldDuration := ts.GetDuration() + nts := i.Split(ts) + if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 17, 59, 00, 0, time.UTC) { + t.Error("Incorrect first half", ts) } - if ts2.TimeStart != time.Date(2012, time.February, 3, 17, 59, 00, 0, time.UTC) || ts2.TimeEnd != t2 { - t.Error("Incorrect second half", ts2) + if nts.TimeStart != time.Date(2012, time.February, 3, 17, 59, 00, 0, time.UTC) || nts.TimeEnd != t2 { + t.Error("Incorrect second half", nts) } - if ts1.Interval != i { + if ts.Interval != i { t.Error("Interval not attached correctly") } - if ts1.GetDuration().Seconds() != 29 * 60 || ts2.GetDuration().Seconds() != 1 * 60 { - t.Error("Wrong durations.for Intervals", ts1.GetDuration().Seconds(), ts2.GetDuration().Seconds()) + if ts.GetDuration().Seconds() != 29 * 60 || nts.GetDuration().Seconds() != 1 * 60 { + t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds()) + } + if ts.GetDuration().Seconds() + nts.GetDuration().Seconds() != oldDuration.Seconds() { + t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) } } @@ -164,19 +171,22 @@ func TestLeftMargin(t *testing.T){ t1 := time.Date(2012, time.February, 5, 23, 45, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 6, 0, 10, 0, 0, time.UTC) ts := &TimeSpan{TimeStart: t1, TimeEnd: t2} - result := i.Split(ts) - ts1, ts2 := result[0], result[1] - if ts1.TimeStart != t1 || ts1.TimeEnd != time.Date(2012, time.February, 6, 0, 0, 0, 0, time.UTC) { - t.Error("Incorrect first half", ts1) + oldDuration := ts.GetDuration() + nts := i.Split(ts) + if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 6, 0, 0, 0, 0, time.UTC) { + t.Error("Incorrect first half", ts) } - if ts2.TimeStart != time.Date(2012, time.February, 6, 0, 0, 0, 0, time.UTC) || ts2.TimeEnd != t2 { - t.Error("Incorrect second half", ts2) + if nts.TimeStart != time.Date(2012, time.February, 6, 0, 0, 0, 0, time.UTC) || nts.TimeEnd != t2 { + t.Error("Incorrect second half", nts) } - if ts2.Interval != i { + if nts.Interval != i { t.Error("Interval not attached correctly") } - if ts1.GetDuration().Seconds() != 15 * 60 || ts2.GetDuration().Seconds() != 10 * 60 { - t.Error("Wrong durations.for Intervals", ts1.GetDuration().Seconds(), ts2.GetDuration().Seconds()) + if ts.GetDuration().Seconds() != 15 * 60 || nts.GetDuration().Seconds() != 10 * 60 { + t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds()) + } + if ts.GetDuration().Seconds() + nts.GetDuration().Seconds() != oldDuration.Seconds() { + t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) } } @@ -185,19 +195,22 @@ func TestLeftHourMargin(t *testing.T){ t1 := time.Date(2012, time.December, 1, 8, 45, 0, 0, time.UTC) t2 := time.Date(2012, time.December, 1, 9, 20, 0, 0, time.UTC) ts := &TimeSpan{TimeStart: t1, TimeEnd: t2} - result := i.Split(ts) - ts1, ts2 := result[0], result[1] - if ts1.TimeStart != t1 || ts1.TimeEnd != time.Date(2012, time.December, 1, 9, 0, 0, 0, time.UTC) { - t.Error("Incorrect first half", ts1) + oldDuration := ts.GetDuration() + nts := i.Split(ts) + if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.December, 1, 9, 0, 0, 0, time.UTC) { + t.Error("Incorrect first half", ts) } - if ts2.TimeStart != time.Date(2012, time.December, 1, 9, 0, 0, 0, time.UTC) || ts2.TimeEnd != t2 { - t.Error("Incorrect second half", ts2) + if nts.TimeStart != time.Date(2012, time.December, 1, 9, 0, 0, 0, time.UTC) || nts.TimeEnd != t2 { + t.Error("Incorrect second half", nts) } - if ts2.Interval != i { + if nts.Interval != i { t.Error("Interval not attached correctly") } - if ts1.GetDuration().Seconds() != 15 * 60 || ts2.GetDuration().Seconds() != 20 * 60 { - t.Error("Wrong durations.for Intervals", ts1.GetDuration().Seconds(), ts2.GetDuration().Seconds()) + if ts.GetDuration().Seconds() != 15 * 60 || nts.GetDuration().Seconds() != 20 * 60 { + t.Error("Wrong durations.for Intervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds()) + } + if ts.GetDuration().Seconds() + nts.GetDuration().Seconds() != oldDuration.Seconds() { + t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) } } @@ -206,17 +219,16 @@ func TestEnclosingMargin(t *testing.T){ t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 5, 18, 10, 0, 0, time.UTC) ts := &TimeSpan{TimeStart: t1, TimeEnd: t2} - result := i.Split(ts) - ts1 := result[0] - if ts1.TimeStart != t1 || ts1.TimeEnd != t2 { - t.Error("Incorrect enclosing", ts1) + nts := i.Split(ts) + if ts.TimeStart != t1 || ts.TimeEnd != t2 || nts != nil{ + t.Error("Incorrect enclosing", ts) } - if ts1.Interval != i { + if ts.Interval != i { t.Error("Interval not attached correctly") } } -func TestOutsideMargin(t *testing.T){ +/*func TestOutsideMargin(t *testing.T){ i := &Interval{WeekDays: []time.Weekday{time.Monday}} t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 5, 18, 10, 0, 0, time.UTC) @@ -225,7 +237,7 @@ func TestOutsideMargin(t *testing.T){ if result != nil { t.Error("Interval not split correctly") } -} +}*/ func BenchmarkIntervalFull(b *testing.B) { i := &Interval{Month: time.February, MonthDay: 1, WeekDays: []time.Weekday{time.Wednesday, time.Thursday}, StartHour: "14:30", EndHour: "15:00"} diff --git a/timeslots/intervals.go b/timeslots/intervals.go index cd1657542..2e11696fc 100644 --- a/timeslots/intervals.go +++ b/timeslots/intervals.go @@ -3,7 +3,7 @@ package timeslots import ( "time" "strings" - "strconv" + "strconv" ) /* @@ -13,9 +13,8 @@ type Interval struct { Month time.Month MonthDay int WeekDays []time.Weekday - StartHour, EndHour string // ##:## format - Ponder float32 - ConnectFee, Price, BillingUnit float32 + StartHour, EndHour string // ##:## format + Ponder, ConnectFee, Price, BillingUnit float32 } /* @@ -114,35 +113,36 @@ func (i *Interval) getLeftMargin(t time.Time) (rigthtTime time.Time){ } /* -Returns nil if the time span has no period in the interval, a slice with the received timespan -if the timespan is fully enclosed in the interval or a slice with two timespans if the timespan -has only a margin in the interval. + */ -func (i *Interval) Split(ts *TimeSpan) (spans []*TimeSpan) { +func (i *Interval) Split(ts *TimeSpan) (nts *TimeSpan) { // if the span is not in interval return nil if !i.ContainsSpan(ts) { return } - // if the span is enclosed in the interval return the whole span + // if the span is enclosed in the interval try to set as new interval and return nil if i.ContainsFullSpan(ts){ - ts.Interval = i - spans = append(spans, ts) + ts.SetInterval(i) return } // if only the start time is in the interval splitt he interval if i.Contains(ts.TimeStart){ - splitTime := i.getRightMargin(ts.TimeStart) - t1 := &TimeSpan{TimeStart: ts.TimeStart, TimeEnd: splitTime, Interval: i} - t2 := &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd} - - spans = append(spans, t1, t2) + splitTime := i.getRightMargin(ts.TimeStart) + oldTimeEnd := ts.TimeEnd + ts.TimeEnd = splitTime + ts.SetInterval(i) + nts = &TimeSpan{TimeStart: splitTime, TimeEnd: oldTimeEnd} + return } // if only the end time is in the interval split the interval - if i.Contains(ts.TimeEnd){ + if i.Contains(ts.TimeEnd){ splitTime := i.getLeftMargin(ts.TimeEnd) - t1 := &TimeSpan{TimeStart: ts.TimeStart, TimeEnd: splitTime} - t2 := &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd, Interval: i} - spans = append(spans, t1, t2) + oldTimeEnd := ts.TimeEnd + ts.TimeEnd = splitTime + nts = &TimeSpan{TimeStart: splitTime, TimeEnd: oldTimeEnd} + nts.SetInterval(i) + return } return } + diff --git a/timeslots/timeslots.go b/timeslots/timeslots.go index ba5629c98..bd46b1fa4 100644 --- a/timeslots/timeslots.go +++ b/timeslots/timeslots.go @@ -77,6 +77,19 @@ func (ts *TimeSpan) GetDuration() time.Duration { return ts.TimeEnd.Sub(ts.TimeStart) } +/* +will set ne interval as spans's interval if new ponder is greater then span's interval ponder +or if the ponders are equal and new price is lower then spans's interval price +*/ +func (ts *TimeSpan) SetInterval(i *Interval) { + if ts.Interval == nil || ts.Interval.Ponder < i.Ponder { + ts.Interval = i + } + if ts.Interval.Ponder == i.Ponder && i.Price < ts.Interval.Price { + ts.Interval = i + } +} + /* The input stucture that contains call information. */