diff --git a/spec/drupol/phptree/Node/TrieNodeSpec.php b/spec/drupol/phptree/Node/TrieNodeSpec.php new file mode 100644 index 0000000..632b10c --- /dev/null +++ b/spec/drupol/phptree/Node/TrieNodeSpec.php @@ -0,0 +1,42 @@ +shouldHaveType(TrieNode::class); + } + + public function it_can_add_node() + { + $this->beConstructedWith('root', 'root'); + + $nodes = [ + 'ab', + 'abc', + 'abcd', + 'abcde', + 'cb', + 'cba', + 'dcba', + 'edcba', + ]; + + foreach ($nodes as $key => $value) { + $nodes[$key] = new KeyValueNode($key, $value); + } + + $this + ->add(...$nodes) + ->count() + ->shouldReturn(25); + } +} diff --git a/src/Exporter/Graph.php b/src/Exporter/Graph.php index c4dd65e..97f2920 100644 --- a/src/Exporter/Graph.php +++ b/src/Exporter/Graph.php @@ -59,13 +59,7 @@ public function getTraverser(): TraverserInterface } /** - * Export a node into a Graph. - * - * @param \drupol\phptree\Node\ValueNodeInterface $node - * The node. - * - * @return \Fhaculty\Graph\Graph - * The graph. + * {@inheritdoc} */ public function export(ValueNodeInterface $node): OriginalGraph { diff --git a/src/Exporter/Text.php b/src/Exporter/Text.php index 2c9d514..1c5887e 100644 --- a/src/Exporter/Text.php +++ b/src/Exporter/Text.php @@ -12,13 +12,7 @@ class Text implements ExporterInterface { /** - * Export the node in a string. - * - * @param \drupol\phptree\Node\ValueNodeInterface $node - * The node. - * - * @return string - * The string. + * {@inheritdoc} */ public function export(ValueNodeInterface $node): string { diff --git a/src/Node/TrieNode.php b/src/Node/TrieNode.php new file mode 100644 index 0000000..1f2586b --- /dev/null +++ b/src/Node/TrieNode.php @@ -0,0 +1,60 @@ +getValue(); + + $hash = \hash('sha256', $node->getKey() . $data); + + $node = new TrieNode($hash, \substr($data, 0, 1)); + $parent = $this->append($node); + + $dataWithoutFirstLetter = \substr($data, 1); + if (!empty($dataWithoutFirstLetter)) { + $parent->add(new TrieNode($hash, $dataWithoutFirstLetter)); + } else { + $nodes = [$node->getValue()]; + foreach ($node->getAncestors() as $ancestor) { + $nodes[] = $ancestor->getValue(); + } + \array_pop($nodes); + $node->append(new TrieNode($hash, \strrev(\implode('', $nodes)))); + } + } + + return $this; + } + + /** + * @param \drupol\phptree\Node\ValueNodeInterface $node + * + * @return \drupol\phptree\Node\NodeInterface|\drupol\phptree\Node\ValueNodeInterface + */ + private function append(ValueNodeInterface $node) + { + /** @var \drupol\phptree\Node\ValueNodeInterface $child */ + foreach ($this->children() as $child) { + /** @var \drupol\phptree\Node\ValueNodeInterface $node */ + if ($node->getValue() === $child->getValue()) { + return $child; + } + } + + parent::add($node); + + return $node; + } +} diff --git a/tests/src/Exporter/KeyValueGraph.php b/tests/src/Exporter/KeyValueGraph.php new file mode 100644 index 0000000..c80cd95 --- /dev/null +++ b/tests/src/Exporter/KeyValueGraph.php @@ -0,0 +1,40 @@ +setAttribute('graphviz.label', $node->getValue()); + } + + return $vertex; + } + + /** + * {@inheritdoc} + */ + protected function createVertexId(NodeInterface $node) + { + if (\method_exists($node, 'getValue') && \method_exists($node, 'getKey')) { + return $node->getKey() . $node->getValue(); + } + + return \sha1((string) parent::createVertexId($node)); + } +}