mirror of https://github.com/schoebel/mars
marsadm: fix recursion depth of _get_common_ancestor()
This commit is contained in:
parent
0d5349b2ca
commit
1715b4fd40
|
@ -581,46 +581,49 @@ sub _get_prev_pos {
|
|||
}
|
||||
|
||||
sub _get_common_ancestor {
|
||||
# TODO: recursive formulation, improve efficiency
|
||||
my ($basedir, $pos1, $host1, $dep1, $pos2, $host2, $dep2) = @_;
|
||||
my ($p1, $nr1, $from1, $len1) = _parse_pos($pos1, 0);
|
||||
my ($p2, $nr2, $from2, $len2) = _parse_pos($pos2, 0);
|
||||
if ($p1 eq $p2) {
|
||||
# usually no split brain here (only if both path depths are non-zero)
|
||||
my $split = ($dep1 && $dep2);
|
||||
if (!$split) { # additionally check the corresponding version links
|
||||
my $path1 = sprintf("$basedir/version-%09d-$from1", $nr1);
|
||||
my $path2 = sprintf("$basedir/version-%09d-$from2", $nr2);
|
||||
if (my $vers1 = get_link($path1) and my $vers2 = get_link($path2)) {
|
||||
$split = 1 if $vers1 ne $vers2;
|
||||
for (;;) {
|
||||
my ($basedir, $pos1, $host1, $dep1, $pos2, $host2, $dep2) = @_;
|
||||
my ($p1, $nr1, $from1, $len1) = _parse_pos($pos1, 0);
|
||||
my ($p2, $nr2, $from2, $len2) = _parse_pos($pos2, 0);
|
||||
if ($p1 eq $p2) {
|
||||
# usually no split brain here (only if both path depths are non-zero)
|
||||
my $split = ($dep1 && $dep2);
|
||||
if (!$split) { # additionally check the corresponding version links
|
||||
my $path1 = sprintf("$basedir/version-%09d-$from1", $nr1);
|
||||
my $path2 = sprintf("$basedir/version-%09d-$from2", $nr2);
|
||||
if (my $vers1 = get_link($path1) and my $vers2 = get_link($path2)) {
|
||||
$split = 1 if $vers1 ne $vers2;
|
||||
}
|
||||
}
|
||||
return ($p1, $split);
|
||||
} elsif ($nr1 > $nr2) {
|
||||
# just flip arguments
|
||||
@_ = ($basedir, $pos2, $host2, $dep2, $pos1, $host1, $dep1);
|
||||
next;
|
||||
} elsif ($nr1 < $nr2) {
|
||||
# recursively advance path depth
|
||||
my $vers2 = _get_prev_pos($basedir, $nr2, $host2);
|
||||
return ("", -1) if !$vers2;
|
||||
@_ = ($basedir, $pos1, $host1, $dep1, $vers2, $host2, $dep2 + 1);
|
||||
next;
|
||||
} elsif ($from1 ne $from2) {
|
||||
# split brain is sure now, but continue computing the common split point
|
||||
my $vers1 = _get_prev_pos($basedir, $nr1, $host1);
|
||||
return ("", 1) if !$vers1;
|
||||
my $vers2 = _get_prev_pos($basedir, $nr2, $host2);
|
||||
return ("", 1) if !$vers2;
|
||||
my ($res, $split) = _get_common_ancestor($basedir, $vers1, $host1, $dep1 + 1, $vers2, $host2, $dep2 + 1);
|
||||
return ($res, 1);
|
||||
} elsif ($len1 < $len2) {
|
||||
# there may be no split brain (just incomplete replay) depending on path depth
|
||||
return ($p1, $dep1);
|
||||
} elsif ($len2 < $len1) {
|
||||
# dto symmetric
|
||||
return ($p2, $dep2);
|
||||
}
|
||||
return ($p1, $split);
|
||||
} elsif ($nr1 > $nr2) {
|
||||
# just flip arguments
|
||||
return _get_common_ancestor($basedir, $pos2, $host2, $dep2, $pos1, $host1, $dep1);
|
||||
} elsif ($nr1 < $nr2) {
|
||||
# recursively advance path depth
|
||||
my $vers2 = _get_prev_pos($basedir, $nr2, $host2);
|
||||
return ("", -1) if !$vers2;
|
||||
return _get_common_ancestor($basedir, $pos1, $host1, $dep1, $vers2, $host2, $dep2 + 1);
|
||||
} elsif ($from1 ne $from2) {
|
||||
# split brain is sure now, but continue computing the common split point
|
||||
my $vers1 = _get_prev_pos($basedir, $nr1, $host1);
|
||||
return ("", 1) if !$vers1;
|
||||
my $vers2 = _get_prev_pos($basedir, $nr2, $host2);
|
||||
return ("", 1) if !$vers2;
|
||||
my ($res, $split) = _get_common_ancestor($basedir, $vers1, $host1, $dep1 + 1, $vers2, $host2, $dep2 + 1);
|
||||
return ($res, 1);
|
||||
} elsif ($len1 < $len2) {
|
||||
# there may be no split brain (just incomplete replay) depending on path depth
|
||||
return ($p1, $dep1);
|
||||
} elsif ($len2 < $len1) {
|
||||
# dto symmetric
|
||||
return ($p2, $dep2);
|
||||
lwarn "error in algorithm: $p1, $nr1, $from1, $len1 : $p2, $nr2, $from2, $len2\n";
|
||||
return ("", -1);
|
||||
}
|
||||
lwarn "error in algorithm: $p1, $nr1, $from1, $len1 : $p2, $nr2, $from2, $len2\n";
|
||||
return ("", -1);
|
||||
}
|
||||
|
||||
sub get_common_ancestor {
|
||||
|
|
Loading…
Reference in New Issue