*/
var $_active;
+ /**
+ * Stream timeout in seconds. Applies for example to fread()
+ *
+ * @var integer
+ * @access private
+ */
+ var $_timeout_seconds;
+
+ /**
+ * Stream timeout in microseconds
+ *
+ * @var integer
+ * @access private
+ */
+ var $_timeout_microseconds;
+
// }}}
// }}}
// {{{ methods
*/
function memcached ($args)
{
- $this->set_servers($args['servers']);
- $this->_debug = $args['debug'];
+ $this->set_servers(@$args['servers']);
+ $this->_debug = @$args['debug'];
$this->stats = array();
- $this->_compress_threshold = $args['compress_threshold'];
- $this->_persistant = isset($args['persistant']) ? $args['persistant'] : false;
+ $this->_compress_threshold = @$args['compress_threshold'];
+ $this->_persistant = array_key_exists('persistant', $args) ? (@$args['persistant']) : false;
$this->_compress_enable = true;
$this->_have_zlib = function_exists("gzcompress");
$this->_cache_sock = array();
$this->_host_dead = array();
+
+ $this->_timeout_seconds = 1;
+ $this->_timeout_microseconds = 0;
}
// }}}
$key = is_array($key) ? $key[1] : $key;
- $this->stats['delete']++;
+ @$this->stats['delete']++;
$cmd = "delete $key $time\r\n";
if(!fwrite($sock, $cmd, strlen($cmd)))
{
$res = trim(fgets($sock));
if ($this->_debug)
- printf("MemCache: delete %s (%s)\n", $key, $res);
+ $this->_debugprint(sprintf("MemCache: delete %s (%s)\n", $key, $res));
if ($res == "DELETED")
return true;
if (!is_resource($sock))
return false;
- $this->stats['get']++;
+ @$this->stats['get']++;
$cmd = "get $key\r\n";
if (!fwrite($sock, $cmd, strlen($cmd)))
if ($this->_debug)
foreach ($val as $k => $v)
- printf("MemCache: sock %s got %s => %s\r\n", $sock, $k, $v);
-
- return $val[$key];
+ $this->_debugprint(@sprintf("MemCache: sock %s got %s => %s\r\n", serialize($sock), $k, $v));
+
+ return @$val[$key];
}
// }}}
if ($this->_debug)
foreach ($val as $k => $v)
- printf("MemCache: got %s => %s\r\n", $k, $v);
+ $this->_debugprint(sprintf("MemCache: got %s => %s\r\n", $k, $v));
return $val;
}
$this->_single_sock = $this->_servers[0];
}
+ /**
+ * Sets the timeout for new connections
+ *
+ * @param integer $seconds Number of seconds
+ * @param integer $microseconds Number of microseconds
+ *
+ * @access public
+ */
+ function set_timeout ($seconds, $microseconds)
+ {
+ $this->_timeout_seconds = $seconds;
+ $this->_timeout_microseconds = $microseconds;
+ }
+
// }}}
// }}}
// {{{ private methods
$sock = @fsockopen($ip, $port, $errno, $errstr, $timeout);
}
- if (!$sock)
+ if (!$sock) {
+ if ($this->_debug)
+ $this->_debugprint( "Error connecting to $host: $errstr\n" );
return false;
+ }
+
+ // Initialise timeout
+ stream_set_timeout($sock, $this->_timeout_seconds, $this->_timeout_microseconds);
+
return true;
}
function _dead_sock ($sock)
{
$host = array_search($sock, $this->_cache_sock);
- list ($ip, $port) = explode(":", $host);
+ @list ($ip, $port) = explode(":", $host);
$this->_host_dead[$ip] = time() + 30 + intval(rand(0, 10));
$this->_host_dead[$host] = $this->_host_dead[$ip];
unset($this->_cache_sock[$host]);
*/
function _hashfunc ($key)
{
- $hash = 0;
- for ($i=0; $i<strlen($key); $i++)
- {
- $hash = $hash*33 + ord($key[$i]);
- }
-
- return $hash;
+ # Hash function must on [0,0x7ffffff]
+ # We take the first 31 bits of the MD5 hash, which unlike the hash
+ # function used in a previous version of this client, works
+ return hexdec(substr(md5($key),0,8)) & 0x7fffffff;
}
// }}}
return null;
$key = is_array($key) ? $key[1] : $key;
- $this->stats[$cmd]++;
+ @$this->stats[$cmd]++;
if (!fwrite($sock, "$cmd $key $amt\r\n"))
return $this->_dead_sock($sock);
break;
$offset += $n;
$bneed -= $n;
- $ret[$rkey] .= $data;
+ @$ret[$rkey] .= $data;
}
if ($offset != $len+2)
{
// Something is borked!
if ($this->_debug)
- printf("Something is borked! key %s expecting %d got %d length\n", $rkey, $len+2, $offset);
+ $this->_debugprint(sprintf("Something is borked! key %s expecting %d got %d length\n", $rkey, $len+2, $offset));
unset($ret[$rkey]);
$this->_close_sock($sock);
return false;
}
- $ret[$rkey] = rtrim($ret[$rkey]);
-
if ($this->_have_zlib && $flags & MEMCACHE_COMPRESSED)
$ret[$rkey] = gzuncompress($ret[$rkey]);
+ $ret[$rkey] = rtrim($ret[$rkey]);
+
if ($flags & MEMCACHE_SERIALIZED)
$ret[$rkey] = unserialize($ret[$rkey]);
} else
{
- print("Error parsing memcached response\n");
+ $this->_debugprint("Error parsing memcached response\n");
return 0;
}
}
if (!is_resource($sock))
return false;
- $this->stats[$cmd]++;
+ @$this->stats[$cmd]++;
$flags = 0;
$val = serialize($val);
$flags |= MEMCACHE_SERIALIZED;
if ($this->_debug)
- printf("client: serializing data as it is not scalar\n");
+ $this->_debugprint(sprintf("client: serializing data as it is not scalar\n"));
}
$len = strlen($val);
$c_val = gzcompress($val, 9);
$c_len = strlen($c_val);
- if ($c_len < $len*(1 - COMPRESS_SAVINGS))
+ if ($c_len < $len*(1 - COMPRESSION_SAVINGS))
{
if ($this->_debug)
- printf("client: compressing data; was %d bytes is now %d bytes\n", $len, $c_len);
+ $this->_debugprint(sprintf("client: compressing data; was %d bytes is now %d bytes\n", $len, $c_len));
$val = $c_val;
$len = $c_len;
$flags |= MEMCACHE_COMPRESSED;
{
if ($flags & MEMCACHE_COMPRESSED)
$val = 'compressed data';
- printf("MemCache: %s %s => %s (%s)\n", $cmd, $key, $val, $line);
+ $this->_debugprint(sprintf("MemCache: %s %s => %s (%s)\n", $cmd, $key, $val, $line));
}
if ($line == "STORED")
return true;
return $this->_cache_sock[$host];
}
+ function _debugprint($str){
+ print($str);
+ }
+
// }}}
// }}}
// }}}