Improve/optimize list generation.

This commit is contained in:
Pol Dellaiera 2021-07-01 09:12:39 +02:00
parent ef6c5870b5
commit b33cb4946c

View File

@ -11,44 +11,38 @@ final class FlatHierarchyEntityHydrator extends ObjectHydrator
{
public const LIST = 'chill_flat_hierarchy_list';
protected function hydrateAllData(): array
protected function hydrateAllData()
{
$generator = $this->buildRecursively(
parent::hydrateAllData(),
static function($value): iterable {
$children = $value->getChildren();
$children->setInitialized(true);
return $children;
}
);
$result = [];
foreach ($generator as $entity) {
// We cannot expect anything from the object entity
// so, we cannot expect it to have a ::getId() method.
// So we use spl_object_hash() instead.
$result += [spl_object_hash($entity) => $entity];
}
return array_values($result);
return array_values(iterator_to_array($this->flatListGenerator($this->buildChildrenHashmap(parent::hydrateAllData()))));
}
/**
* @param iterable<int, SocialIssue> $iterable
* @param callable(SocialIssue): iterable<int, SocialIssue> $childrenAccessor
*
* @return Generator<int, SocialIssue>
*/
private function buildRecursively(iterable $iterable, callable $childrenAccessor): Generator
private function flatListGenerator(array $hashMap, $parent = null): Generator
{
foreach ($iterable as $item)
{
yield $item;
$parent = null === $parent ?
null :
spl_object_hash($parent);
yield from $this->buildRecursively($childrenAccessor($item), $childrenAccessor);
$hashMap += [$parent => []];
foreach ($hashMap[$parent] as $node) {
yield $node->getId() => $node;
yield from $this->flatListGenerator($hashMap, $node);
}
}
private function buildChildrenHashmap(array $nodes): array
{
$r = [];
foreach ($nodes as $node) {
$parentId = (null !== $parent = $node->getParent())
? spl_object_hash($parent)
: null;
$r[$parentId][] = $node;
}
return $r;
}
}