The ordering change in add_child is critical if $self == $parent
as the {children} hash was lost before this change.
has_descendent can be simplified by walking upwards from the child
instead of downwards from the parent.
This fixes threading regressions introduced in
commit
30100c46326e2eac275e0af13116636701d2537e
("thread: use hash + array instead of hand-rolled linked list")
if $self == $child;
my $cid = $child->{id};
if $self == $child;
my $cid = $child->{id};
- $self->{children}->{$cid} = $child;
# reparenting:
if (defined(my $parent = $child->{parent})) {
delete $parent->{children}->{$cid};
}
# reparenting:
if (defined(my $parent = $child->{parent})) {
delete $parent->{children}->{$cid};
}
+ $self->{children}->{$cid} = $child;
$child->{parent} = $self;
}
sub has_descendent {
$child->{parent} = $self;
}
sub has_descendent {
- my ($cur, $child) = @_;
- my %seen;
- my @q = ($cur->{parent} || $cur);
-
- while (defined($cur = shift @q)) {
- return 1 if $cur == $child;
-
- if (!$seen{$cur}++) {
- push @q, values %{$cur->{children}};
- }
+ my ($self, $child) = @_;
+ while ($child) {
+ return 1 if $self == $child;
+ $child = $child->{parent};