@@ -26,10 +26,6 @@ public function __construct(int $capacity = 0, NodeInterface $parent = null, Tra
26
26
{
27
27
parent ::__construct ($ parent );
28
28
29
- $ capacity = 0 > $ capacity ?
30
- 0 :
31
- $ capacity ;
32
-
33
29
$ this ->storage ()->set (
34
30
'capacity ' ,
35
31
$ capacity
@@ -56,18 +52,10 @@ public function add(NodeInterface ...$nodes): NodeInterface
56
52
continue ;
57
53
}
58
54
59
- foreach ($ this ->getTraverser ()->traverse ($ this ) as $ candidate ) {
60
- if (!($ candidate instanceof NaryNodeInterface)) {
61
- continue ;
62
- }
63
-
64
- if ($ candidate ->degree () >= $ candidate ->capacity ()) {
65
- continue ;
66
- }
67
-
68
- $ candidate ->add ($ node );
69
-
70
- break ;
55
+ if (null !== $ parent = $ this ->findFirstAvailableNode ($ this )) {
56
+ $ parent ->add ($ node );
57
+ } else {
58
+ throw new \Exception ('Unable to add the node to the tree. ' );
71
59
}
72
60
}
73
61
@@ -105,4 +93,39 @@ public function offsetSet($offset, $value)
105
93
parent ::offsetSet ($ offset , $ value );
106
94
}
107
95
}
96
+
97
+ /**
98
+ * Find the first available node in the tree.
99
+ *
100
+ * When adding nodes to a NaryNode based tree, you must traverse the tree
101
+ * and find the first node that can be used as a parent for the node to add.
102
+ *
103
+ * @param \drupol\phptree\Node\NodeInterface $tree
104
+ * The base node.
105
+ *
106
+ * @return null|\drupol\phptree\Node\NodeInterface
107
+ * A node, null if none are found.
108
+ */
109
+ protected function findFirstAvailableNode (NodeInterface $ tree ): ?NodeInterface
110
+ {
111
+ foreach ($ this ->getTraverser ()->traverse ($ tree ) as $ candidate ) {
112
+ if (!($ candidate instanceof NaryNodeInterface)) {
113
+ continue ;
114
+ }
115
+
116
+ $ capacity = $ candidate ->capacity ();
117
+
118
+ if (0 > $ capacity ) {
119
+ continue ;
120
+ }
121
+
122
+ if (0 !== $ capacity && $ candidate ->degree () >= $ capacity ) {
123
+ continue ;
124
+ }
125
+
126
+ return $ candidate ;
127
+ }
128
+
129
+ return null ;
130
+ }
108
131
}
0 commit comments