add_depends: optimise influence calculation
authorJoey Hess <joey@gnu.kitenet.net>
Fri, 9 Oct 2009 21:15:40 +0000 (17:15 -0400)
committerJoey Hess <joey@gnu.kitenet.net>
Fri, 9 Oct 2009 21:15:40 +0000 (17:15 -0400)
I made match_* functions whose influences can vary depending on the page
matched set a special "" influence to indicate this.

Then add_depends can try just one page, and if static influences are found,
stop there.

IkiWiki.pm
IkiWiki/Plugin/meta.pm
doc/plugins/write.mdwn

index c67a1e138c7a8657922a932495a1d4ab928918f2..cd93fe969de8a38b4356ad041ba7c1cf6de3b801 100644 (file)
@@ -1780,19 +1780,17 @@ sub add_depends ($$;$) {
                return 1;
        }
 
-       # Analyse the pagespec, and match it against all pages
-       # to get a list of influences, and add explicit dependencies
-       # for those.
-       #my $sub=pagespec_translate($pagespec);
-       #return if $@;
-       #foreach my $p (keys %pagesources) {
-       #       my $r=$sub->($p, location => $page );
-       #       my %i=$r->influences;
-       #       foreach my $i (keys %i) {
-       #               $depends_simple{$page}{lc $i} |= $i{$i};
-       #       }
-       #}
-       print STDERR "warning: use of add_depends by ".caller()."; influences not tracked\n";
+       # Add explicit dependencies for influences.
+       my $sub=pagespec_translate($pagespec);
+       return if $@;
+       foreach my $p (keys %pagesources) {
+               my $r=$sub->($p, location => $page);
+               my $i=$r->influences;
+               foreach my $k (keys %$i) {
+                       $depends_simple{$page}{lc $k} |= $i->{$k};
+               }
+               last if $r->influences_static;
+       }
 
        $depends{$page}{$pagespec} |= $deptype;
        return 1;
@@ -2045,9 +2043,9 @@ sub pagespec_match_list ($$;@) {
        }
 
        # Add simple dependencies for accumulated influences.
-       my %i=$accum->influences;
-       foreach my $i (keys %i) {
-               $depends_simple{$page}{lc $i} |= $i{$i};
+       my $i=$accum->influences;
+       foreach my $k (keys %$i) {
+               $depends_simple{$page}{lc $k} |= $i->{$k};
        }
 
        return @matches;
@@ -2099,12 +2097,14 @@ sub new {
 
 sub influences {
        my $this=shift;
-       if (! @_) {
-               return %{$this->[1]};
-       }
-       else {
-               $this->[1]={@_};
-       }
+       $this->[1]={@_} if @_;
+       my %i=%{$this->[1]};
+       delete $i{""};
+       return \%i;
+}
+
+sub influences_static {
+       return ! $_[0][1]->{""};
 }
 
 sub merge_influences {
@@ -2173,19 +2173,19 @@ sub match_link ($$;@) {
        my $bestlink = IkiWiki::bestlink($from, $link);
        foreach my $p (@{$links}) {
                if (length $bestlink) {
-                       return IkiWiki::SuccessReason->new("$page links to $link", $page => $IkiWiki::DEPEND_LINKS)
+                       return IkiWiki::SuccessReason->new("$page links to $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
                                if $bestlink eq IkiWiki::bestlink($page, $p);
                }
                else {
-                       return IkiWiki::SuccessReason->new("$page links to page $p matching $link", $page => $IkiWiki::DEPEND_LINKS)
+                       return IkiWiki::SuccessReason->new("$page links to page $p matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
                                if match_glob($p, $link, %params);
                        my ($p_rel)=$p=~/^\/?(.*)/;
                        $link=~s/^\///;
-                       return IkiWiki::SuccessReason->new("$page links to page $p_rel matching $link", $page => $IkiWiki::DEPEND_LINKS)
+                       return IkiWiki::SuccessReason->new("$page links to page $p_rel matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
                                if match_glob($p_rel, $link, %params);
                }
        }
-       return IkiWiki::FailReason->new("$page does not link to $link");
+       return IkiWiki::FailReason->new("$page does not link to $link", "" => 1);
 }
 
 sub match_backlink ($$;@) {
index c675880b3c48b5fd7228b4892b42cd7e8346d9fc..8dcd73a1a847683747c247068259255b6d905078 100644 (file)
@@ -291,14 +291,14 @@ sub match {
 
        if (defined $val) {
                if ($val=~/^$re$/i) {
-                       return IkiWiki::SuccessReason->new("$re matches $field of $page", $page => $IkiWiki::DEPEND_CONTENT);
+                       return IkiWiki::SuccessReason->new("$re matches $field of $page", $page => $IkiWiki::DEPEND_CONTENT, "" => 1);
                }
                else {
-                       return IkiWiki::FailReason->new("$re does not match $field of $page");
+                       return IkiWiki::FailReason->new("$re does not match $field of $page", "" => 1);
                }
        }
        else {
-               return IkiWiki::FailReason->new("$page does not have a $field");
+               return IkiWiki::FailReason->new("$page does not have a $field", "" => 1);
        }
 }
 
index 2254d70257dbeb17b58a4a5df6da2d42eea6901a..c72418c3c24eefe06662497a1197c33b5c0d4fab 100644 (file)
@@ -632,7 +632,7 @@ in the wiki that match the [[ikiwiki/PageSpec]].
 
 The page will automatically be made to depend on the specified
 [[ikiwiki/PageSpec]], so `add_depends` does not need to be called. This
-is significantly more efficient than calling `add_depends` and
+is often significantly more efficient than calling `add_depends` and
 `pagespec_match` in a loop. You should use this anytime a plugin
 needs to match a set of pages and do something based on that list.