in reply to Random and sequential for the price of one!
in thread Reading files sequentially

hi grying, thanks for the reply, but is it okay if you could demonstrate you seggestion in my code? thanks, arvin
  • Comment on RE: Random and sequential for the price of one!

Replies are listed 'Best First'.
Sample Random (Code)
by gryng (Hermit) on Sep 15, 2000 at 07:36 UTC
    sub shuffle { my $array = shift; my $i; for ($i = @$array; --$i; ) { my $j = int rand ($i+1); next if $i == $j; @$array[$i,$j] = @$array[$j,$i]; } } my $counter = 10; # this is the number of images you want open DAT, "ads.dat" or die "Error: cannot open data file!"; my @item; while (my $c=<DAT>) { my ($id,$image,$url)=split(/\|/,$c); push @item, {"image"=>$image,"url"=>$url,"desc"=>$desc}; } close DAT; while ($counter) { my @itemtmp = @item; shuffle(\@itemtmp); while (my $i = pop @itemtmp) { $img = $i->{"image"}; $link = $i->{"url"}; print qq|Set-Cookie: URL=$link\n|; print qq|Location: $img\n\n|; last if --$counter == 0; } }
    Warning, in that I didn't test that code, I only thought about it, and ran it through the syntax checker. Hopefully that is clearer and will help you out!

    Ciao,
    Gryn

      hi, i've tried your code and it's fairly the same.... i think what i am thinking is impossible bec. i'm running the script on the <img src="ad.cgi"> tag. imagine if i have 3 tags that runs the same script simultaneously. it will sure that although you randomly display the image it's 100% that it may display 2 or 3 same images at a time right? thanks anyway
        damian What you are dealing with is more of a concurrency issue.

        I suggest trying to reduce the webpage to one call of this script. However, if you don't you will have to help your script out more than you do now.

        Basically you have to use file locking, and then also write your script like an iterator function. That is, where you see the while loops you need remove them and instead store state information in files that will allow you to simulate the while loop over multiple calls of the script.

        Here is sample code to give you an idea of what I'm talking about (because it's getting late and I'm low on caffeine :) -- so I know I'm not entirely clear).

        simple.pl

        #!/usr/bin/perl #This program counts from 1 to 10 my $count = 1; while($count <= 10) { print $count,"\n"; $count++; }

        iterator.pl

        #!/usr/bin/perl #This program prints out 1 to 10, but only one number #per call to the program if (not -e "/tmp/iterator-state") { `echo 1 > /tmp/iterator-state`; } open(S, "/tmp/iterator-state"); chomp(my $count = <S>); print $count,"\n"; $count++; close(S); if ($count <= 10) { `echo $count > /tmp/iterator-state`; } else { unlink "/tmp/iterator-state"; }

        The major problem with this last approach is that it's very very very BAD. That is, you need to do alot of locking that I'm not doing in the example, and whole sorts of other things can go wrong.

        Therefore, I suggest you change your requirements. Either do it like my original sample does (that is, run the script only once and get all the results then). Alternatively, you can split the ad file into three separate files, and then run your original code on it (but of course once on each file).

        The last method I just mentioned can be jury-rigged to act more like what you want. You can periodically change the three files to be three new files with different subsets. That way you don't have the same 1/3 of the ad's appear on each 3 ad's.

        Enjoy!
        Gryn

        This is a case where I think it would be a good fit to use JavaScript to choose the locations of the images. Really this is a question that fits well on the client-side.

        Alternately have the html have the tags filled in through some sort of CGI/mod_perl/server side include.

        Trying to have a CGI program which is not aware of what else is on the target page try to fill it in is going to break in time. (What happens if you have 3 webservers? How about if you have requests coming from 2 people at once?)