Skip to content

Commit f21c02d

Browse files
Fix choking license detection post-processing #3245
We were iterating over license detections, which was taking forever to complete and this approach uses a dict/hashmap instead which fixes the issue here. Reference: #3245 Signed-off-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com> Reported-by: Philippe Ombredanne <pombredanne@nexb.com>
1 parent 6358a4b commit f21c02d

1 file changed

Lines changed: 28 additions & 17 deletions

File tree

src/licensedcode/detection.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
from collections import Counter
1818

1919
import attr
20+
import click
2021
from license_expression import combine_expressions
2122
from license_expression import Licensing
23+
from time import time
2224

2325
from commoncode.resource import clean_path
2426
from commoncode.text import python_safe_name
@@ -595,33 +597,25 @@ def get_unique_detections(cls, license_detections):
595597
Return all unique UniqueDetection from a ``license_detections`` list of
596598
LicenseDetection.
597599
"""
598-
identifiers = get_identifiers(license_detections)
599-
unique_detection_counts = dict(Counter(identifiers))
600-
600+
detections_by_id = get_detections_by_id(license_detections)
601601
unique_license_detections = []
602-
for detection_identifier in unique_detection_counts.keys():
603-
file_regions = (
602+
603+
for all_detections in detections_by_id.values():
604+
file_regions = [
604605
detection.file_region
605-
for detection in license_detections
606-
if detection_identifier == detection.identifier
607-
)
608-
all_detections = (
609-
detection
610-
for detection in license_detections
611-
if detection_identifier == detection.identifier
612-
)
606+
for detection in all_detections
607+
]
613608

614-
detection = next(all_detections)
609+
detection = next(iter(all_detections))
615610
detection_mapping = detection.to_dict()
616-
files = list(file_regions)
617611
unique_license_detections.append(
618612
cls(
619613
identifier=detection.identifier_with_expression,
620614
license_expression=detection_mapping["license_expression"],
621615
detection_log=detection_mapping["detection_log"],
622616
matches=detection_mapping["matches"],
623-
count=len(files),
624-
files=files,
617+
count=len(file_regions),
618+
files=file_regions,
625619
)
626620
)
627621

@@ -638,6 +632,23 @@ def dict_fields(attr, value):
638632
return attr.asdict(self, filter=dict_fields)
639633

640634

635+
def get_detections_by_id(license_detections):
636+
"""
637+
Get a dict(hashmap) where each item is: {detection.identifier: all_detections} where
638+
`all_detections` is all detections in `license_detections` whose detection.identifier
639+
is the same.
640+
"""
641+
detections_by_id = {}
642+
643+
for detection in license_detections:
644+
detection_id = detection.identifier
645+
if detection_id in detections_by_id:
646+
detections_by_id[detection_id].append(detection)
647+
else:
648+
detections_by_id[detection_id] = [detection]
649+
650+
return detections_by_id
651+
641652
def get_identifiers(license_detections):
642653
"""
643654
Return identifiers for all ``license detections``.

0 commit comments

Comments
 (0)