From b4db945b34d0475894467792acc69038d5b25306 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 19 Jul 2011 11:39:32 -0400 Subject: mercurial: Make both rcs_getctime and rcs_getmtime fast. (Daniel Andersson) --- IkiWiki/Plugin/mercurial.pm | 84 +++++++++++++++++----- debian/changelog | 1 + doc/rcs.mdwn | 4 +- ...rcurial_backend__44___based_on_Git_backend.mdwn | 5 ++ 4 files changed, 76 insertions(+), 18 deletions(-) diff --git a/IkiWiki/Plugin/mercurial.pm b/IkiWiki/Plugin/mercurial.pm index 79f021516..e64e00512 100644 --- a/IkiWiki/Plugin/mercurial.pm +++ b/IkiWiki/Plugin/mercurial.pm @@ -258,7 +258,7 @@ sub rcs_recentchanges ($) { foreach my $info (mercurial_log($out)) { my @pages = (); my @message = (); - + foreach my $msgline (split(/\n/, $info->{description})) { push @message, { line => $msgline }; } @@ -310,28 +310,80 @@ sub rcs_diff ($;$) { # TODO } -sub rcs_getctime ($) { - my ($file) = @_; +{ +my %time_cache; + +sub findtimes ($$) { + my $file=shift; + my $id=shift; # 0 = mtime ; 1 = ctime + + if (! keys %time_cache) { + my $date; + + # It doesn't seem possible to specify the format wanted for the + # changelog (same format as is generated in git.pm:findtimes(), + # though the date differs slightly) without using a style + # _file_. There is a "hg log" switch "--template" to directly + # control simple output formatting, but in this case, the + # {file} directive must be redefined, which can only be done + # with "--style". + # + # If {file} is not redefined, all files are output on a single + # line separated with a space. It is not possible to conclude + # if the space is part of a filename or just a separator, and + # thus impossible to use in this case. + # + # Some output filters are available in hg, but they are not fit + # for this cause (and would slow down the process + # unnecessarily). + + eval q{use File::Temp}; + error $@ if $@; + my ($tmpl_fh, $tmpl_filename) = File::Temp::tempfile(UNLINK => 1); + + print $tmpl_fh 'changeset = "{date}\\n{files}\\n"' . "\n"; + print $tmpl_fh 'file = "{file}\\n"' . "\n"; + + foreach my $line (run_or_die('hg', 'log', '--style', $tmpl_filename)) { + # {date} gives output on the form + # 1310694511.0-7200 + # where the first number is UTC Unix timestamp with one + # decimal (decimal always 0, at least on my system) + # followed by local timezone offset from UTC in + # seconds. + if (! defined $date && $line =~ /^\d+\.\d[+-]\d*$/) { + $line =~ s/^(\d+).*/$1/; + $date=$line; + } + elsif (! length $line) { + $date=undef; + } + else { + my $f=$line; - my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", - "--style", "default", "$config{srcdir}/$file"); - open (my $out, "-|", @cmdline); + if (! $time_cache{$f}) { + $time_cache{$f}[0]=$date; # mtime + } + $time_cache{$f}[1]=$date; # ctime + } + } + } - my @log = (mercurial_log($out)); + return exists $time_cache{$file} ? $time_cache{$file}[$id] : 0; +} - if (@log < 1) { - return 0; - } +} - eval q{use Date::Parse}; - error($@) if $@; - - my $ctime = str2time($log[$#log]->{"date"}); - return $ctime; +sub rcs_getctime ($) { + my $file = shift; + + return findtimes($file, 1); } sub rcs_getmtime ($) { - error "rcs_getmtime is not implemented for mercurial\n"; # TODO + my $file = shift; + + return findtimes($file, 0); } 1 diff --git a/debian/changelog b/debian/changelog index 30084304a..562816083 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ ikiwiki (3.20110716) UNRELEASED; urgency=low can be used. (Daniel Andersson) * mercurial: fix viewing of a diff containing non-utf8 changes. (Daniel Andersson) + * mercurial: Make both rcs_getctime and rcs_getmtime fast. (Daniel Andersson) -- Joey Hess Tue, 19 Jul 2011 11:22:52 -0400 diff --git a/doc/rcs.mdwn b/doc/rcs.mdwn index 9f531d442..f2c6f192f 100644 --- a/doc/rcs.mdwn +++ b/doc/rcs.mdwn @@ -21,8 +21,8 @@ auto.setup |yes |yes |incomplete|yes |incomplete |yes `rcs_rename` |yes |yes |yes |yes |no |yes |no |yes `rcs_remove` |yes |yes |yes |yes |no |yes |no |yes `rcs_diff` |yes |yes |yes |yes |no |yes |yes |yes -`rcs_getctime` |fast |slow |slow |slow |slow |slow |slow |slow -`rcs_getmtime` |fast |slow |slow |slow |no |no |no |no +`rcs_getctime` |fast |slow |slow |slow |fast |slow |slow |slow +`rcs_getmtime` |fast |slow |slow |slow |fast |no |no |no `rcs_preprevert` |yes |no |no |no |no |no |no |no `rcs_revert` |yes |no |no |no |no |no |no |no anonymous push |yes |no |no |no |no |no |no |no diff --git a/doc/todo/rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn b/doc/todo/rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn index 6cd195a53..54ab4ad3a 100644 --- a/doc/todo/rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn +++ b/doc/todo/rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn @@ -21,6 +21,11 @@ In the patch listing below, I've marked the parts of the patch that should be re --[[Daniel Andersson]] +> I have applied this, but I left the temp file in. +> The overhead seems small since it will only be run once per ikiwiki run, +> and only when `ikiwiki --gettime` is run, or the first time +> ikiwiki runs. Thanks for this! [[done]] --[[Joey]] + --- diff -r 78a217fb13f3 -r 1b6c46b62a28 Plugin/mercurial.pm -- cgit v1.2.3