Changeset View
Changeset View
Standalone View
Standalone View
swh/model/merkle.py
# Copyright (C) 2017 The Software Heritage developers | # Copyright (C) 2017-2020 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
"""Merkle tree data structure""" | """Merkle tree data structure""" | ||||
import abc | import abc | ||||
import collections | import collections | ||||
from typing import Iterator, List, Optional, Set | from typing import Iterator, List, Set | ||||
def deep_update(left, right): | def deep_update(left, right): | ||||
"""Recursively update the left mapping with deeply nested values from the right | """Recursively update the left mapping with deeply nested values from the right | ||||
mapping. | mapping. | ||||
This function is useful to merge the results of several calls to | This function is useful to merge the results of several calls to | ||||
:func:`MerkleNode.collect`. | :func:`MerkleNode.collect`. | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | class MerkleNode(dict, metaclass=abc.ABCMeta): | ||||
Attributes: | Attributes: | ||||
data (dict): data associated to the current node | data (dict): data associated to the current node | ||||
parents (list): known parents of the current node | parents (list): known parents of the current node | ||||
collected (bool): whether the current node has been collected | collected (bool): whether the current node has been collected | ||||
""" | """ | ||||
__slots__ = ["parents", "data", "__hash", "collected"] | __slots__ = ["parents", "data", "__hash", "collected"] | ||||
type = None # type: Optional[str] # TODO: make this an enum | |||||
"""Type of the current node (used as a classifier for :func:`collect`)""" | """Type of the current node (used as a classifier for :func:`collect`)""" | ||||
anlambert: Maybe you should type this as `Final` like in `swh.model.model` and set some generic… | |||||
Done Inline ActionsI'll try, I did not in the first place as my understanding of the Final would not work here (base class, etc...). I left it because I did not really understand it but why not ;) ardumont: I'll try, I did not in the first place as my understanding of the Final would not work here… | |||||
Not Done Inline Actions
Oh right, this declare the attribute read only. Maybe remove it from the abstract base class then ? anlambert: > I'll try, I did not in the first place as my understanding of the Final would not work here… | |||||
Done Inline Actions
it being the todo ;)
i'll try, i'm not so sure mypy will be happy around the lines below then though. ardumont: > I left it because I did not really understand it but why not ;)
it being the todo ;)
> Oh… | |||||
def __init__(self, data=None): | def __init__(self, data=None): | ||||
super().__init__() | super().__init__() | ||||
self.parents = [] | self.parents = [] | ||||
self.data = data | self.data = data | ||||
self.__hash = None | self.__hash = None | ||||
self.collected = False | self.collected = False | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | def collect_node(self, **kwargs): | ||||
Arguments: | Arguments: | ||||
kwargs: passed as-is to :func:`get_data`. | kwargs: passed as-is to :func:`get_data`. | ||||
Returns: | Returns: | ||||
A :class:`dict` compatible with :func:`collect`. | A :class:`dict` compatible with :func:`collect`. | ||||
""" | """ | ||||
if not self.collected: | if not self.collected: | ||||
self.collected = True | self.collected = True | ||||
return {self.type: {self.hash: self.get_data(**kwargs)}} | return {self.object_type: {self.hash: self.get_data(**kwargs)}} | ||||
else: | else: | ||||
return {} | return {} | ||||
def collect(self, **kwargs): | def collect(self, **kwargs): | ||||
"""Collect the data for all nodes in the subtree rooted at `self`. | """Collect the data for all nodes in the subtree rooted at `self`. | ||||
The data is deduplicated by type and by hash. | The data is deduplicated by type and by hash. | ||||
▲ Show 20 Lines • Show All 68 Lines • Show Last 20 Lines |
Maybe you should type this as Final like in swh.model.model and set some generic object_type value for base merkle model classes ("merkle_node", "merkle_leaf" ?)
Also, maybe the TODO could be removed ?