Stas Bekman <[EMAIL PROTECTED]> writes:
Joe Schaefer wrote:
Stas Bekman <[EMAIL PROTECTED]> writes: [...]
Moving $b->remove to the end makes the code horribly kludgy. It's better to change the idiom to step through the buckets instead of removing them. Adjusting John's sample code:
my $bb = $r->upload('file')->bb(); open(OUT,">/tmp/test_file"); for (my $b = $bb->first; $b; $b = $bb->next($b)) { $b->read(my $data); print OUT $data; } close OUT;
[...]
What I'm going to recommend in the Apache::Upload docs is ask people to use the TIEHANDLE api for io() instead: my $io = $req->upload("foo")->io; print while read $io, $_, 8000; # read() will manage the buckets for you
Do you mean the difference is in being able to request chunks of limited size (8k?). Otherwise the two are equivalent.
No, they are not at all equivalent, because io *deletes* the buckets
as it reads them, which puts them right back into the bucket allocator for immediate reuse. Witness:
% CONTENT_TYPE="multipart/form-data; boundary=AaB03x" % PERL5OPT="-Mblib -MApache2 -MApache::Upload -MAPR::Bucket -MAPR::Pool" % export CONTENT_TYPE PERL5OPT % ls -sh ~/tmp/mfd_post_data 5.0M /home/joe/tmp/mfd_post_data
% perl -wle '$r = Apache::Request->new(APR::Pool->new); \ $bb = $r->upload("pics")->bb; \ for ($b = $bb->first; $b; $b= $bb->next($b)) {$b->read($_)} \ system "ps u $$" ' < ~/tmp/mfd_post_data USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND joe 32201 0.0 0.4 38424 9952 ? S+ 05:34 0:00 perl -wle $r = Ap
% perl -wle '$r = Apache::Request->new(APR::Pool->new); my $io = $r->upload("pics")->io; 1 while $io->read($_); system "ps u $$" ' < ~/tmp/mfd_post_data
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
joe 32203 0.0 0.2 33408 4908 ? S+ 05:36 0:00 perl -wle $r = Ap
That's a difference of 5MB, or exactly one full copy of the upload file into RAM. This is because the for(...) loop transforms the sole file bucket into a string of heap buckets that aren't cleaned up until the pool goes away.
Doesn't it get transformed into HEAP buckets with io->read?
static XS(apreq_xs_upload_brigade_read)
Looks exactly the same internally as the perl for loop. The only difference is that it calls apr_bucket_delete when it's done with it. Which you can do with the for() loop just the same.
In any case, I think $r->upload->slurp(my $data) is a goodness as it doesn't require the user to even be aware of the internal representation.
I was just teasing :-). Anyway's we can at least rip out the XS duplication in Apache::Upload and just write slurp in 2 lines of perl via bb->flatten.
And you need to load APR::Bucket, so it's better to keep it as it is. -0 on removal of $upload->slurp.
-- __________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
-- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html