On closer inspection, Bloom::Filter is a bit broken, unless I'm badly misreading it:

* The add() method doesn't actually add anything, because the new() method doesn't initialise the $self->{contents} hashref. it needs to be changed so that either the add method assigns directly to $self->{contents}, or the new() method changes 'keys' to 'contents'. that's probably just a typo.

* because $self->{contents} is not populated, _calculate_filter_length() always returns undef, so the default filter length is always used.

* because $self->{contents} is not populated, build_filter doesn't build a filter anyway.

* the use of == to compare bitstrings in check() is generating warnings, as you've seen. Its purpose is to test that ($a & $b) is the same as $a, ie that all the on bits in $a are also on in $b, and never mind the off bits. Someone better than me at pack(), ie anyone at all, will know how to test equivalence using the bitstrings themselves: meanwhile, you can make it work by testing with the unpacked versions.

* And anyway, it's not incremental. Every time you add a new key, the whole filter is rebuilt by way of a loop on $self->{contents}. This makes it more or less useless for your purposes: you presumably want an iterative check($_) || add($_) mechanism that can be placed in the equivalent of a while(<HUGE_FILE>) loop. As it stands, Bloom::Filter will perform another loop across your whole dataset-so-far for each input line, which might slow things down a bit.

You will need to roll your own, I think, unless the author can be persuaded to accommodate both approaches as well as fixing the bugs, but if you patch Bloom::Filter with this, at least your test script should work:

--- Filter.orig.pm Tue Apr 20 20:01:37 2004 +++ Filter.pm Tue Apr 20 20:04:34 2004 @@ -25,7 +25,7 @@ min_length => 20, filter_length => 20, %params, - keys => {} + contents => {} }, $class; } @@ -52,7 +52,7 @@ my $list = $self->{contents}; foreach my $add ( @addresses ) { # convert email to SHA1 hash if necessary - $add = sha1_base64( $add ) if $add =~ /@/o; + #$add = sha1_base64( $add ) if $add =~ /@/o; $list->{$add}++; } $self->{reindex_flag} = 1; @@ -83,7 +83,11 @@ # A match occurs if every bit we check is on foreach my $key ( @keys ) { my $mask = $self->_make_bitmask( $key ); - push @result, ($mask == ( $mask & $self->{filter} )); + #push @result, ($mask == ( $mask & $self->{filter} )); + + my $m = unpack("b*", $mask); + push @result, ($m == unpack("b*", ($mask & $self->{filter}))) +; + } return ( wantarray() ? @result : $result[0] ); }

In reply to Re: Bloom::Filter Usage [patch] by thpfft
in thread Bloom::Filter Usage by jreades

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.