@@ -14,8 +14,7 @@ public class Hashes : IEnumerable<HashedFingerprint>
1414 private readonly List < HashedFingerprint > fingerprints ;
1515
1616 [ ProtoIgnore ]
17- private List < HashedFingerprint > Fingerprints =>
18- fingerprints ?? Enumerable . Empty < HashedFingerprint > ( ) . ToList ( ) ;
17+ private List < HashedFingerprint > Fingerprints => fingerprints ?? Enumerable . Empty < HashedFingerprint > ( ) . ToList ( ) ;
1918
2019 public Hashes ( IEnumerable < HashedFingerprint > fingerprints , double durationInSeconds ) :
2120 this ( fingerprints ,
@@ -93,19 +92,6 @@ public DateTime EndsAt
9392 }
9493 }
9594
96- private float LengthOfOneFingerprint
97- {
98- get
99- {
100- if ( IsEmpty )
101- {
102- return 0 ;
103- }
104-
105- return ( float ) DurationInSeconds - Fingerprints . Last ( ) . StartsAt ;
106- }
107- }
108-
10995 public bool IsEmpty => ! Fingerprints . Any ( ) ;
11096
11197 public int Count => IsEmpty ? 0 : Fingerprints . Count ;
@@ -134,11 +120,19 @@ IEnumerator IEnumerable.GetEnumerator()
134120
135121 public Hashes GetRange ( DateTime startsAt , float length )
136122 {
123+ if ( IsEmpty )
124+ {
125+ return Empty ;
126+ }
127+
137128 var endsAt = startsAt . AddSeconds ( length ) ;
138- var filtered = fingerprints . Where ( fingerprint =>
129+ var ordered = fingerprints . OrderBy ( _ => _ . SequenceNumber ) . ToList ( ) ;
130+ var lengthOfOneFingerprint = DurationInSeconds - ordered . Last ( ) . StartsAt ;
131+
132+ var filtered = ordered . Where ( fingerprint =>
139133 {
140134 var fingerprintStartsAt = RelativeTo . AddSeconds ( fingerprint . StartsAt ) ;
141- var fingerprintEndsAt = RelativeTo . AddSeconds ( fingerprint . StartsAt + LengthOfOneFingerprint ) ;
135+ var fingerprintEndsAt = RelativeTo . AddSeconds ( fingerprint . StartsAt + lengthOfOneFingerprint ) ;
142136 return fingerprintStartsAt >= startsAt && fingerprintEndsAt <= endsAt ;
143137 } )
144138 . ToList ( ) ;
@@ -149,7 +143,7 @@ public Hashes GetRange(DateTime startsAt, float length)
149143 }
150144
151145 var relativeTo = RelativeTo . AddSeconds ( filtered . First ( ) . StartsAt ) ;
152- var duration = filtered . Last ( ) . StartsAt - filtered . First ( ) . StartsAt + LengthOfOneFingerprint ;
146+ var duration = filtered . Last ( ) . StartsAt - filtered . First ( ) . StartsAt + lengthOfOneFingerprint ;
153147 return new Hashes ( filtered , duration , relativeTo , Origins , StreamId ) ;
154148 }
155149
@@ -183,10 +177,7 @@ public bool MergeWith(Hashes with, out Hashes? merged, double allowedGap = 1.48f
183177 return false ;
184178 }
185179
186- var result = Merge ( this , with ) ;
187- float fullLength = result . Last ( ) . StartsAt + LengthOfOneFingerprint ;
188- var relativeTo = RelativeTo < with . RelativeTo ? RelativeTo : with . RelativeTo ;
189- merged = new Hashes ( result , fullLength , relativeTo , new HashSet < string > ( Origins . Concat ( with . Origins ) ) , streamId ) ;
180+ merged = Merge ( this , with , streamId ) ;
190181 return true ;
191182 }
192183
@@ -230,29 +221,33 @@ public static IEnumerable<Hashes> Aggregate(IEnumerable<Hashes> hashes, double l
230221 } ) ;
231222 }
232223
233- private static List < HashedFingerprint > Merge ( Hashes left , Hashes right )
224+ private static Hashes Merge ( Hashes left , Hashes right , string streamId )
234225 {
235226 var first = left . OrderBy ( _ => _ . SequenceNumber ) . ToList ( ) ;
227+ double lengthOfLeftFingerprint = left . DurationInSeconds - first . Last ( ) . StartsAt ;
236228 var firstStartsAt = left . RelativeTo ;
237229 var second = right . OrderBy ( _ => _ . SequenceNumber ) . ToList ( ) ;
230+ double lengthOfRightFingerprint = right . DurationInSeconds - second . Last ( ) . StartsAt ;
238231 var secondStartsAt = right . RelativeTo ;
239232
240233 var result = new List < HashedFingerprint > ( ) ;
241234 int i = 0 , j = 0 ;
242235 var diff = secondStartsAt . Subtract ( firstStartsAt ) ;
243-
236+ double tailLength = 0 ;
244237 for ( int k = 0 ; k < first . Count + second . Count ; ++ k )
245238 {
246239 if ( i == first . Count )
247240 {
248241 var startAt = diff . TotalSeconds + second [ j ] . StartsAt ;
249242 result . Add ( new HashedFingerprint ( second [ j ] . HashBins , ( uint ) k , ( float ) startAt , second [ j ] . OriginalPoint ) ) ;
250243 ++ j ;
244+ tailLength = lengthOfRightFingerprint ;
251245 }
252246 else if ( j == second . Count )
253247 {
254248 result . Add ( new HashedFingerprint ( first [ i ] . HashBins , ( uint ) k , first [ i ] . StartsAt , first [ i ] . OriginalPoint ) ) ;
255249 ++ i ;
250+ tailLength = lengthOfLeftFingerprint ;
256251 }
257252 else if ( firstStartsAt . AddSeconds ( first [ i ] . StartsAt ) <= secondStartsAt . AddSeconds ( second [ j ] . StartsAt ) )
258253 {
@@ -266,8 +261,10 @@ private static List<HashedFingerprint> Merge(Hashes left, Hashes right)
266261 ++ j ;
267262 }
268263 }
269-
270- return result ;
264+
265+ var relativeTo = left . RelativeTo < right . RelativeTo ? left . RelativeTo : right . RelativeTo ;
266+ var fullLength = result . Last ( ) . StartsAt + tailLength ;
267+ return new Hashes ( result , fullLength , relativeTo , new HashSet < string > ( left . Origins . Concat ( right . Origins ) ) , streamId ) ;
271268 }
272269 }
273270}
0 commit comments