/// <summary> /// Compare two TrustMaps to determine how many of the found values per property matched, /// to incorporate that into trust scoring. /// </summary> /// <param name="otherRunMap">TrustMap for the other Run we're baselining against</param> public void CountMatchesWith(TrustMap otherRunMap) { foreach (TrustKey key in _map.Keys) { int matchCount = 0; TrustValue ourValue = _map[key]; if (otherRunMap._map.TryGetValue(key, out TrustValue theirValue)) { foreach (string value in ourValue.UniqueValues) { if (theirValue.UniqueValues.Contains(value)) { matchCount++; } } theirValue.MatchCount = matchCount; } ourValue.MatchCount = matchCount; } this.WasMatched = true; otherRunMap.WasMatched = true; }
public StatefulResultMatcher(IList <ExtractedResult> before, IList <ExtractedResult> after) { // Sort results by 'Where', then 'RuleId' for matching _before = new List <ExtractedResult>(before); _before.Sort(ResultMatchingComparer.Instance); _beforeTrustMap = new TrustMap(); _beforeWhatMap = new WhatMap(); _matchingIndexFromBefore = new int[_before.Count]; Fill(_matchingIndexFromBefore, -1); _after = new List <ExtractedResult>(after); _after.Sort(ResultMatchingComparer.Instance); _afterTrustMap = new TrustMap(); _afterWhatMap = new WhatMap(); _matchingIndexFromAfter = new int[_after.Count]; Fill(_matchingIndexFromAfter, -1); }
private static void BuildMap(List <ExtractedResult> results, WhatMap whatMap, TrustMap trustMap, HashSet <string> otherRunLocations) { // Populate the WhatMap and TrustMap for (int i = 0; i < results.Count; ++i) { ExtractedResult result = results[i]; // Find the LocationSpecifier for the Result (the first Uri or FQN also in the other Run) string locationSpecifier = WhereComparer.LocationSpecifier(result, otherRunLocations); foreach (WhatComponent component in WhatComparer.WhatProperties(result, locationSpecifier)) { // Add Result attributes used as matching hints in a "bucket" for the Rule x LocationSpecifier x AttributeName whatMap.Add(component, i); // Track attribute usage to determine per-attribute trust trustMap.Add(component); } } }
/// <summary> /// Match the 'What' properties of two ExtractedResults. /// </summary> /// <param name="right">ExtractedResult to match</param> /// <returns>True if *any* 'What' property matches, False otherwise</returns> public static bool MatchesWhat(ExtractedResult left, ExtractedResult right, TrustMap trustMap = null) { if (left?.Result == null || right?.Result == null) { return(false); } // Match Guid if (left.Result.Guid != null) { if (string.Equals(left.Result.Guid, right.Result.Guid)) { return(true); } // Non-Match doesn't force false, as GUIDs are often re-generated by tools. } // Match Fingerprints (any one match is a match) if (left.Result.Fingerprints != null && right.Result.Fingerprints != null) { int correspondingFingerprintCount = 0; foreach (KeyValuePair <string, string> fingerprint in left.Result.Fingerprints) { if (right.Result.Fingerprints.TryGetValue(fingerprint.Key, out string otherFingerprint)) { correspondingFingerprintCount++; if (string.Equals(fingerprint.Value, otherFingerprint)) { return(true); } } } // Force non-match if there were fingerprints but none of them matched if (correspondingFingerprintCount > 0) { return(false); } } // Match PartialFingerprints (50% must match) if (left.Result.PartialFingerprints != null && right.Result.PartialFingerprints != null) { float weightOfComparableValues = 0; float matchWeight = 0; foreach (KeyValuePair <string, string> fingerprint in left.Result.PartialFingerprints) { if (right.Result.PartialFingerprints.TryGetValue(fingerprint.Key, out string otherFingerprint)) { float trust = trustMap?.Trust(PropertySetPartialFingerprint, fingerprint.Key) ?? TrustMap.DefaultTrust; weightOfComparableValues += trust; if (string.Equals(fingerprint.Value, otherFingerprint)) { matchWeight += trust; } } } if (weightOfComparableValues > 0) { // Return whether at least half of the partialFingerprints matched weighted by trust return(matchWeight * 2 >= weightOfComparableValues); } } // At this point, no high confidence properties matched or failed to match string leftMessage = GetCanonicalizedMessage(left); string rightMessage = GetCanonicalizedMessage(right); string leftSnippet = GetFirstSnippet(left); string rightSnippet = GetFirstSnippet(right); return(string.Equals(leftMessage, rightMessage) && string.Equals(leftSnippet, rightSnippet)); }