Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
 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);
            }
Beispiel #5
0
            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));
 }
Beispiel #7
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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());
        }
Beispiel #13
0
        /// <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());
        }
Beispiel #14
0
 public Task <QueryResult> Query()
 {
     return(createFingerprintMethod()
            .Hash()
            .ContinueWith(task => queryFingerprintService.Query(task.Result, QueryConfiguration), TaskContinuationOptions.ExecuteSynchronously));
 }