@@ -32,6 +32,7 @@ public static function link(
3232 MovableNodeContract $ node ,
3333 MovableNodeContract $ parent ,
3434 string |int |null $ key = null ,
35+ bool $ preventDuplicateLinking = true ,
3536 ): ?MovableNodeContract {
3637 $ currentParent = $ node ->parent ();
3738
@@ -47,7 +48,7 @@ public static function link(
4748 }
4849
4950 // Create the parent-to-child link.
50- self ::adoptChild ($ parent , $ node , $ key );
51+ self ::adoptChild ($ parent , $ node , $ key, $ preventDuplicateLinking );
5152
5253 // If a parent was unlinked during the process, return it.
5354 return $ originalParent ?? null ;
@@ -163,9 +164,13 @@ public static function reindexTree(
163164 private static function adoptChild (
164165 MovableNodeContract $ parent ,
165166 MovableNodeContract $ child ,
166- string |int |null $ key = null
167+ string |int |null $ key ,
168+ bool $ preventDuplicateLinking ,
167169 ): void {
168- $ existing = $ parent ->childKey ($ child );
170+ // Note:
171+ // The duplicate adding prevention is very slow for nodes with many siblings due to the child node lookup
172+ // (done by the `childKey` method), if not optimized internally.
173+ $ existing = $ preventDuplicateLinking ? $ parent ->childKey ($ child ) : null ;
169174 if (
170175 null !== $ existing &&
171176 $ parent ->child ($ existing ) === $ child &&
0 commit comments