Last modified: 2008-09-27 23:40:39 UTC
Function get_sock uses loop for for searching for memcache server. This is: <pre> for ($tries = 0; $tries<20; $tries++) { $host = $this->_buckets[$hv % $this->_bucketcount]; $sock = $this->sock_to_host($host); if (is_resource($sock)) { $this->_flush_read_buffer($sock); return $sock; } $hv += $this->_hashfunc($tries . $realkey); }</pre> If there are servers in _buckets then the if(is_resource..) is true and loop exits. However, if there is no good server then the line: <pre>$hv += $this->_hashfunc($tries . $realkey);</pre> is reached and the $hv is increased. In the next loop passes <pre>$hv % $this->_bucketcount</pre> will return negative numbers as the $hv will pass beyond the bounds of the integer type. My idea to fix it is to change <pre>$hv += $this->_hashfunc($tries . $realkey);</pre> to: <pre>$hv ^= $this->_hashfunc($tries . $realkey);</pre> or: <pre>$hv += $this->_hashfunc($tries . $realkey); $hv ^= 0x7fffffff;</pre> One should performe a test of distribution of this variable (a histogram) after making this changes.
Ech.. there is no "preview" or "edit" option [why?] nor the help about tags that can be used to format this text. If someone who can edit will see it - please - remove/change the <pre> above to something that is accepted here to format a code *and* delete this comment. Thanks
Ah! What a terrible mistake! The last suggested version should be: $hv += $this->_hashfunc($tries . $realkey); $hv &= 0x7fffffff; That is '&' instead of '^' of course! I'm sorry for that typo. [and this is a version which I use on my local test MW]
This would explain the mysterious negative indexes that popped up on a maintenance script
Fixed in r41326
Thanks for applying this fix.