Skip to content

Commit f5aab21

Browse files
committed
Hashes may not be ordered at the time of getting ranges or merging.
1 parent 121af8f commit f5aab21

File tree

1 file changed

+23
-26
lines changed

1 file changed

+23
-26
lines changed

src/SoundFingerprinting/Data/Hashes.cs

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)