Skip to content

Commit 6d57146

Browse files
authored
Merge pull request #1 from paulgibert/fast-paulgibert
Created a document cache decorator and handled Relationships as tuple…
2 parents 30ebcf3 + d1dbc27 commit 6d57146

File tree

5 files changed

+34
-14
lines changed

5 files changed

+34
-14
lines changed

src/spdx_tools/common/typing/dataclass_with_properties.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# SPDX-FileCopyrightText: 2022 spdx contributors
22
#
33
# SPDX-License-Identifier: Apache-2.0
4-
from dataclasses import dataclass
4+
from dataclasses import dataclass, astuple
55

66
from beartype import beartype
77
from beartype.roar import BeartypeCallHintException
88

99

10+
def freeze_dataclass_with_properties_list(items):
11+
return {astuple(itm) for itm in items}
12+
13+
1014
def dataclass_with_properties(cls):
1115
"""Decorator to generate a dataclass with properties out of the class' value:type list.
1216
Their getters and setters will be subjected to the @typechecked decorator to ensure type conformity."""

src/spdx_tools/spdx/model/document.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: 2022 spdx contributors
22
#
33
# SPDX-License-Identifier: Apache-2.0
4-
from dataclasses import field
4+
from dataclasses import field, astuple
55
from datetime import datetime
66

77
from beartype.typing import List, Optional
@@ -82,5 +82,17 @@ def __init__(
8282
extracted_licensing_info = [] if extracted_licensing_info is None else extracted_licensing_info
8383
check_types_and_set_values(self, locals())
8484

85-
def __hash__(self):
86-
return id(self)
85+
86+
def document_cache(func):
87+
cache = {}
88+
89+
def cached_function(document: Document):
90+
key = id(document)
91+
if key in cache.keys():
92+
return cache[key]
93+
else:
94+
value = func(document)
95+
cache[key] = value
96+
return value
97+
98+
return cached_function

src/spdx_tools/spdx/model/relationship.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,3 @@ def __init__(
7373
comment: Optional[str] = None,
7474
):
7575
check_types_and_set_values(self, locals())
76-
77-
def __hash__(self):
78-
return hash("{} -> {} ({})".format(self.spdx_element_id, str(self.related_spdx_element_id), str(self.relationship_type)))

src/spdx_tools/spdx/parser/jsonlikedict/relationship_parser.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# SPDX-FileCopyrightText: 2022 spdx contributors
22
#
33
# SPDX-License-Identifier: Apache-2.0
4+
from dataclasses import astuple
5+
46
from beartype.typing import Dict, List, Optional, Set
57

68
from spdx_tools.common.typing.constructor_type_errors import ConstructorTypeErrors
9+
from spdx_tools.common.typing.dataclass_with_properties import freeze_dataclass_with_properties_list
710
from spdx_tools.spdx.model import Relationship, RelationshipType
811
from spdx_tools.spdx.parser.error import SPDXParsingError
912
from spdx_tools.spdx.parser.jsonlikedict.dict_parsing_functions import (
@@ -35,9 +38,12 @@ def parse_all_relationships(self, input_doc_dict: Dict) -> List[Relationship]:
3538
document_describes: List[str] = delete_duplicates_from_list(input_doc_dict.get("documentDescribes", []))
3639
doc_spdx_id: Optional[str] = input_doc_dict.get("SPDXID")
3740

38-
existing_relationships_without_comments: Set[Relationship] = set(self.get_all_relationships_without_comments(
39-
relationships
40-
))
41+
relationship_hash = lambda r: hash("{} -> {} ({})" \
42+
.format(r.spdx_element_id,
43+
str(r.related_spdx_element_id),
44+
str(r.relationship_type)))
45+
existing_relationships_without_comments: Set[Relationship] = freeze_dataclass_with_properties_list(
46+
self.get_all_relationships_without_comments(relationships))
4147
relationships.extend(
4248
parse_field_or_log_error(
4349
self.logger,
@@ -161,10 +167,10 @@ def check_if_relationship_exists(
161167
self, relationship: Relationship, existing_relationships: Set[Relationship]
162168
) -> bool:
163169
# assume existing relationships are stripped of comments
164-
if relationship in existing_relationships:
170+
if astuple(relationship) in existing_relationships:
165171
return True
166172
relationship_inverted: Relationship = self.invert_relationship(relationship)
167-
if relationship_inverted in existing_relationships:
173+
if astuple(relationship_inverted) in existing_relationships:
168174
return True
169175

170176
return False

src/spdx_tools/spdx/validation/spdx_id_validators.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from spdx_tools.spdx.document_utils import get_contained_spdx_element_ids
1212
from spdx_tools.spdx.model import Document, File
13+
from spdx_tools.spdx.model.document import document_cache
1314

1415

1516
def is_valid_internal_spdx_id(spdx_id: str) -> bool:
@@ -24,13 +25,13 @@ def is_spdx_id_present_in_files(spdx_id: str, files: List[File]) -> bool:
2425
return spdx_id in [file.spdx_id for file in files]
2526

2627

27-
@cache
28+
# @cache
2829
def is_spdx_id_present_in_document(spdx_id: str, document: Document) -> bool:
2930
all_spdx_ids_in_document: Set[str] = get_set_of_all_spdx_ids(document)
3031

3132
return spdx_id in all_spdx_ids_in_document
3233

33-
@cache
34+
@document_cache
3435
def get_set_of_all_spdx_ids(document: Document) -> Set[str]:
3536
return set(get_list_of_all_spdx_ids(document))
3637

0 commit comments

Comments
 (0)