Skip to content

Commit e701b2f

Browse files
committed
Make DOMChildNode::remove() run in O(1) performance
This method had some useless logic in it. It checked whether the child node is a child of its parent, which is always true of course. But I know where this check comes from, if you follow the spec closely you'll find that the spec used to have explicit child and parent arguments for the removal algorithm [1]. That's because that algorithm is written in a generic way, where the parent and child arguments might not come from the same subtree. However, in this particular case it *is* always the case that the child is a child of its parent. The checks weren't needed back then for DOMChildNode::remove(), and are still not needed today. [1] e.g. https://web.archive.org/web/20180601092634/https://dom.spec.whatwg.org/#concept-node-remove
1 parent efc73f2 commit e701b2f

File tree

2 files changed

+2
-12
lines changed

2 files changed

+2
-12
lines changed

UPGRADING

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ PHP 8.3 UPGRADE NOTES
611611
longer takes quadratic time by default.
612612
. Getting text content from nodes now avoids an allocation, resulting in a
613613
performance gain.
614+
. DOMChildNode::remove() now runs in O(1) performance.
614615

615616
- Standard:
616617
. The file() flags error check is now about 7% faster.

ext/dom/parentnode.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,6 @@ static zend_result dom_child_removal_preconditions(const xmlNodePtr child, int s
527527
void dom_child_node_remove(dom_object *context)
528528
{
529529
xmlNode *child = dom_object_get_node(context);
530-
xmlNodePtr children;
531530
int stricterror;
532531

533532
stricterror = dom_get_strict_error(context->document);
@@ -536,19 +535,9 @@ void dom_child_node_remove(dom_object *context)
536535
return;
537536
}
538537

539-
children = child->parent->children;
540-
541538
php_libxml_invalidate_node_list_cache_from_doc(context->document->ptr);
542539

543-
while (children) {
544-
if (children == child) {
545-
xmlUnlinkNode(child);
546-
return;
547-
}
548-
children = children->next;
549-
}
550-
551-
php_dom_throw_error(NOT_FOUND_ERR, stricterror);
540+
xmlUnlinkNode(child);
552541
}
553542

554543
void dom_child_replace_with(dom_object *context, zval *nodes, uint32_t nodesc)

0 commit comments

Comments
 (0)