Joe Schaefer wrote:
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



Reply via email to