MCPcopy Create free account
hub / github.com/aboutcode-org/scancode-toolkit / merge_matches

Function merge_matches

src/licensedcode/match.py:869–1068  ·  view source on GitHub ↗

Return a list of merged LicenseMatch matches given a `matches` list of LicenseMatch. Merging is a "lossless" operation that combines two or more matches to the same rule and that are in sequence of increasing query and index positions in a single new match.

(matches, max_dist=None, trace=TRACE_MERGE)

Source from the content-addressed store, hash-verified

867
868
869def merge_matches(matches, max_dist=None, trace=TRACE_MERGE):
870 """
871 Return a list of merged LicenseMatch matches given a `matches` list of
872 LicenseMatch. Merging is a "lossless" operation that combines two or more
873 matches to the same rule and that are in sequence of increasing query and
874 index positions in a single new match.
875 """
876 # shortcut for single matches
877 if len(matches) < 2:
878 return matches
879
880 # only merge matches with the same rule: sort then group by rule for the
881 # same rule, sort on start, longer high, longer match, matcher type
882 sorter = lambda m: (m.rule.identifier, m.qspan.start, -m.hilen(), -m.len(), m.matcher_order)
883 matches.sort(key=sorter)
884 matches_by_rule = [
885 (rid, list(rule_matches))
886 for rid, rule_matches
887 in groupby(matches, key=lambda m: m.rule.identifier)
888 ]
889
890 if trace:
891 print('merge_matches: number of matches to process:', len(matches))
892
893 if max_dist is None:
894 max_dist = MAX_DIST
895
896 merged = []
897 merged_extend = merged.extend
898
899 for rid, rule_matches in matches_by_rule:
900 if trace:
901 logger_debug('merge_matches: processing rule:', rid)
902
903 rule_length = rule_matches[0].rule.length
904
905 # FIXME this is likely too much as we are getting gaps that are often too big
906 max_rule_side_dist = min((rule_length // 2) or 1, max_dist)
907
908 # compare two matches in the sorted sequence: current and next
909 i = 0
910 while i < len(rule_matches) - 1:
911 j = i + 1
912 while j < len(rule_matches):
913 current_match = rule_matches[i]
914 next_match = rule_matches[j]
915
916 if trace:
917 logger_debug('---> merge_matches: current:', current_match)
918 logger_debug('---> merge_matches: next: ', next_match)
919
920 # FIXME: also considers the match length!
921 # stop if we exceed max dist
922 # or distance over 1/2 of rule length
923 if (current_match.qdistance_to(next_match) > max_rule_side_dist
924 or current_match.idistance_to(next_match) > max_rule_side_dist):
925
926 if trace:

Calls 13

hilenMethod · 0.80
qdistance_toMethod · 0.80
idistance_toMethod · 0.80
magnitudeMethod · 0.80
qcontainsMethod · 0.80
combineMethod · 0.80
logger_debugFunction · 0.70
lenMethod · 0.45
sortMethod · 0.45
overlapMethod · 0.45
surroundMethod · 0.45
updateMethod · 0.45