new link change detection method and general code rework
This new method for determining when links on pages have changed should be more efficient, since it avoids double calculation of the bestlinks. It also allows collecting data about the old links, before the scan pass, so the data is accurate when pages move around and bestlinks change. Also got some code back to a saner indent level.master
parent
0cb9e588e4
commit
fd7b5767d3
|
@ -58,52 +58,6 @@ sub backlinks ($) {
|
||||||
return @links;
|
return @links;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub find_changed_links (@_) {
|
|
||||||
my %linkchanged;
|
|
||||||
my %linkchangers;
|
|
||||||
foreach my $file (@_) {
|
|
||||||
my $page=pagename($file);
|
|
||||||
|
|
||||||
if (exists $links{$page}) {
|
|
||||||
foreach my $l (@{$links{$page}}) {
|
|
||||||
my $link=bestlink($page, $l);
|
|
||||||
if (length $link) {
|
|
||||||
if (! exists $oldlinks{$page} ||
|
|
||||||
! grep { bestlink($page, $_) eq $link } @{$oldlinks{$page}}) {
|
|
||||||
$linkchanged{$link}=1;
|
|
||||||
$linkchangers{lc($page)}=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (! grep { lc $_ eq lc $l } @{$oldlinks{$page}}) {
|
|
||||||
$linkchangers{lc($page)}=1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exists $oldlinks{$page}) {
|
|
||||||
foreach my $l (@{$oldlinks{$page}}) {
|
|
||||||
my $link=bestlink($page, $l);
|
|
||||||
if (length $link) {
|
|
||||||
if (! exists $links{$page} ||
|
|
||||||
! grep { bestlink($page, $_) eq $link } @{$links{$page}}) {
|
|
||||||
$linkchanged{$link}=1;
|
|
||||||
$linkchangers{lc($page)}=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (! grep { lc $_ eq lc $l } @{$links{$page}}) {
|
|
||||||
$linkchangers{lc($page)}=1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return \%linkchanged, \%linkchangers;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub genpage ($$) {
|
sub genpage ($$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $content=shift;
|
my $content=shift;
|
||||||
|
@ -389,6 +343,7 @@ sub refresh () {
|
||||||
my ($files, $exists)=find_src_files();
|
my ($files, $exists)=find_src_files();
|
||||||
|
|
||||||
my (%rendered, @add, @del, @internal, @internal_change);
|
my (%rendered, @add, @del, @internal, @internal_change);
|
||||||
|
|
||||||
# check for added or removed pages
|
# check for added or removed pages
|
||||||
foreach my $file (@$files) {
|
foreach my $file (@$files) {
|
||||||
my $page=pagename($file);
|
my $page=pagename($file);
|
||||||
|
@ -452,10 +407,11 @@ sub refresh () {
|
||||||
$stat[9] > $pagemtime{$page} ||
|
$stat[9] > $pagemtime{$page} ||
|
||||||
$forcerebuild{$page}) {
|
$forcerebuild{$page}) {
|
||||||
$pagemtime{$page}=$stat[9];
|
$pagemtime{$page}=$stat[9];
|
||||||
|
|
||||||
if (isinternal($page)) {
|
if (isinternal($page)) {
|
||||||
push @internal_change, $file;
|
|
||||||
# Preprocess internal page in scan-only mode.
|
# Preprocess internal page in scan-only mode.
|
||||||
preprocess($page, $page, readfile($srcfile), 1);
|
preprocess($page, $page, readfile($srcfile), 1);
|
||||||
|
push @internal_change, $file;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
push @needsbuild, $file;
|
push @needsbuild, $file;
|
||||||
|
@ -464,7 +420,19 @@ sub refresh () {
|
||||||
}
|
}
|
||||||
run_hooks(needsbuild => sub { shift->(\@needsbuild) });
|
run_hooks(needsbuild => sub { shift->(\@needsbuild) });
|
||||||
|
|
||||||
# scan and render files
|
# before scanning, make a note of where pages'
|
||||||
|
# old links pointed
|
||||||
|
my %oldlink_targets;
|
||||||
|
foreach my $file (@needsbuild, @del) {
|
||||||
|
my $page=pagename($file);
|
||||||
|
if (exists $oldlinks{$page}) {
|
||||||
|
foreach my $l (@{$oldlinks{$page}}) {
|
||||||
|
$oldlink_targets{$page}{$l}=bestlink($page, $l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# scan and render changed files
|
||||||
foreach my $file (@needsbuild) {
|
foreach my $file (@needsbuild) {
|
||||||
debug(sprintf(gettext("scanning %s"), $file));
|
debug(sprintf(gettext("scanning %s"), $file));
|
||||||
scan($file);
|
scan($file);
|
||||||
|
@ -500,20 +468,43 @@ sub refresh () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (%rendered || @del || @internal || @internal_change) {
|
# determine which links, on what pages, have changed
|
||||||
my @changed=(keys %rendered, @del);
|
my %backlinkchanged;
|
||||||
my ($linkchanged, $linkchangers)=find_changed_links(@changed);
|
my %linkchangers;
|
||||||
|
foreach my $file (@needsbuild, @del) {
|
||||||
|
my $page=pagename($file);
|
||||||
|
my %link_targets;
|
||||||
|
if (exists $links{$page}) {
|
||||||
|
foreach my $l (@{$links{$page}}) {
|
||||||
|
my $target=bestlink($page, $l);
|
||||||
|
if (! exists $oldlink_targets{$page}{$l} ||
|
||||||
|
$target ne $oldlink_targets{$page}{$l}) {
|
||||||
|
$backlinkchanged{$l}=1;
|
||||||
|
$linkchangers{lc($page)}=1;
|
||||||
|
}
|
||||||
|
delete $oldlink_targets{$page}{$l};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exists $oldlink_targets{$page} &&
|
||||||
|
%{$oldlink_targets{$page}}) {
|
||||||
|
foreach my $target (keys %{$oldlink_targets{$page}}) {
|
||||||
|
$backlinkchanged{$target}=1;
|
||||||
|
}
|
||||||
|
$linkchangers{lc($page)}=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%oldlink_targets=();
|
||||||
|
|
||||||
my $unsettled;
|
# rebuild dependant pages, recursively
|
||||||
|
my $deps=(@needsbuild || @del || @internal || @internal_change);
|
||||||
do {
|
do {
|
||||||
$unsettled=0;
|
$deps=0;
|
||||||
@changed=(keys %rendered, @del);
|
my @changed=(keys %rendered, @del);
|
||||||
my @exists_changed=(@add, @del);
|
my @exists_changed=(@add, @del);
|
||||||
|
|
||||||
my %lc_changed = map { lc(pagename($_)) => 1 } @changed;
|
my %lc_changed = map { lc(pagename($_)) => 1 } @changed;
|
||||||
my %lc_exists_changed = map { lc(pagename($_)) => 1 } @exists_changed;
|
my %lc_exists_changed = map { lc(pagename($_)) => 1 } @exists_changed;
|
||||||
|
|
||||||
# rebuild dependant pages
|
|
||||||
foreach my $f (@$files) {
|
foreach my $f (@$files) {
|
||||||
next if $rendered{$f};
|
next if $rendered{$f};
|
||||||
my $p=pagename($f);
|
my $p=pagename($f);
|
||||||
|
@ -528,7 +519,7 @@ sub refresh () {
|
||||||
$lc_exists_changed{$d})
|
$lc_exists_changed{$d})
|
||||||
||
|
||
|
||||||
($depends_simple{$p}{$d} & $IkiWiki::DEPEND_LINKS &&
|
($depends_simple{$p}{$d} & $IkiWiki::DEPEND_LINKS &&
|
||||||
$linkchangers->{$d})
|
$linkchangers{$d})
|
||||||
) {
|
) {
|
||||||
$reason = $d;
|
$reason = $d;
|
||||||
last;
|
last;
|
||||||
|
@ -563,7 +554,7 @@ sub refresh () {
|
||||||
my $page=pagename($file);
|
my $page=pagename($file);
|
||||||
if ($sub->($page, location => $p)) {
|
if ($sub->($page, location => $p)) {
|
||||||
if ($depends{$p}{$d} & $IkiWiki::DEPEND_LINKS) {
|
if ($depends{$p}{$d} & $IkiWiki::DEPEND_LINKS) {
|
||||||
next unless $linkchangers->{lc($page)};
|
next unless $linkchangers{lc($page)};
|
||||||
}
|
}
|
||||||
$reason = $page;
|
$reason = $page;
|
||||||
last D;
|
last D;
|
||||||
|
@ -576,14 +567,14 @@ sub refresh () {
|
||||||
debug(sprintf(gettext("building %s, which depends on %s"), $f, $reason));
|
debug(sprintf(gettext("building %s, which depends on %s"), $f, $reason));
|
||||||
render($f);
|
render($f);
|
||||||
$rendered{$f}=1;
|
$rendered{$f}=1;
|
||||||
$unsettled=1;
|
$deps=1;
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while $unsettled;
|
} while $deps;
|
||||||
|
|
||||||
# update backlinks at end
|
# update backlinks
|
||||||
foreach my $link (keys %{$linkchanged}) {
|
foreach my $link (keys %backlinkchanged) {
|
||||||
my $linkfile=$pagesources{$link};
|
my $linkfile=$pagesources{$link};
|
||||||
if (defined $linkfile) {
|
if (defined $linkfile) {
|
||||||
next if $rendered{$linkfile};
|
next if $rendered{$linkfile};
|
||||||
|
@ -592,7 +583,6 @@ sub refresh () {
|
||||||
$rendered{$linkfile}=1;
|
$rendered{$linkfile}=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# remove no longer rendered files
|
# remove no longer rendered files
|
||||||
foreach my $src (keys %rendered) {
|
foreach my $src (keys %rendered) {
|
||||||
|
|
Loading…
Reference in New Issue