public void CalculateHammingSimilarityCorrect()
        {
            byte[] first  = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            byte[] second = new byte[] { 1, 2, 3, 8, 5, 9, 7, 8, 11, 13 };

            var result = SimilarityUtility.CalculateHammingSimilarity(first, second);

            Assert.AreEqual(6, result);
        }
        public QueryResult Query(IModelService modelService, IEnumerable <HashData> hashes, IQueryConfiguration queryConfiguration)
        {
            var hammingSimilarities = new Dictionary <IModelReference, int>();

            foreach (var hash in hashes)
            {
                var subFingerprints = GetSubFingerprints(modelService, hash, queryConfiguration);
                foreach (var subFingerprint in subFingerprints)
                {
                    int similarity = SimilarityUtility.CalculateHammingSimilarity(hash.SubFingerprint, subFingerprint.Signature);
                    if (hammingSimilarities.ContainsKey(subFingerprint.TrackReference))
                    {
                        hammingSimilarities[subFingerprint.TrackReference] += similarity;
                    }
                    else
                    {
                        hammingSimilarities.Add(subFingerprint.TrackReference, similarity);
                    }
                }
            }

            if (hammingSimilarities.Any())
            {
                var topMatches = hammingSimilarities.OrderByDescending(pair => pair.Value).Take(queryConfiguration.MaximumNumberOfTracksToReturnAsResult);
                var resultSet  = topMatches.Select(match => new ResultEntry {
                    Track = modelService.ReadTrackByReference(match.Key), Similarity = match.Value
                }).ToList();

                return(new QueryResult
                {
                    ResultEntries = resultSet,
                    IsSuccessful = true,
                    AnalyzedCandidatesCount = hammingSimilarities.Count
                });
            }

            return(new QueryResult
            {
                ResultEntries = Enumerable.Empty <ResultEntry>().ToList(),
                IsSuccessful = false,
                AnalyzedCandidatesCount = 0
            });
        }