From 05fd0e18b23d17c03962f004a86194a2add32b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Manuel=20Dom=C3=ADnguez?= <43052541+kysrpex@users.noreply.github.com> Date: Tue, 6 Dec 2022 10:33:48 +0100 Subject: [PATCH] Use BFS in `find` function and variants (#833) A workaround for issue #820 (caching mechanism incompatible with DFS). --- simphony_osp/tools/search.py | 37 +++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/simphony_osp/tools/search.py b/simphony_osp/tools/search.py index a99b4cf4..71cb5f4f 100644 --- a/simphony_osp/tools/search.py +++ b/simphony_osp/tools/search.py @@ -72,7 +72,10 @@ def find( annotation = set() annotation = frozenset(annotation) - result = _iter(criterion, root, rel, annotation, max_depth) + result = iter(()) + if criterion(root): + result = chain(result, (root,)) + result = chain(result, _iter(criterion, root, rel, annotation, max_depth)) if not find_all: result = next(result, None) @@ -110,24 +113,28 @@ def _iter( """ visited = visited or set() visited.add(root.uid) - if criterion(root): - yield root if current_depth < max_depth: - for sub in chain( + # Originally, this function was using DFS (no `list`), but it is + # incompatible with the caching mechanism. See issue #820. + # TODO: Fix + # [issue #820](https://github.com/simphony/simphony-osp/issues/820). + children = chain( *(root.iter(rel=r) for r in rel), *(root.annotations_iter(rel=r) for r in annotation) - ): - if sub.uid not in visited: - yield from _iter( - criterion=criterion, - root=sub, - rel=rel, - annotation=annotation, - max_depth=max_depth, - current_depth=current_depth + 1, - visited=visited, - ) + ) + children = set(child for child in children if child.uid not in visited) + yield from (child for child in children if criterion(child)) + for sub in children: + yield from _iter( + criterion=criterion, + root=sub, + rel=rel, + annotation=annotation, + max_depth=max_depth, + current_depth=current_depth + 1, + visited=visited, + ) def find_by_identifier(