diff --git a/add.go b/add.go index a39ef94..969078b 100644 --- a/add.go +++ b/add.go @@ -1,5 +1,7 @@ package interval +import "math" + func (intvls *intervals) Add(low, high int, obj interface{}) error { itvl := &Interval{ Low: low, @@ -10,6 +12,17 @@ func (intvls *intervals) Add(low, high int, obj interface{}) error { } func (intvls *intervals) AddInterval(itvl *Interval) error { + + // the first time an interval is added, we check if a self adjustment is programmed to update some control variables + if len(intvls.Intervals) == 0 { + if intvls.SelfAdjustMinLow { + intvls.MinLow = math.MaxInt64 + } + if intvls.SelfAdjustMaxHigh { + intvls.MaxHigh = math.MinInt64 + } + } + low := intvls.getInclusiveLow(itvl.Low) high := intvls.getInclusiveHigh(itvl.High) @@ -18,6 +31,13 @@ func (intvls *intervals) AddInterval(itvl *Interval) error { return err } + if intvls.SelfAdjustMaxHigh && high > intvls.MaxHigh { + intvls.MaxHigh = high + } + if intvls.SelfAdjustMinLow && low < intvls.MinLow { + intvls.MinLow = low + } + intvls.Intervals = append(intvls.Intervals, itvl) intvls.reset() return nil diff --git a/demo_test.go b/demo_test.go index 913ae42..26880b9 100644 --- a/demo_test.go +++ b/demo_test.go @@ -2,6 +2,7 @@ package interval_test import ( "fmt" + "math" "bitbucket.org/differenttravel/interval" ) @@ -19,14 +20,16 @@ type demo struct { /// Tests from 000 to 099: low/high are inclusive /// /////////////////////////////////////////////////////////// -// no intervals (low/high inclusive) --> all is a gap +// no intervals (low/high inclusive) --> all is a gap (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo001() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // calculate expected gaps gaps := []interval.Interval{} @@ -41,14 +44,16 @@ func buildIntervalsDemo001() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval at the beginning (low/high inclusive) +// one interval at the beginning (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo002() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 4}); err != nil { @@ -69,14 +74,16 @@ func buildIntervalsDemo002() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval at the end (low/high inclusive) +// one interval at the end (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo003() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 8, High: maxHigh}); err != nil { @@ -97,14 +104,16 @@ func buildIntervalsDemo003() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval in the middle (low/high inclusive) +// one interval in the middle (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo004() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 8}); err != nil { @@ -126,14 +135,16 @@ func buildIntervalsDemo004() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, one inside the other (low/high inclusive) +// two intervals in the middle, one inside the other (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo005() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 8}); err != nil { @@ -159,14 +170,16 @@ func buildIntervalsDemo005() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, not overlapping (low/high inclusive) +// two intervals in the middle, not overlapping (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo006() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -193,14 +206,16 @@ func buildIntervalsDemo006() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, consecutives (not overlapping) (low/high inclusive) +// two intervals in the middle, consecutives (not overlapping) (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo007() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 3}); err != nil { @@ -225,14 +240,16 @@ func buildIntervalsDemo007() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, overlapping by 1 position (low/high inclusive) +// two intervals in the middle, overlapping by 1 position (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo008() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 6}); err != nil { @@ -258,14 +275,16 @@ func buildIntervalsDemo008() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, overlapping by 3 positions (low/high inclusive) +// two intervals in the middle, overlapping by 3 positions (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo009() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 6}); err != nil { @@ -291,14 +310,16 @@ func buildIntervalsDemo009() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// three intervals (leading, middle and trailing), not overlapping (low/high inclusive) +// three intervals (leading, middle and trailing), not overlapping (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo010() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 2}); err != nil { @@ -328,14 +349,16 @@ func buildIntervalsDemo010() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// three intervals (in the middle), overlapping (low/high inclusive) +// three intervals (in the middle), overlapping (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo011() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -365,14 +388,16 @@ func buildIntervalsDemo011() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// complex case with a lot of intervals and overlapping (low/high inclusive) +// complex case with a lot of intervals and overlapping (low/high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo012() demo { // initialize Intervals minLow := 0 maxHigh := 100 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil { @@ -431,18 +456,216 @@ func buildIntervalsDemo012() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } +// complex case with a lot of intervals and overlapping (low/high inclusive, selfAdjustMinLow=false and selfAdjustMaxHigh=true) +func buildIntervalsDemo013() demo { + // initialize Intervals + minLow := 0 + maxHigh := math.MaxInt64 + lowInclusive := true + highInclusive := true + selfAdjustMinLow := false + selfAdjustMaxHigh := true + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) + + // add intervals + if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 35, High: 35}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 3, High: 6}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 18, High: 20}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 20, High: 30}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 25, High: 28}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 1}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 30, High: 32}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 10, High: 12}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + + // calculate expected gaps + gaps := []interval.Interval{} + gaps = append(gaps, interval.Interval{Low: 8, High: 9}) + gaps = append(gaps, interval.Interval{Low: 13, High: 17}) + gaps = append(gaps, interval.Interval{Low: 33, High: 34}) + + // calculate expected overlaps + overlaps := []interval.Interval{} + overlaps = append(overlaps, interval.Interval{Low: 3, High: 4}) + overlaps = append(overlaps, interval.Interval{Low: 5, High: 6}) + overlaps = append(overlaps, interval.Interval{Low: 20, High: 20}) + overlaps = append(overlaps, interval.Interval{Low: 25, High: 28}) + overlaps = append(overlaps, interval.Interval{Low: 30, High: 30}) + + // calculate expected merges + merges := []interval.Interval{} + merges = append(merges, interval.Interval{Low: minLow, High: 7}) + merges = append(merges, interval.Interval{Low: 10, High: 12}) + merges = append(merges, interval.Interval{Low: 18, High: 32}) + merges = append(merges, interval.Interval{Low: 35, High: 35}) + + return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} +} + +// complex case with a lot of intervals and overlapping (low/high inclusive, selfAdjustMinLow=true and selfAdjustMaxHigh=true) +func buildIntervalsDemo014() demo { + // initialize Intervals + minLow := 0 + maxHigh := math.MaxInt64 + lowInclusive := true + highInclusive := true + selfAdjustMinLow := true + selfAdjustMaxHigh := true + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) + + // add intervals + if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 35, High: 35}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 3, High: 6}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 18, High: 20}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 20, High: 30}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 25, High: 28}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 30, High: 32}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 10, High: 12}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + + // calculate expected gaps + gaps := []interval.Interval{} + gaps = append(gaps, interval.Interval{Low: 8, High: 9}) + gaps = append(gaps, interval.Interval{Low: 13, High: 17}) + gaps = append(gaps, interval.Interval{Low: 33, High: 34}) + + // calculate expected overlaps + overlaps := []interval.Interval{} + overlaps = append(overlaps, interval.Interval{Low: 3, High: 4}) + overlaps = append(overlaps, interval.Interval{Low: 5, High: 6}) + overlaps = append(overlaps, interval.Interval{Low: 20, High: 20}) + overlaps = append(overlaps, interval.Interval{Low: 25, High: 28}) + overlaps = append(overlaps, interval.Interval{Low: 30, High: 30}) + + // calculate expected merges + merges := []interval.Interval{} + merges = append(merges, interval.Interval{Low: 2, High: 7}) + merges = append(merges, interval.Interval{Low: 10, High: 12}) + merges = append(merges, interval.Interval{Low: 18, High: 32}) + merges = append(merges, interval.Interval{Low: 35, High: 35}) + + return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} +} + +// complex case with a lot of intervals and overlapping (low/high inclusive, selfAdjustMinLow=true and selfAdjustMaxHigh=false) +func buildIntervalsDemo015() demo { + // initialize Intervals + minLow := 0 + maxHigh := 40 + lowInclusive := true + highInclusive := true + selfAdjustMinLow := true + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) + + // add intervals + if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 35, High: 35}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 3, High: 6}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 18, High: 20}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 20, High: 30}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 25, High: 28}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 30, High: 32}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + if err := itvls.AddInterval(&interval.Interval{Low: 10, High: 12}); err != nil { + fmt.Printf("invalid interval discarded: %v\n", err) + } + + // calculate expected gaps + gaps := []interval.Interval{} + gaps = append(gaps, interval.Interval{Low: 8, High: 9}) + gaps = append(gaps, interval.Interval{Low: 13, High: 17}) + gaps = append(gaps, interval.Interval{Low: 33, High: 34}) + gaps = append(gaps, interval.Interval{Low: 36, High: maxHigh}) + + // calculate expected overlaps + overlaps := []interval.Interval{} + overlaps = append(overlaps, interval.Interval{Low: 3, High: 4}) + overlaps = append(overlaps, interval.Interval{Low: 5, High: 6}) + overlaps = append(overlaps, interval.Interval{Low: 20, High: 20}) + overlaps = append(overlaps, interval.Interval{Low: 25, High: 28}) + overlaps = append(overlaps, interval.Interval{Low: 30, High: 30}) + + // calculate expected merges + merges := []interval.Interval{} + merges = append(merges, interval.Interval{Low: 2, High: 7}) + merges = append(merges, interval.Interval{Low: 10, High: 12}) + merges = append(merges, interval.Interval{Low: 18, High: 32}) + merges = append(merges, interval.Interval{Low: 35, High: 35}) + + return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} +} + /////////////////////////////////////////////////////////// /// Tests from 100 to 199: low/high are exclusive /// /////////////////////////////////////////////////////////// -// no intervals (low/high are exclusive) +// no intervals (low/high are exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo101() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // calculate expected gaps gaps := []interval.Interval{} @@ -457,14 +680,16 @@ func buildIntervalsDemo101() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval at the beginning (low/high exclusive) +// one interval at the beginning (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo102() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 4}); err != nil { @@ -486,14 +711,16 @@ func buildIntervalsDemo102() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval at the end (low/high exclusive) +// one interval at the end (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo103() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 8, High: maxHigh}); err != nil { @@ -515,14 +742,16 @@ func buildIntervalsDemo103() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval in the middle (low/high exclusive) +// one interval in the middle (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo104() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 8}); err != nil { @@ -544,14 +773,16 @@ func buildIntervalsDemo104() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, one inside the other (low/high exclusive) +// two intervals in the middle, one inside the other (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo105() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 8}); err != nil { @@ -577,14 +808,16 @@ func buildIntervalsDemo105() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low/high exclusive) +// two intervals in the middle (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo106() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -611,14 +844,16 @@ func buildIntervalsDemo106() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, consecutives (low/high exclusive) +// two intervals in the middle, consecutives (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo107() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -645,14 +880,16 @@ func buildIntervalsDemo107() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low/high exclusive) +// two intervals in the middle (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo108() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 6}); err != nil { @@ -677,14 +914,16 @@ func buildIntervalsDemo108() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low/high exclusive) +// two intervals in the middle (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo109() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 6}); err != nil { @@ -710,14 +949,16 @@ func buildIntervalsDemo109() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// three intervals (leading, middle and trailing) (low/high exclusive) +// three intervals (leading, middle and trailing) (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo110() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 2}); err != nil { @@ -747,14 +988,16 @@ func buildIntervalsDemo110() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// three intervals (in the middle) (low/high exclusive) +// three intervals (in the middle) (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo111() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -782,14 +1025,16 @@ func buildIntervalsDemo111() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// complex case with a lot of intervals (low/high exclusive) +// complex case with a lot of intervals (low/high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo112() demo { // initialize Intervals minLow := 0 maxHigh := 100 lowInclusive := false highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil { @@ -851,14 +1096,16 @@ func buildIntervalsDemo112() demo { /// Tests from 200 to 299: low inclusive and high exclusive /// ///////////////////////////////////////////////////////////////// -// no intervals (low inclusive and high exclusive) --> all is a gap +// no intervals (low inclusive and high exclusive) --> all is a gap (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo201() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // calculate expected gaps gaps := []interval.Interval{} @@ -873,14 +1120,16 @@ func buildIntervalsDemo201() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval at the beginning (low inclusive and high exclusive) +// one interval at the beginning (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo202() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 4}); err != nil { @@ -901,14 +1150,16 @@ func buildIntervalsDemo202() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval at the end (low inclusive and high exclusive) +// one interval at the end (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo203() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 8, High: maxHigh}); err != nil { @@ -930,14 +1181,16 @@ func buildIntervalsDemo203() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval in the middle (low inclusive and high exclusive) +// one interval in the middle (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo204() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 8}); err != nil { @@ -959,14 +1212,16 @@ func buildIntervalsDemo204() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, one inside the other (low inclusive and high exclusive) +// two intervals in the middle, one inside the other (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo205() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 8}); err != nil { @@ -992,14 +1247,16 @@ func buildIntervalsDemo205() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low inclusive and high exclusive) +// two intervals in the middle (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo206() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -1026,14 +1283,16 @@ func buildIntervalsDemo206() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, consecutives (low inclusive and high exclusive) +// two intervals in the middle, consecutives (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo207() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -1058,14 +1317,16 @@ func buildIntervalsDemo207() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low inclusive and high exclusive) +// two intervals in the middle (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo208() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 6}); err != nil { @@ -1090,14 +1351,16 @@ func buildIntervalsDemo208() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low inclusive and high exclusive) +// two intervals in the middle (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo209() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 6}); err != nil { @@ -1123,14 +1386,16 @@ func buildIntervalsDemo209() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// three intervals (leading, middle and trailing) (low inclusive and high exclusive) +// three intervals (leading, middle and trailing) (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo210() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 2}); err != nil { @@ -1159,14 +1424,16 @@ func buildIntervalsDemo210() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// three intervals (in the middle) (low inclusive and high exclusive) +// three intervals (in the middle) (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo211() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -1196,14 +1463,16 @@ func buildIntervalsDemo211() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// complex case with a lot of intervals (low inclusive and high exclusive) +// complex case with a lot of intervals (low inclusive and high exclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo212() demo { // initialize Intervals minLow := 0 maxHigh := 100 lowInclusive := true highInclusive := false - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil { @@ -1264,14 +1533,16 @@ func buildIntervalsDemo212() demo { /// Tests from 300 to 399: low exclusive and high inclusive /// ///////////////////////////////////////////////////////////////// -// no intervals (low exclusive and high inclusive) --> all is a gap +// no intervals (low exclusive and high inclusive) --> all is a gap (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo301() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // calculate expected gaps gaps := []interval.Interval{} @@ -1286,14 +1557,16 @@ func buildIntervalsDemo301() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval at the beginning (low exclusive and high inclusive) +// one interval at the beginning (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo302() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 4}); err != nil { @@ -1315,14 +1588,16 @@ func buildIntervalsDemo302() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval at the end (low exclusive and high inclusive) +// one interval at the end (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo303() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 8, High: maxHigh}); err != nil { @@ -1343,14 +1618,16 @@ func buildIntervalsDemo303() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// one interval in the middle (low exclusive and high inclusive) +// one interval in the middle (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo304() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 8}); err != nil { @@ -1372,14 +1649,16 @@ func buildIntervalsDemo304() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, one inside the other (low exclusive and high inclusive) +// two intervals in the middle, one inside the other (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo305() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 8}); err != nil { @@ -1405,14 +1684,16 @@ func buildIntervalsDemo305() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low exclusive and high inclusive) +// two intervals in the middle (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo306() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -1439,14 +1720,16 @@ func buildIntervalsDemo306() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle, consecutives (low exclusive and high inclusive) +// two intervals in the middle, consecutives (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo307() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -1471,14 +1754,16 @@ func buildIntervalsDemo307() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low exclusive and high inclusive) +// two intervals in the middle (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo308() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 6}); err != nil { @@ -1503,14 +1788,16 @@ func buildIntervalsDemo308() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// two intervals in the middle (low exclusive and high inclusive) +// two intervals in the middle (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo309() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 6}); err != nil { @@ -1536,14 +1823,16 @@ func buildIntervalsDemo309() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// three intervals (leading, middle and trailing) (low exclusive and high inclusive) +// three intervals (leading, middle and trailing) (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo310() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: minLow, High: 2}); err != nil { @@ -1572,14 +1861,16 @@ func buildIntervalsDemo310() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// three intervals (in the middle) (low exclusive and high inclusive) +// three intervals (in the middle) (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo311() demo { // initialize Intervals minLow := 0 maxHigh := 10 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 2, High: 4}); err != nil { @@ -1609,14 +1900,16 @@ func buildIntervalsDemo311() demo { return demo{Intervals: itvls, ExpectedGaps: gaps, ExpectedOverlaps: overlaps, ExpectedMerges: merges} } -// complex case with a lot of intervals (low exclusive and high inclusive) +// complex case with a lot of intervals (low exclusive and high inclusive) (selfAdjustMinLow/selfAdjustMaxHigh=false) func buildIntervalsDemo312() demo { // initialize Intervals minLow := 0 maxHigh := 100 lowInclusive := false highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := false + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil { diff --git a/example/main.go b/example/main.go index 241c599..6591a56 100644 --- a/example/main.go +++ b/example/main.go @@ -91,7 +91,14 @@ func readData(path string) ([]xy, error) { } func initIntervals(xys []xy) interval.Intervals { - intervals := interval.NewIntervals(MinX, MaxX, true, true) + // initialize Intervals + minLow := MinX + maxHigh := MaxX + lowInclusive = true + highInclusive = true + selfAdjustMinLow := false + selfAdjustMaxHigh := true + intervals := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) if intervals.IsLowInclusive() { intervalOpening = "[" @@ -110,7 +117,7 @@ func initIntervals(xys []xy) interval.Intervals { } for _, xy := range xys { - err := intervals.Add(&interval.Interval{Low: xy.x, High: xy.y}) + err := intervals.AddInterval(&interval.Interval{Low: xy.x, High: xy.y}) if err != nil { fmt.Printf("invalid interval discarded: %v\n", err) } @@ -127,7 +134,7 @@ func convertToPlotterXYs(intervals []*interval.Interval) plotter.XYs { return pxys } -func alignPlots(plotItems []*Superplot) *vgimg.Canvas { +func alignPlots(plotItems []*Superplot, minLow, maxHigh int) *vgimg.Canvas { rows, cols := len(plotItems), 1 plots := make([][]*plot.Plot, rows) for j := 0; j < rows; j++ { @@ -136,8 +143,8 @@ func alignPlots(plotItems []*Superplot) *vgimg.Canvas { p := plotItems[j] // make sure the horizontal scales match - p.Plot.X.Min = MinX - p.Plot.X.Max = MaxX + p.Plot.X.Min = float64(minLow) // MinX + p.Plot.X.Max = float64(maxHigh) //MaxX plots[j][i] = p.Plot } @@ -232,7 +239,7 @@ func plotData(path string, intervals interval.Intervals) error { plots = append(plots, p4) // join all plots, align them - canvas := alignPlots(plots) + canvas := alignPlots(plots, intervals.GetMinLow(), intervals.GetMaxHigh()) err = createFileFromCanvas("out.png", canvas) if err != nil { return err diff --git a/find_test.go b/find_test.go index 801b884..99ed31f 100644 --- a/find_test.go +++ b/find_test.go @@ -13,7 +13,9 @@ func initIntervalsForDemo001() interval.Intervals { maxHigh := 100 lowInclusive := true highInclusive := true - itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive) + selfAdjustMinLow := false + selfAdjustMaxHigh := true + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) // add new intervals if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil { diff --git a/gaps_test.go b/gaps_test.go index 5ee2c32..ab72f89 100644 --- a/gaps_test.go +++ b/gaps_test.go @@ -20,6 +20,9 @@ func TestGaps(t *testing.T) { demo010 := buildIntervalsDemo010() demo011 := buildIntervalsDemo011() demo012 := buildIntervalsDemo012() + demo013 := buildIntervalsDemo013() + demo014 := buildIntervalsDemo014() + demo015 := buildIntervalsDemo015() // tests for low/high exclusive demo101 := buildIntervalsDemo101() @@ -79,6 +82,9 @@ func TestGaps(t *testing.T) { {name: "demo010", intvls: demo010.Intervals, expectedGaps: demo010.ExpectedGaps}, {name: "demo011", intvls: demo011.Intervals, expectedGaps: demo011.ExpectedGaps}, {name: "demo012", intvls: demo012.Intervals, expectedGaps: demo012.ExpectedGaps}, + {name: "demo013", intvls: demo013.Intervals, expectedGaps: demo013.ExpectedGaps}, + {name: "demo014", intvls: demo014.Intervals, expectedGaps: demo014.ExpectedGaps}, + {name: "demo015", intvls: demo015.Intervals, expectedGaps: demo015.ExpectedGaps}, {name: "demo101", intvls: demo101.Intervals, expectedGaps: demo101.ExpectedGaps}, {name: "demo102", intvls: demo102.Intervals, expectedGaps: demo102.ExpectedGaps}, @@ -122,6 +128,9 @@ func TestGaps(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { + // if tc.name == "demo014" { + // fmt.Printf("stop point") + // } gaps := tc.intvls.Gaps() unexpectedLength := false if len(gaps) != len(tc.expectedGaps) { diff --git a/get.go b/get.go index 06f5df7..28f8f20 100644 --- a/get.go +++ b/get.go @@ -1,6 +1,6 @@ package interval -func (intvls *intervals) Get() []*Interval { +func (intvls *intervals) GetIntervals() []*Interval { // sort intervals (if necessary) intvls.Sort() diff --git a/intervals.go b/intervals.go index 3daebc2..1e291d2 100644 --- a/intervals.go +++ b/intervals.go @@ -5,10 +5,12 @@ import ( ) const ( - defaultMinLow = 0 - defaultMaxHigh = math.MaxInt64 - defaultLowInclusive = true - defaultHighInclusive = true + defaultMinLow = 0 + defaultMaxHigh = math.MaxInt64 + defaultLowInclusive = true + defaultHighInclusive = true + defaultSelfAdjustMinLow = false + defaultSelfAdjustMaxHigh = true ) // Intervals is an interface to handle Interval structures discovering the existence of gaps or overlays @@ -26,7 +28,7 @@ type Intervals interface { HasGaps() bool // Get returns the interval list - Get() []*Interval + GetIntervals() []*Interval // Gaps returns the interval gaps Gaps() []*Interval @@ -43,43 +45,55 @@ type Intervals interface { // FindIntervalsForValue returns all the intervals which contains the passed value FindIntervalsForValue(value int) []*Interval - // Report creates a report of the interval sequence - Report() string - // IsLowInclusive indicates if the Low part of the interval is included, e. g. (3,5) --> the 3 is included as part of the interval IsLowInclusive() bool // IsHighInclusive indicates if the High part of the interval is included, e. g. (3,5) --> the 5 is included as part of the interval IsHighInclusive() bool + + // GetMinLow returns the minimal Low, either the one configured in the constructor, or the self-adjusted calculated if SelfAdjustMinLow=true + GetMinLow() int + + // GetMaxHigh returns the maximal High, either the one configured in the constructor, or the self-adjusted calculated if SelfAdjustMaxHigh=true + GetMaxHigh() int } // intervals implements Intervals interface type intervals struct { - Intervals []*Interval - GapsList []*Interval - OverlappedList []*Interval - MergeList []*Interval - MinLow int - MaxHigh int - Sorted bool - LowInclusive bool - HighInclusive bool + Intervals []*Interval + GapsList []*Interval + OverlappedList []*Interval + MergeList []*Interval + MinLow int + MaxHigh int + Sorted bool + LowInclusive bool + HighInclusive bool + SelfAdjustMinLow bool // set the minLow to the minimal Low value passed in Add or AddInterval methods + SelfAdjustMaxHigh bool // set the maxHigh to the maximal High value passed in Add or AddInterval methods +} + +// String implements Stringer.Interface Interval +func (itvls *intervals) String() string { + return itvls.report() } // NewIntervalsDefault is a constructor that returns an instance of the Intervals interface with default values func NewIntervalsDefault() Intervals { - return NewIntervals(defaultMinLow, defaultMaxHigh, defaultLowInclusive, defaultHighInclusive) + return NewIntervals(defaultMinLow, defaultMaxHigh, defaultLowInclusive, defaultHighInclusive, defaultSelfAdjustMinLow, defaultSelfAdjustMaxHigh) } // NewIntervals is a constructor that returns an instance of the Intervals interface -func NewIntervals(minLow int, maxHigh int, lowInclusive bool, highInclusive bool) Intervals { +func NewIntervals(minLow, maxHigh int, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh bool) Intervals { return &intervals{ - MinLow: minLow, - MaxHigh: maxHigh, - Intervals: []*Interval{}, - Sorted: false, - LowInclusive: lowInclusive, - HighInclusive: highInclusive, + MinLow: minLow, + MaxHigh: maxHigh, + Intervals: []*Interval{}, + Sorted: false, + LowInclusive: lowInclusive, + HighInclusive: highInclusive, + SelfAdjustMinLow: selfAdjustMinLow, + SelfAdjustMaxHigh: selfAdjustMaxHigh, } } @@ -90,3 +104,11 @@ func (intvls *intervals) IsLowInclusive() bool { func (intvls *intervals) IsHighInclusive() bool { return intvls.HighInclusive } + +func (intvls *intervals) GetMinLow() int { + return intvls.MinLow +} + +func (intvls *intervals) GetMaxHigh() int { + return intvls.MaxHigh +} diff --git a/merge_test.go b/merge_test.go index 7a01ca4..98be5a4 100644 --- a/merge_test.go +++ b/merge_test.go @@ -20,6 +20,9 @@ func TestMerge(t *testing.T) { demo010 := buildIntervalsDemo010() demo011 := buildIntervalsDemo011() demo012 := buildIntervalsDemo012() + demo013 := buildIntervalsDemo013() + demo014 := buildIntervalsDemo014() + demo015 := buildIntervalsDemo015() // tests for low/high exclusive demo101 := buildIntervalsDemo101() @@ -79,6 +82,9 @@ func TestMerge(t *testing.T) { {name: "demo010", intvls: demo010.Intervals, expectedMerges: demo010.ExpectedMerges}, {name: "demo011", intvls: demo011.Intervals, expectedMerges: demo011.ExpectedMerges}, {name: "demo012", intvls: demo012.Intervals, expectedMerges: demo012.ExpectedMerges}, + {name: "demo013", intvls: demo013.Intervals, expectedMerges: demo013.ExpectedMerges}, + {name: "demo014", intvls: demo014.Intervals, expectedMerges: demo014.ExpectedMerges}, + {name: "demo015", intvls: demo015.Intervals, expectedMerges: demo015.ExpectedMerges}, {name: "demo101", intvls: demo101.Intervals, expectedMerges: demo101.ExpectedMerges}, {name: "demo102", intvls: demo102.Intervals, expectedMerges: demo102.ExpectedMerges}, diff --git a/overlap_test.go b/overlap_test.go index 9120ef8..c189b75 100644 --- a/overlap_test.go +++ b/overlap_test.go @@ -20,6 +20,9 @@ func TestOverlapped(t *testing.T) { demo010 := buildIntervalsDemo010() demo011 := buildIntervalsDemo011() demo012 := buildIntervalsDemo012() + demo013 := buildIntervalsDemo013() + demo014 := buildIntervalsDemo014() + demo015 := buildIntervalsDemo015() // tests for low/high exclusive demo101 := buildIntervalsDemo101() @@ -79,6 +82,9 @@ func TestOverlapped(t *testing.T) { {name: "demo010", intvls: demo010.Intervals, expectedOverlaps: demo010.ExpectedOverlaps}, {name: "demo011", intvls: demo011.Intervals, expectedOverlaps: demo011.ExpectedOverlaps}, {name: "demo012", intvls: demo012.Intervals, expectedOverlaps: demo012.ExpectedOverlaps}, + {name: "demo013", intvls: demo013.Intervals, expectedOverlaps: demo013.ExpectedOverlaps}, + {name: "demo014", intvls: demo014.Intervals, expectedOverlaps: demo014.ExpectedOverlaps}, + {name: "demo015", intvls: demo015.Intervals, expectedOverlaps: demo015.ExpectedOverlaps}, {name: "demo101", intvls: demo101.Intervals, expectedOverlaps: demo101.ExpectedOverlaps}, {name: "demo102", intvls: demo102.Intervals, expectedOverlaps: demo102.ExpectedOverlaps}, diff --git a/report.go b/report.go index e2af599..011d183 100644 --- a/report.go +++ b/report.go @@ -25,7 +25,7 @@ func newSymbols() symbols { } } -func (intvls *intervals) Report() string { +func (intvls *intervals) report() string { intvls.Sort() symbols := newSymbols() intro := intvls.buildHeading() diff --git a/report_test.go b/report_test.go index 117ade5..cbb079f 100644 --- a/report_test.go +++ b/report_test.go @@ -8,7 +8,13 @@ import ( ) func TestReport(t *testing.T) { - itvls := interval.NewIntervals(0, 100, true, true) + minLow := 0 + maxHigh := 100 + lowInclusive := true + highInclusive := true + selfAdjustMinLow := false + selfAdjustMaxHigh := true + itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh) var err error err = itvls.AddInterval(&interval.Interval{Low: 5, High: 7}) @@ -49,7 +55,8 @@ func TestReport(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { - t.Log(tc.itvls.Report()) + // this will call report() which implements Springer interface + t.Log(tc.itvls) }) } }