@@ -48,6 +48,7 @@ func filter(spans Spans, filterFunc func(Span) bool) Spans {
4848 return filtered
4949}
5050
51+ // getMax gets the latest of two timestamps, returning the latter if they are equal
5152func getMax (a , b time.Time ) time.Time {
5253 if a .After (b ) {
5354 return a
@@ -56,6 +57,7 @@ func getMax(a, b time.Time) time.Time {
5657 return b
5758}
5859
60+ // getMax gets the earliest of two timestamps, returning the latter if they are equal
5961func getMin (a , b time.Time ) time.Time {
6062 if a .Before (b ) {
6163 return a
@@ -76,15 +78,18 @@ func IsInstant(a Span) bool {
7678// It returns two Span elements in Spans, if the intersector is within the baseSpan. this creates
7779// a Span baseSpan.Start->interseector.Start and intersector.End->baseSpan.End
7880func Without (a , b Span ) Spans {
79- var residues Spans
81+ residues := Spans {}
8082
8183 baseStart := a .Start ()
8284 baseEnd := a .End ()
8385 interStart := b .Start ()
8486 interEnd := b .End ()
8587
86- // ----++++++----
87- // ------++------
88+ // We do not want to split a Span with a no-duration time span
89+ if IsInstant (b ) {
90+ residues = append (residues , a )
91+ return residues
92+ }
8893
8994 switch {
9095 case baseStart .Before (interStart ) && baseEnd .After (interEnd ):
@@ -132,8 +137,12 @@ func Without(a, b Span) Spans {
132137 residues = append (residues , baseSpanPart )
133138
134139 case baseStart .Equal (interStart ) && baseEnd .Equal (interEnd ):
140+ // if basespan and intersection match, return empty Spans
135141 break
136142
143+ case ! interStart .After (baseStart ) && ! interEnd .Before (baseEnd ):
144+ // if intersection engulfs the basespan, return empty Spans
145+ break
137146 default :
138147 residues = append (residues , a )
139148 }
@@ -148,74 +157,18 @@ func WithoutWithHandler(a, b Span, handlerFunc WithoutHandlerFunc) Spans {
148157 return handlerFunc (a , b , s )
149158}
150159
151- // Within returns if b is completly in a
160+ // Within returns if b is completely in a
152161// Same instants of start or end are considered within.
153162func Within (a , b Span ) bool {
154163 return ((a .Start ().Before (b .Start ())) || a .Start ().Equal (b .Start ())) &&
155164 ((a .End ().After (b .End ())) || a .End ().Equal (b .End ()))
156165}
157166
158- // Returns true if two spans are side by side
159- func contiguous (a , b Span ) bool {
160- return a .End ().Equal (b .Start ()) || b .End ().Equal (a .Start ())
161- }
162-
163167// Returns true if two spans overlap
164168func overlap (a , b Span ) bool {
165169 return a .Start ().Before (b .End ()) && b .Start ().Before (a .End ())
166170}
167171
168- // // UnionWithHandler returns a list of Spans representing the union of all of the spans.
169- // // For example, given a list [A,B] where A and B overlap, a list [C] would be returned, with the span C spanning
170- // // both A and B. The provided handler is passed the source and destination spans, and the currently merged empty span.
171- // func (s Spans) UnionWithHandler(unionHandlerFunc UnionHandlerFunc) Spans {
172- //
173- // if len(s) < 2 {
174- // return s
175- // }
176- //
177- // var sorted Spans
178- // sorted = append(sorted, s...)
179- // sort.Stable(ByStart(sorted))
180- //
181- // result := Spans{sorted[0]}
182- //
183- // for _, b := range sorted[1:] {
184- // // A: current span in merged array; B: current span in sorted array
185- // // If B overlaps with A, it can be merged with A.
186- // a := result[len(result)-1]
187- // if overlap(a, b) || contiguous(a, b) {
188- //
189- // spanStart := getMin(EndPoint{a.Start(), a.StartType()}, EndPoint{b.Start(), b.StartType()})
190- // spanEnd := getMax(EndPoint{a.End(), a.EndType()}, EndPoint{b.End(), b.EndType()})
191- //
192- // if a.Start().Equal(b.Start()) {
193- // spanStart.Type = getLoosestIntervalType(a.StartType(), b.StartType())
194- // }
195- // if a.End().Equal(b.End()) {
196- // spanEnd.Type = getLoosestIntervalType(a.EndType(), b.EndType())
197- // }
198- //
199- // span := NewWithTypes(spanStart.Element, spanEnd.Element, spanStart.Type, spanEnd.Type)
200- // result[len(result)-1] = unionHandlerFunc(a, b, span)
201- //
202- // continue
203- // }
204- // result = append(result, b)
205- // }
206- //
207- // return result
208- // }
209- //
210- // // Union returns a list of Spans representing the union of all of the spans.
211- // // For example, given a list [A,B] where A and B overlap, a list [C] would be returned, with the span C spanning
212- // // both A and B.
213- // func (s Spans) Union() Spans {
214- // return s.UnionWithHandler(func(mergeInto, mergeFrom, mergeSpan Span) Span {
215- // return mergeSpan
216- // })
217- // }
218-
219172// IntersectionWithHandler returns a list of Spans representing the overlaps between the contained spans.
220173// For example, given a list [A,B] where A and B overlap, a list [C] would be returned, with the span C covering
221174// the intersection of the A and B. The provided handler function is notified of the two spans that have been found
@@ -291,8 +244,9 @@ func (s Spans) IntersectionBetween(b Spans) Spans {
291244 })
292245}
293246
247+ //Without removes the given Span from the Spans
294248func (s Spans ) Without (b Span ) Spans {
295- var o Spans
249+ var o = Spans {}
296250 for _ , a := range s {
297251 o = append (o , Without (a , b )... )
298252 }
@@ -309,6 +263,7 @@ func (s Spans) WithoutWithHandler(b Span, handlerFunc WithoutHandlerFunc) Spans
309263 return o
310264}
311265
266+ //Duration sums up the duration of all given Spans
312267func (s Spans ) Duration () time.Duration {
313268 var d time.Duration
314269
0 commit comments