Question to Cache::Memcached

Brad Fitzpatrick brad@danga.com
Tue, 8 Jun 2004 11:06:23 -0700 (PDT)


Whoa, good bug!

I guess I assumed Perl ints would wrap around, not get magically upcast to
some float/bigint type, or whatever's going on.

Can you change it to this:

 $hash =3D ($hash*33 + ord($_)) % (2 ** 31);

That should work, right?  *scratchs head*



On Tue, 8 Jun 2004, Joachim Bauernberger wrote:

> Hi,
>
> consider the snipped below which extracts the _hashfuc from Memcached.pm.
>
> Feeding a key to set or add which looks like this:
> "020/dating/profilcache/profilAnsicht.xmlindex=3Dpage1userid=3D1812379"
>
> will result in an internal key like:
> 2.34523032118619e+15
>
> doing a % modulo on this value will always result in 0 therefore the arra=
y
> index is 0 and the second server is ignored.
>
> Best regards,
> ~/joachim
>
> #########################################
> #!/usr/bin/perl
> use strict;
>
> my $res =3D  _hashfunc($ARGV[0])."\n";
>
> print "$res\n";
> print "res % 2: ". $res % 2 ."\n";
>
> sub _hashfunc {
>     my $hash =3D 0;
>     foreach (split //, shift) {
>             $hash =3D $hash*33 + ord($_);
>     }
> return $hash;
> }
> ########################################
>
> Not sure if something like the following would work better in this case (=
or
> break something else):
>
> foreach (split //, shift) {
>  $hash +=3D sprintf("%d",ord($_));
> }
>
> Thanks & Best regards,
> ~/joachim
>
> Regards,
> ~/joachim
>
>
> On Monday 07 June 2004 22:56, Joachim Bauernberger wrote:
> > Hi Brad,
> >
> > On Monday 07 June 2004 21:09, Brad Fitzpatrick wrote:
> > > > How does the module decide which backend to give it too (if no weig=
ht
> > > > value is specified)?
> > >
> > > It runs the key through a hashing function, then mods that number wit=
h
> > > the number of buckets (number of servers * each's weight) and uses th=
e
> > > result as the bucket number.
> > >
> > > So if you have two servers:
> > >
> > > 10.0.0.1 weight 1   ->  1 bucket  (bucket 0)
> > > 10.0.0.2 weight 3   ->  3 buckets (bucket 1, 2, 3)
> > >
> > > Total:                  4 buckets
> > >
> > > So now we have key "foobar".  HashValue("foobar") =3D 238423432423434=
=2E
> > >
> > > Taking the hash value, mod 4 (4 buckets)...
> > >
> > >  238423432423434 % 4 =3D 2 (bucket 2)
> > >
> > > So it uses 10.0.0.2
> > >
> > > > Is there a restriction on how the keys may look?
> > >
> > > No spaces or newlines.
> > >
> > > > My keys are similar to this (without quotes):
> > > >
> > > > "010/dating/profilansicht/profilAnsicht.xmlindex=3Dpage1userid=3D21=
70797"
> > >
> > > That looks fine.
> > >
> > > So the mystery is:  what hash values is it calculating for your keys?
> > > It'd be way too weird if they were all 0.
> >
> > I just added some debugging to Memcached.pm:
> >
> > first in get_sock() just after asigning a value to $hv
> >
> > print STDERR "[JMBDEBUG] hv =3D $hv
> > bucketcount=3D".$self->{'bucketcount'}."\n";
> >
> > this results in the following output:
> >
> > [JMBDEBUG] hv =3D 8.25640843592502e+101 bucketcount=3D2
> >
> >
> > then in get_sock() just after $host gets calculated:
> > print STDERR "[JMBDEBUG] host=3D".$host." ".$self->{'buckets'}[0]." ".
> > $self->{'buckets'}[1]."\n";
> >
> > which results in:
> > [JMBDEBUG] host=3D127.0.0.1:11211 127.0.0.1:11211 127.0.0.1:11212
> >
> > Somehow I always get 0 from this:
> >  $hv % $self->{'bucketcount'}
> >
> > Thanks again,
> > ~/joachim
>
> --
> Phone: +49 (0) 89 490 267 726
> Fax: +49 (0) 89 490 267 701
> Mobile: +49 (0) 179 674 3611
> mailto: joachim.bauernberger@friendscout24.de =A0 =A0 =A0 =A0
> Web: http://www.friendscout24.de
>
>