/// <summary> /// Insert hash into the RAM Storage. Be careful, there should be a Track object already inserted into the Storage. /// </summary> /// <param name = "hash">Hash signature that corresponds to a specific track</param> public void InsertHash(HashSignature hash) { fingerprints[hash.Track].Add(hash); long[] signature = hash.Signature; /*Lock insertion in the hash-tables as it keys are verified*/ lock (hashTables.SyncRoot) { for (int i = 0; i < numberOfHashTables; i++) { if (!hashTables[i].ContainsKey(signature[i])) { hashTables[i][signature[i]] = new HashSet<Track>(); } hashTables[i][signature[i]].Add(hash.Track); } } }
private IEnumerable<HashSignature> GetSignatures(IEnumerable<bool[]> fingerprints, Track track, int hashTables, int hashKeys) { List<HashSignature> signatures = new List<HashSignature>(); foreach (bool[] fingerprint in fingerprints) { long[] buckets = combinedHashingAlgorithm.Hash(fingerprint, hashTables, hashKeys).Item2; long[] hashSignature = new long[buckets.Length]; int tableCount = 0; foreach (long bucket in buckets) { hashSignature[tableCount++] = bucket; } HashSignature hash = new HashSignature(track, hashSignature); /*associate track to hash-signature*/ signatures.Add(hash); } return signatures; /*Return the signatures*/ }
/// <summary> /// Get tracks that correspond to a specific hash signature and pass the threshold value /// </summary> /// <param name = "hashSignature">Hash signature of the track</param> /// <param name = "hashTableThreshold">Number of threshold tables</param> /// <returns>Possible candidates</returns> public Dictionary<Track, int> GetTracks(HashSignature hashSignature, int hashTableThreshold) { Dictionary<Track, int> result = new Dictionary<Track, int>(); long[] signature = hashSignature.Signature; // loop through all 25 hash tables for (int i = 0; i < numberOfHashTables; i++) { if (hashTables[i].ContainsKey(signature[i])) { HashSet<Track> tracks = hashTables[i][signature[i]]; // get the set of tracks that map to a specific hash signature // select all tracks except the original one foreach (Track track in tracks.Where(t => t.Id != hashSignature.Track.Id)) { if (!result.ContainsKey(track)) { result[track] = 1; } else { result[track]++; } } } } // select only those tracks that passed threshold votes Dictionary<Track, int> filteredResult = result.Where(item => item.Value >= hashTableThreshold).ToDictionary(item => item.Key, item => item.Value); return filteredResult; }