until recently, $r->finfo() was missing from the mod_perl 2.0 API. while it had been on my list of things to do for a while, I finally managed to get around to it during ApacheCon.$r->finfo() was a pretty cool, but little used feature in mod_perl 1.0. basically, when Apache ran the translation phase and determined the real file corresponding to the URI ($r->filename), it would stat the file and stuff that data into the finfo slot in the request_rec. mod_perl added some sugar, which allowed for some pretty interesting things, like
if (-r $r->finfo && -s _) {
...
}
finfo() populated the special filehandle _ with data from Apache's finfo struct and returns it, giving you two speedups: first using Apache's cache (finfo) then perl's cache (_), in both cases avoiding a direct stat to the file on disk (save the first one, that is). all in all, much more efficient than stat $r->filename. (oh, and take the time to look up _ if you don't know what it does - it's pretty cool)finfo slot in the request_rec doesn't translate directly into the same thing perl stores in _, so the above trickery won't work anymore in mod_perl 2.0. here's how it looks now:
use APR::Finfo ();
use APR::Const -compile => qw(UREAD);
my $finfo = $r->finfo;
if ($finfo->protection & APR::UREAD && $finfo->size) { ... }
$r->finfo() returns an APR::Finfo object, through which file attributes are accessed. also note that the permissions are determined using APR specific constants, not the typical Fcntl ones (though I haven't actually checked to see if they are the same).stat calls to the filesystem. I suppose you could also dostat $r->filename;
if (-r _ && -s _) { ... }
APR::Finfo stuff you can avoid that initial trip back to disk.
Re:Faster?
geoff on 2003-11-26T13:34:38
when I was implementing it I said to myself, "well, there is the overhead of the method call, but that has to be faster than going to disk." my gut tells me it's true, but I have no real evidence.
I suspect that what really makes the difference is not having_automatically populated when you need to make multiplestatcalls - in that case, you might be better off using perl'sstaton$r->filenameand the special filehandle. I really don't know.
but at least now people have different approaches they can benchmark, where they didn't before:)