From: Joey Hess Date: Thu, 22 Apr 2010 04:34:03 +0000 (-0400) Subject: Merge branch 'autotag' X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/commitdiff_plain/3ee571390e3697a3b738ea6791ac7f07052a709c?hp=17a89d3d19f3a04ca2686ff18df127e5afaf9577 Merge branch 'autotag' --- diff --git a/IkiWiki.pm b/IkiWiki.pm index dbf50feb4..19ed69d75 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1819,10 +1819,12 @@ sub add_depends ($$;$) { foreach my $p (keys %pagesources) { my $r=$sub->($p, location => $page); my $i=$r->influences; + my $static=$r->influences_static; foreach my $k (keys %$i) { + next unless $r || $static || $k eq $page; $depends_simple{$page}{lc $k} |= $i->{$k}; } - last if $r->influences_static; + last if $static; } $depends{$page}{$pagespec} |= $deptype; @@ -2146,6 +2148,9 @@ sub pagespec_match_list ($$;@) { my $r=$sub->($p, %params, location => $page); error(sprintf(gettext("cannot match pages: %s"), $r)) if $r->isa("IkiWiki::ErrorReason"); + unless ($r) { + $r->remove_influence($p); + } $accum |= $r; if ($r) { push @matches, $p; @@ -2231,7 +2236,7 @@ sub merge_influences { my $anded=shift; if (! $anded || (($this || %{$this->[1]}) && - ($other || %{$other->[1]}))) { + ($other || %{$other->[1]}))) { foreach my $influence (keys %{$other->[1]}) { $this->[1]{$influence} |= $other->[1]{$influence}; } @@ -2242,6 +2247,13 @@ sub merge_influences { } } +sub remove_influence { + my $this=shift; + my $torm=shift; + + delete $this->[1]{$torm}; +} + package IkiWiki::ErrorReason; our @ISA = 'IkiWiki::FailReason'; diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index 128a6342c..159008614 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -346,11 +346,11 @@ sub match { 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", "" => 1); + return IkiWiki::FailReason->new("$re does not match $field of $page", $page => $IkiWiki::DEPEND_CONTENT, "" => 1); } } else { - return IkiWiki::FailReason->new("$page does not have a $field", "" => 1); + return IkiWiki::FailReason->new("$page does not have a $field", $page => $IkiWiki::DEPEND_CONTENT); } } diff --git a/debian/NEWS b/debian/NEWS index 8b87bc601..433fc845c 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -1,4 +1,4 @@ -ikiwiki (3.20100406) unstable; urgency=low +ikiwiki (3.20100422) unstable; urgency=low This version of ikiwiki has a lot of changes that you need to know about. diff --git a/debian/changelog b/debian/changelog index a63860088..0ab04f522 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -ikiwiki (3.20100415) UNRELEASED; urgency=low +ikiwiki (3.20100422) UNRELEASED; urgency=low [ Joey Hess ] * tag: Automatic creation of tag pages can now be enabled using @@ -64,6 +64,8 @@ ikiwiki (3.20100415) UNRELEASED; urgency=low $pagestate{index}. * bzr: Support rcs_getmtime, and fix rcs_getctime implementation (Jelmer Vernooij) + * Quite a lot of new optimisations, and one major fix to a recent + performance regression. -- Joey Hess Sun, 04 Apr 2010 12:17:11 -0400 diff --git a/debian/postinst b/debian/postinst index fa0591153..810b7cfe0 100755 --- a/debian/postinst +++ b/debian/postinst @@ -4,7 +4,7 @@ set -e # Change this when some incompatible change is made that requires # rebuilding all wikis. -firstcompat=3.20100410 +firstcompat=3.20100422 if [ "$1" = configure ] && \ dpkg --compare-versions "$2" lt "$firstcompat"; then diff --git a/doc/bugs/depends_simple_mixup.mdwn b/doc/bugs/depends_simple_mixup.mdwn index 2603ff04c..a5910d02e 100644 --- a/doc/bugs/depends_simple_mixup.mdwn +++ b/doc/bugs/depends_simple_mixup.mdwn @@ -18,6 +18,71 @@ not noticing that bugs dependeded on the page and needs to be updated. Ok.. Turns out this was not a problem with the actual influences calculation or dependency calculation code. Whew! `match_link` -just didn't set the influence correctly when failing. [[fixed|done]] +just didn't set the influence correctly when failing. fixed --[[Joey]] + +--- + +Update: Reopening this because the fix for it rather sucks. + +I made `match_link` return on failure an influence of +type DEPEND_LINKS. So, a tag page that inlines `tagged(foo)` +gets a `depends_simple` built up that contains link dependencies for +*every* page in the wiki. A very bloaty way to represent the dependency! + +Per [[todo/dependency_types]], `link(done)` only needs to list in +`depends_simple` the pages that currently match. If a page is modified +to add the link, the regular dependency calculation code notices that +a new page matches. If a page that had the link is modified to remove it, +the `depends_simple` lets ikiwiki remember that the now non-matching page +matched before. + +Where that fell down was `!link(done)`. A page matching that was not added +to `depends_simple`, because the `link(done)` did not match it. If the page +is modified to add the link, the regular dependency calculation code +didn't notice, since the pagespec no longer matched. + +In this case, `depends_simple` needs to contain all pages +that do *not* match `link(done)`, but before my change, it contained +all pages that *do* match. After my change, it contained all pages. + +---- + +So, seems what is needed is a way for influence info to be manipulated by +the boolean operations that are applied. One way would be to have two +sets of influences be returned, one for successful matches, and one for +failed matches. Normally, these would be the same. For successful +`match_link`, the successful influence would be the page. +For failed `match_link`, the failed influence would be the page. + +Then, when NOTting a `*Reason`, swap the two sets of influences. +When ANDing/ORing, combine the individual sets. Querying the object for +influences should return only the successful influences. + +---- + +Would it be possible to avoid the complication of maintianing two sets of +influence info? + +Well, notice that the influence of `pagespec_match($page, "link(done)")` +is $page. Iff the match succeeds. + +Also, the influence of `pagespec_match($page, "!link(done)")` is +$page. Iff the (overall) match succeeds. + +Does that hold for all cases? If so, the code that populates +`depends_simple` could just test if the pagespec was successful, and +if not, avoid adding $page influences, while still adding any other, +non-$page influences. + +---- + +Hmm, commit f2b3d1341447cbf29189ab490daae418fbe5d02d seems +thuroughly wrong. So, what about influence info for other matches +like `!author(foo)` etc? Currently, none is returned, but it should +be a content influence. (Backlink influence data seems ok.) + +---- + +[[done]] again! diff --git a/doc/todo/auto-create_tag_pages_according_to_a_template.mdwn b/doc/todo/auto-create_tag_pages_according_to_a_template.mdwn index 1e0a910f4..f6d444890 100644 --- a/doc/todo/auto-create_tag_pages_according_to_a_template.mdwn +++ b/doc/todo/auto-create_tag_pages_according_to_a_template.mdwn @@ -239,7 +239,7 @@ wrong direction. (fixed --[[Joey]] ) [[!template id=gitbranch branch=origin/autotag author="[[Joey]]"]] I've pushed an autotag branch of my own, which refactors things a bit and fixes bugs around deletion/recreation. -I've tested it somewhat. --[[Joey]] +I've tested it fairly thouroughly. --[[Joey]] [f3abeac919c4736429bd3362af6edf51ede8e7fe]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=f3abeac919c4736429bd3362af6edf51ede8e7fe (commitdiff for f3abeac919c4736429bd3362af6edf51ede8e7fe) [4af4d26582f0c2b915d7102fb4a604b176385748]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=4af4d26582f0c2b915d7102fb4a604b176385748 (commitdiff for 4af4d26582f0c2b915d7102fb4a604b176385748) diff --git a/t/add_depends.t b/t/add_depends.t index 9b074818c..aa58fb0ff 100755 --- a/t/add_depends.t +++ b/t/add_depends.t @@ -1,7 +1,7 @@ #!/usr/bin/perl use warnings; use strict; -use Test::More tests => 38; +use Test::More tests => 40; BEGIN { use_ok("IkiWiki"); } %config=IkiWiki::defaultconfig(); @@ -60,3 +60,11 @@ ok(! ($IkiWiki::depends{foo0}{"*"} & $IkiWiki::DEPEND_PRESENCE)); ok(add_depends("foo9", "*", deptype("monkey"))); ok($IkiWiki::depends{foo9}{"*"} & $IkiWiki::DEPEND_CONTENT); ok(! ($IkiWiki::depends{foo9}{"*"} & ($IkiWiki::DEPEND_PRESENCE | $IkiWiki::DEPEND_LINKS))); + +# Influences are added for dependencies involving links. +$pagesources{"foo"}="foo.mdwn"; +$links{foo}=[qw{bar}]; +$pagesources{"bar"}="bar.mdwn"; +$links{bar}=[qw{}]; +ok(add_depends("foo", "link(bar) and backlink(meep)")); +ok($IkiWiki::depends_simple{foo}{foo} == $IkiWiki::DEPEND_LINKS); diff --git a/t/pagespec_match_list.t b/t/pagespec_match_list.t index 05dc012fe..244ad9159 100755 --- a/t/pagespec_match_list.t +++ b/t/pagespec_match_list.t @@ -1,7 +1,7 @@ #!/usr/bin/perl use warnings; use strict; -use Test::More tests => 94; +use Test::More tests => 126; BEGIN { use_ok("IkiWiki"); } @@ -27,6 +27,8 @@ IkiWiki::checkconfig(); $IkiWiki::pagectime{foo} = 2; $IkiWiki::pagectime{foo2} = 2; $IkiWiki::pagectime{foo3} = 1; +$IkiWiki::pagectime{foo4} = 1; +$IkiWiki::pagectime{foo5} = 1; $IkiWiki::pagectime{bar} = 3; $IkiWiki::pagectime{"post/1"} = 6; $IkiWiki::pagectime{"post/2"} = 6; @@ -79,18 +81,44 @@ foreach my $spec ("* and link(bar)", "* or link(bar)") { %IkiWiki::depends=(); } +# A link pagespec is influenced by the pages that currently contain the link. +# It is not influced by pages that do not currently contain the link, +# because if those pages were changed to contain it, regular dependency +# handling would be triggered. +foreach my $spec ("* and link(bar)", "link(bar)", "no_such_page or link(bar)") { + pagespec_match_list("foo2", $spec); + ok($IkiWiki::depends_simple{foo2}{foo2} == $IkiWiki::DEPEND_LINKS); + ok(! exists $IkiWiki::depends_simple{foo2}{foo}, $spec); + %IkiWiki::depends_simple=(); + %IkiWiki::depends=(); +} + +# Oppositely, a pagespec that tests for pages that do not have a link +# is not influenced by pages that currently contain the link, but +# is instead influenced by pages that currently do not (but that +# could be changed to have it). +foreach my $spec ("* and !link(bar)", "* and !(!(!link(bar)))") { + pagespec_match_list("foo2", $spec); + ok(! exists $IkiWiki::depends_simple{foo2}{foo2}); + ok($IkiWiki::depends_simple{foo2}{foo} == $IkiWiki::DEPEND_LINKS, $spec); + %IkiWiki::depends_simple=(); + %IkiWiki::depends=(); +} + # a pagespec with backlinks() will add as an influence the page with the links -foreach my $spec ("bar or (backlink(foo) and !*.png)", "backlink(foo)") { +foreach my $spec ("bar or (backlink(foo) and !*.png)", "backlink(foo)", "!backlink(foo)") { pagespec_match_list("foo2", $spec, deptype => deptype("presence")); ok($IkiWiki::depends{foo2}{$spec} & $IkiWiki::DEPEND_PRESENCE); ok(! ($IkiWiki::depends{foo2}{$spec} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_LINKS))); ok($IkiWiki::depends_simple{foo2}{foo} == $IkiWiki::DEPEND_LINKS); + ok(! exists $IkiWiki::depends_simple{foo2}{foo2}); %IkiWiki::depends_simple=(); %IkiWiki::depends=(); pagespec_match_list("foo2", $spec, deptype => deptype("links")); ok($IkiWiki::depends{foo2}{$spec} & $IkiWiki::DEPEND_LINKS); ok(! ($IkiWiki::depends{foo2}{$spec} & ($IkiWiki::DEPEND_PRESENCE | $IkiWiki::DEPEND_CONTENT))); ok($IkiWiki::depends_simple{foo2}{foo} == $IkiWiki::DEPEND_LINKS); + ok(! exists $IkiWiki::depends_simple{foo2}{foo2}); %IkiWiki::depends_simple=(); %IkiWiki::depends=(); pagespec_match_list("foo2", $spec, deptype => deptype("presence", "links")); @@ -98,6 +126,7 @@ foreach my $spec ("bar or (backlink(foo) and !*.png)", "backlink(foo)") { ok($IkiWiki::depends{foo2}{$spec} & $IkiWiki::DEPEND_LINKS); ok(! ($IkiWiki::depends{foo2}{$spec} & $IkiWiki::DEPEND_CONTENT)); ok($IkiWiki::depends_simple{foo2}{foo} == $IkiWiki::DEPEND_LINKS); + ok(! exists $IkiWiki::depends_simple{foo2}{foo2}); %IkiWiki::depends_simple=(); %IkiWiki::depends=(); pagespec_match_list("foo2", $spec);