public void CreateFingerprintsInsertThenQueryAndGetTheRightResult() { const int SecondsToProcess = 10; const int StartAtSecond = 30; var tagService = new BassAudioService(); TagInfo info = tagService.GetTagInfo(PathToMp3); TrackData track = new TrackData( info.ISRC, info.Artist, info.Title, info.Album, info.Year, (int)info.Duration); var trackReference = modelService.InsertTrack(track); var hashDatas = fingerprintCommandBuilderWithBass .BuildFingerprintCommand() .From(PathToMp3, SecondsToProcess, StartAtSecond) .WithDefaultFingerprintConfig() .Hash() .Result; modelService.InsertHashDataForTrack(hashDatas, trackReference); var queryResult = queryFingerprintService.Query(hashDatas, new DefaultQueryConfiguration()); Assert.IsTrue(queryResult.IsSuccessful); Assert.AreEqual(1, queryResult.ResultEntries.Count); Assert.AreEqual(trackReference.HashCode, queryResult.ResultEntries[0].Track.TrackReference.HashCode); }
private bool TryQuery(IQueryFingerprintService service, Hashes hashes, out IEnumerable <QueryResult> results) { try { var result = service.Query(hashes, configuration.QueryConfiguration, modelService); if (!downtimeHashes.Any()) { results = new[] { result }.AsEnumerable(); return(true); } results = ConsumeDowntimeHashes(service) .Concat(ConsumeExternalDowntimeHashes(service)) .Concat(new[] { result }); configuration?.RestoredAfterErrorCallback.Invoke(); return(true); } catch (Exception e) { var timedHashes = StoreDowntimeEntries(hashes); InvokeExceptionCallback(e, timedHashes); results = Enumerable.Empty <QueryResult>(); return(false); } }
private IEnumerable <QueryResult> ConsumeDowntimeHashes(IQueryFingerprintService service) { while (downtimeHashes.Any()) { var timedHashes = downtimeHashes.Dequeue(); yield return(service.Query(timedHashes, configuration.QueryConfiguration, modelService)); } }
public QueryResult Query(Hashes queryFingerprints, QueryConfiguration configuration, IModelService modelService) { if (faultyCounts-- > 0) { throw new IOException("I/O exception"); } return goodOne.Query(queryFingerprints, configuration, modelService); }
public QueryResult Query(IEnumerable <HashedFingerprint> queryFingerprints, QueryConfiguration configuration, DateTime relativeTo, IModelService modelService) { if (faultyCounts-- > 0) { throw new IOException("I/O exception"); } return(goodOne.Query(queryFingerprints, configuration, relativeTo, modelService)); }
public Task <QueryResult> Query() { return(createFingerprintMethod() .Hash() .ContinueWith( task => { var hashes = task.Result; return queryFingerprintService.Query(modelService, hashes, QueryConfiguration); }, TaskContinuationOptions.ExecuteSynchronously)); }
private IEnumerable <QueryResult> ConsumeExternalDowntimeHashes(IQueryFingerprintService service) { foreach (var downtimeHash in configuration.DowntimeHashes) { if (downtimeHash.IsEmpty) { continue; } yield return(service.Query(downtimeHash, configuration.QueryConfiguration, modelService)); } }
private IEnumerable <QueryResult> ConsumeDowntimeHashes(IQueryFingerprintService service) { var list = new List <QueryResult>(); while (downtimeHashes.Any()) { var timedHashes = downtimeHashes.Dequeue(); var results = service.Query(timedHashes, configuration.QueryConfiguration, modelService); list.Add(results); } return(list); }
private IEnumerable <QueryResult> ConsumeExternalDowntimeHashes(IQueryFingerprintService service) { var list = new List <QueryResult>(); foreach (var downtimeHash in configuration.DowntimeHashes) { if (downtimeHash.IsEmpty) { continue; } var results = service.Query(downtimeHash, configuration.QueryConfiguration, modelService); list.Add(results); } return(list); }
public Task <QueryResult> Query() { var fingerprintingStopwatch = Stopwatch.StartNew(); Task <QueryResult> resultingTask = createFingerprintMethod() .Hash() .ContinueWith( task => { long fingerprintingTime = fingerprintingStopwatch.ElapsedMilliseconds; var hashes = task.Result; var queryStopwatch = Stopwatch.StartNew(); QueryResult queryResult = queryFingerprintService.Query(hashes, QueryConfiguration, modelService); long queryingTime = queryStopwatch.ElapsedMilliseconds; queryResult.Stats.FingerprintingDuration = fingerprintingTime; queryResult.Stats.QueryDuration = queryingTime; return(queryResult); }, TaskContinuationOptions.ExecuteSynchronously); return(resultingTask); }
public async Task <QueryResult> Query(DateTime relativeTo) { var fingerprintingStopwatch = Stopwatch.StartNew(); var hashes = await createFingerprintCommand().Hash(); long fingerprintingDuration = fingerprintingStopwatch.ElapsedMilliseconds; var queryStopwatch = Stopwatch.StartNew(); var queryResult = queryFingerprintService.Query(hashes, queryConfiguration, relativeTo, modelService); long queryDuration = queryStopwatch.ElapsedMilliseconds; if (queryResult.ContainsMatches) { var queryMatches = queryResult.ResultEntries.ToQueryMatches(); queryMatchRegistry.RegisterMatches(queryMatches, new Dictionary <string, string>()); } return(new QueryResult(queryResult.ResultEntries, new QueryStats(queryResult.Stats.TotalTracksAnalyzed, queryResult.Stats.TotalFingerprintsAnalyzed, queryDuration, fingerprintingDuration))); }
/// <summary> /// Find duplicates between existing tracks in the database /// </summary> /// <param name = "callback">Callback invoked at each processed track</param> /// <returns>Sets of duplicates</returns> public HashSet <TrackData>[] FindDuplicates(Action <TrackData, int, int> callback) { var tracks = modelService.ReadAllTracks(); var duplicates = new List <HashSet <TrackData> >(); int total = tracks.Count, current = 0; var queryConfiguration = new CustomQueryConfiguration { ThresholdVotes = ThresholdVotes, MaximumNumberOfTracksToReturnAsResult = int.MaxValue }; foreach (var track in tracks) { var trackDuplicates = new HashSet <TrackData>(); var hashes = modelService.ReadHashDataByTrack(track.TrackReference); var result = queryFingerprintService.Query(hashes, queryConfiguration); if (result.IsSuccessful) { foreach (var resultEntry in result.ResultEntries) { if (track.Equals(resultEntry.Track)) { continue; } if (MinimumHammingSimilarity > resultEntry.Similarity) { continue; } trackDuplicates.Add(resultEntry.Track); } if (trackDuplicates.Any()) { HashSet <TrackData> duplicatePair = new HashSet <TrackData>(trackDuplicates) { track }; duplicates.Add(duplicatePair); } } if (callback != null) { callback.Invoke(track, total, ++current); } } for (int i = 0; i < duplicates.Count - 1; i++) { HashSet <TrackData> set = duplicates[i]; for (int j = i + 1; j < duplicates.Count; j++) { IEnumerable <TrackData> result = set.Intersect(duplicates[j]); if (result.Any()) { foreach (var track in duplicates[j]) { // collapse all duplicates in one set set.Add(track); } duplicates.RemoveAt(j); /*Remove the duplicate set*/ j--; } } } return(duplicates.ToArray()); }
/// <summary> /// Find duplicates between existing tracks in the database /// </summary> /// <param name = "callback">Callback invoked at each processed track</param> /// <returns>Sets of duplicates</returns> public HashSet <TrackData>[] FindDuplicates(Action <TrackData, int, int> callback) { var tracks = modelService.ReadAllTracks().ToList(); var duplicates = new List <HashSet <TrackData> >(); int total = tracks.Count, current = 0; var queryConfiguration = new DefaultQueryConfiguration { MaxTracksToReturn = int.MaxValue, ThresholdVotes = 4 }; foreach (var track in tracks) { var trackDuplicates = new HashSet <TrackData>(); var hashedFingerprints = modelService.ReadHashedFingerprintsByTrack(track.TrackReference); var max = hashedFingerprints.Max(_ => _.StartsAt); var min = hashedFingerprints.Min(_ => _.StartsAt); var hashes = new Hashes(hashedFingerprints, GetLength(min, max, queryConfiguration.FingerprintConfiguration.FingerprintLengthInSeconds)); var result = queryFingerprintService.Query(hashes, queryConfiguration, modelService); if (result.ContainsMatches) { foreach (var resultEntry in result.ResultEntries) { if (resultEntry.Confidence < FalsePositivesThreshold || track.Equals(resultEntry.Track)) { continue; } trackDuplicates.Add(resultEntry.Track); } if (trackDuplicates.Any()) { HashSet <TrackData> duplicatePair = new HashSet <TrackData>(trackDuplicates) { track }; duplicates.Add(duplicatePair); } } callback?.Invoke(track, total, ++current); } for (int i = 0; i < duplicates.Count - 1; i++) { HashSet <TrackData> set = duplicates[i]; for (int j = i + 1; j < duplicates.Count; j++) { IEnumerable <TrackData> result = set.Intersect(duplicates[j]); if (result.Any()) { foreach (var track in duplicates[j]) { // collapse all duplicates in one set set.Add(track); } duplicates.RemoveAt(j); /*Remove the duplicate set*/ j--; } } } return(duplicates.ToArray()); }
public Task <QueryResult> Query() { return(createFingerprintMethod() .Hash() .ContinueWith(task => queryFingerprintService.Query(task.Result, QueryConfiguration), TaskContinuationOptions.ExecuteSynchronously)); }