Skip to content

Commit

Permalink
patches
Browse files Browse the repository at this point in the history
  • Loading branch information
dakujem committed Jan 12, 2024
1 parent 05ad3aa commit 9333195
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 24 deletions.
25 changes: 25 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,28 @@ Flexible tree structures, materialized path trees, tree iterators.

This package is a modern reimplementation of `dakujem/oliva-tree`.

```php
use Any\Item;
use Dakujem\Oliva\MaterializedPath\TreeBuilder;
use Dakujem\Oliva\Node;

$data = [
new Item(1, '000'),
new Item(2, '001'),
new Item(3, '003'),
new Item(4, '000000'),
new Item(5, '002000'),
new Item(6, '002'),
];

$builder = new TreeBuilder();
$root = $builder->build(
input: $data,
node: fn(Item $item) => new Node($item),
vector: TreeBuilder::fixed(
3,
fn(Item $item) => $item->path,
),
);

```
4 changes: 2 additions & 2 deletions src/MaterializedPath/Support/Tree.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
class Tree
{
public function __construct(
private TreeNodeContract $root,
private ?TreeNodeContract $root,
private ShadowNode $shadowRoot,
) {
}

/**
* Return the actual tree root.
*/
public function root(): TreeNodeContract
public function root(): ?TreeNodeContract
{
return $this->root;
}
Expand Down
31 changes: 16 additions & 15 deletions src/MaterializedPath/TreeBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Dakujem\Oliva\MaterializedPath\Support\Tree;
use Dakujem\Oliva\TreeNodeContract;
use LogicException;
use RuntimeException;

/**
* Materialized path tree builder. Builds trees from flat data collections.
Expand Down Expand Up @@ -76,7 +77,11 @@ public function build(
callable $node,
callable $vector,
): TreeNodeContract {
return $this->buildTree($input, $node, $vector)->root();
$root = $this->buildTree($input, $node, $vector)->root();
if (null === $root) {
throw new RuntimeException('Corrupted input, no tree created.');
}
return $root;
}

public function buildTree(
Expand Down Expand Up @@ -117,7 +122,7 @@ private function buildShadowTree(
}

// Check for consistency.
if ($node instanceof TreeNodeContract) {
if (!$node instanceof TreeNodeContract) {
// TODO improve exceptions
throw new LogicException('The node factory must return a node instance.');
}
Expand All @@ -135,18 +140,13 @@ private function buildShadowTree(
}
}

// Check for node collisions.
$existingNode = $register->pull($vector);
if ($existingNode->realNode() instanceof TreeNodeContract) {
// TODO improve exceptions
throw new LogicException('Duplicate node vector: ' . implode('.', $vector));
}

$shadow = new ShadowNode($node);

// Finally, connect the node to the tree.
// Make sure all the (shadow) nodes exist all the way to the root.
$this->connectNode($shadow, $vector, $register/*, $key*/);
// Finally, connect the newly created shadow node to the shadow tree.
// Make sure all the shadow nodes exist all the way to the root.
$this->connectNode(
new ShadowNode($node),
$vector,
$register,
);
}

// Pull the shadow root from the register.
Expand All @@ -162,7 +162,7 @@ private function connectNode(ShadowNode $node, array $vector, Register $register

// If the node is already in the registry, replace the real node and return.
if (null !== $existingNode) {
// We first need to check for node collisions.
// Check for node collisions.
if (null !== $node->realNode() && null !== $existingNode->realNode()) {
// TODO improve exceptions
throw new LogicException('Duplicate node vector: ' . implode('.', $vector));
Expand Down Expand Up @@ -194,6 +194,7 @@ private function connectAncestry(ShadowNode $node, array $vector, Register $regi
// Establish parent-child relationship.
$node->setParent($parent);
$parent->addChild($node);
return;
}

// Otherwise create a bridging node, push it to the registry, link them and continue recursively,
Expand Down
21 changes: 14 additions & 7 deletions tests/mptree.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,30 @@ class Item
}

$data = [
new Item(0, ''), // TODO get rid of this
new Item(1, '000'),
new Item(2, '001'),
new Item(3, '003'),
new Item(4, '000000'),
new Item(5, '002000'),
new Item(6, '002'),
// new Item(3, '003'),
// new Item(4, '000000'),
// new Item(5, '002000'),
// new Item(6, '002'),
// new Item(7, '007007007'),
// new Item(8, '008'),
];

$builder = new TreeBuilder();
$root = $builder->build(
$tree = $builder->buildTree(
input: $data,
node: fn(Item $item) => new Node($item),
vector: TreeBuilder::fixed(3, fn(Item $item) => $item->path),
vector: TreeBuilder::fixed(
3,
fn(Item $item) => $item->path,
),
);

xdebug_break();

$item = $root->data();
$item = $tree->root()?->data();


// rekalkulacia / presuny ?
Expand Down

0 comments on commit 9333195

Please sign in to comment.