DB_File WTF (was GDBM_File WTF?)

Dirk Koopman djk at tobit.co.uk
Sun Apr 8 19:24:29 BST 2007


Andy Armstrong wrote:
> On 8 Apr 2007, at 18:25, Dirk Koopman wrote:
> 
>> I see to be getting a similar and rather more final problem along a 
>> similar vein. Except that it bangs out with:
>>
>> Out of memory during ridiculously large request at 
>> /spider/perl/DXDupe.pm line 78.
>>
>>  $dbm = tie (%d, 'DB_File', $fn);
>>
>> ..
>> ..
>>
>>  if ($main::systime - $lasttime >=  3600) {
>>     while (($k, $v) = each %d) {
>>        delete $d{$k} if $main::systime >= $v; # line 78
>>     }
>>     $lasttime = $main::systime;
>>  }
>>
>> But only on the latest freebsd 6.2.
>>
>> Any clues?
> 
> Did you miss my post? It's not safe to modify the tied hash during 
> iteration. That's a limitation the Perl wrapper inherits from the 
> underlying library.
> 

Mind you, I was lead astray by this (from perlfunc "each")

      When the hash is entirely read, a null array is returned in
      list context (which when assigned produces a false (0) value),
      and "undef" in scalar context.  The next call to "each" after
      that will start iterating again.  There is a single iterator
      for each hash, shared by all "each", "keys", and "values" func‐
      tion calls in the program; it can be reset by reading all the
      elements from the hash, or by evaluating "keys HASH" or "values
      HASH".  If you add or delete elements of a hash while you’re
      iterating over it, you may get entries skipped or duplicated,
      so don’t.  Exception: It is always safe to delete the item most
      recently returned by "each()", which means that the following
      code will work:

              while (($key, $value) = each %hash) {
                   print $key, "\n";
                   delete $hash{$key};   # This is safe
              }

Note the gratuitous use of the word "safe" in official perl 
documentation :-)



More information about the london.pm mailing list