Optimization: Use __slots__ in Deckhand engine

This adds __slots__ to object-inherited classes in deckhand.engine
package as a memory optimization [0][1].

Also removes self._parentless_documents from layering module
as it's no longer used by anything.

[0] https://stackoverflow.com/questions/472000/usage-of-slots
[1] http://book.pythontips.com/en/latest/__slots__magic.html

Change-Id: Ifbeaef15f679968d0f45486ffeab75567ca315d7
This commit is contained in:
Felipe Monteiro 2018-03-03 13:33:36 -05:00 committed by Anthony Lin
parent dc69b7c7b2
commit a07635c6a4
3 changed files with 18 additions and 4 deletions

View File

@ -78,6 +78,8 @@ class BaseValidator(object):
validation.
"""
__slots__ = ('_schema_map')
_supported_versions = ('v1',)
_schema_re = re.compile(r'^[a-zA-Z]+\/[a-zA-Z]+\/v\d+$')
@ -103,6 +105,8 @@ class GenericValidator(BaseValidator):
or abstract, or what version its schema is.
"""
__slots__ = ('base_schema')
def __init__(self):
super(GenericValidator, self).__init__()
self.base_schema = self._schema_map['v1']['deckhand/Base']
@ -153,6 +157,8 @@ class GenericValidator(BaseValidator):
class DataSchemaValidator(GenericValidator):
"""Validator for validating ``DataSchema`` documents."""
__slots__ = ('_default_schema_map', '_external_data_schemas')
def _build_schema_map(self, data_schemas):
schema_map = copy.deepcopy(self._default_schema_map)

View File

@ -47,6 +47,10 @@ class DocumentLayering(object):
together into a fully rendered document.
"""
__slots__ = ('_documents_by_index', '_documents_by_labels',
'_documents_by_layer', '_layer_order', '_layering_policy',
'_parents', '_sorted_documents', 'secrets_substitution')
_SUPPORTED_METHODS = (_MERGE_ACTION, _REPLACE_ACTION, _DELETE_ACTION) = (
'merge', 'replace', 'delete')
@ -149,7 +153,6 @@ class DocumentLayering(object):
# Mapping of (doc.name, doc.metadata.name) => children, where children
# are the documents whose `parentSelector` references the doc.
self._parents = {}
self._parentless_documents = []
for layer in self._layer_order:
documents_in_layer = self._documents_by_layer.get(layer, [])
@ -179,7 +182,6 @@ class DocumentLayering(object):
'Could not find parent for document with name=%s, '
'schema=%s, layer=%s, parentSelector=%s.', doc.name,
doc.schema, doc.layer, doc.parent_selector)
self._parentless_documents.append(doc)
# If the document is a child document of more than 1 parent, then
# the document has too many parents, which is a validation error.
elif all_children[doc] > 1:
@ -356,9 +358,9 @@ class DocumentLayering(object):
self._layer_order = self._get_layering_order(self._layering_policy)
self._calc_all_document_children()
self._substitution_sources = substitution_sources or []
self.secrets_substitution = secrets_manager.SecretsSubstitution(
self._substitution_sources,
substitution_sources or [],
fail_on_missing_sub_src=fail_on_missing_sub_src)
self._sorted_documents = self._topologically_sort_documents(documents)
@ -499,3 +501,7 @@ class DocumentLayering(object):
# Return only concrete documents.
return [d for d in self._sorted_documents if d.is_abstract is False]
@property
def documents(self):
return self._sorted_documents

View File

@ -114,6 +114,8 @@ class SecretsManager(object):
class SecretsSubstitution(object):
"""Class for document substitution logic for YAML files."""
__slots__ = ('_fail_on_missing_sub_src', '_substitution_sources')
@staticmethod
def sanitize_potential_secrets(error, document):
"""Sanitize all secret data that may have been substituted into the