Skip to content

Commit

Permalink
[jan] Add support for memcached extension and PHP 7.
Browse files Browse the repository at this point in the history
  • Loading branch information
yunosh committed Jul 1, 2016
1 parent 2cb8a19 commit 7e5502b
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 44 deletions.
115 changes: 83 additions & 32 deletions framework/Memcache/lib/Horde/Memcache.php
@@ -1,15 +1,25 @@
<?php
/**
* This class provides an API or Horde code to interact with a centrally
* configured memcache installation.
*
* memcached website: http://www.danga.com/memcached/
*
* Copyright 2007-2016 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Jan Schneider <jan@horde.org>
* @author Michael Slusarz <slusarz@horde.org>
* @author Didi Rieder <adrieder@sbox.tugraz.at>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Memcache
*/

/**
* This class provides an API or Horde code to interact with a centrally
* configured memcache installation.
*
* memcached website: http://www.danga.com/memcached/
*
* @author Jan Schneider <jan@horde.org>
* @author Michael Slusarz <slusarz@horde.org>
* @author Didi Rieder <adrieder@sbox.tugraz.at>
* @category Horde
Expand Down Expand Up @@ -107,7 +117,8 @@ class Horde_Memcache implements Serializable
* - hostspec: (array) The memcached host(s) to connect to.
* DEFAULT: 'localhost'
* - large_items: (boolean) Allow storing large data items (larger than
* Horde_Memcache::MAX_SIZE)?
* Horde_Memcache::MAX_SIZE)? Currently not supported with
* memcached extension.
* DEFAULT: true
* - persistent: (boolean) Use persistent DB connections?
* DEFAULT: false
Expand All @@ -134,19 +145,48 @@ public function __construct(array $params = array())
*/
public function _init()
{
$this->_memcache = new Memcache();
if (class_exists('Memcached')) {
if (empty($this->_params['persistent'])) {
$this->_memcache = new Memcached();
} else {
$this->_memcache = new Memcached('horde_memcache');
}
$this->_params['large_items'] = false;
$this->_memcache->setOptions(array(
Memcached::OPT_COMPRESSION => $this->_params['compression'],
Memcached::OPT_DISTRIBUTION => Memcached::DISTRIBUTION_CONSISTENT,
Memcached::OPT_HASH => Memcached::HASH_MD5,
Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
Memcached::OPT_PREFIX_KEY => $this->_params['prefix'],
));
} else {
// Force consistent hashing
ini_set('memcache.hash_strategy', 'consistent');
$this->_memcache = new Memcache();
if (!empty($this->_params['c_threshold'])) {
$this->_memcache->setCompressThreshold($this->_params['c_threshold']);
}
}

for ($i = 0, $n = count($this->_params['hostspec']); $i < $n; ++$i) {
$res = $this->_memcache->addServer(
$this->_params['hostspec'][$i],
empty($this->_params['port'][$i]) ? 0 : $this->_params['port'][$i],
!empty($this->_params['persistent']),
!empty($this->_params['weight'][$i]) ? $this->_params['weight'][$i] : 1,
1,
15,
true,
array($this, 'failover')
);
if ($this->_memcache instanceof Memcached) {
$res = $this->_memcache->addServer(
$this->_params['hostspec'][$i],
empty($this->_params['port'][$i]) ? 0 : $this->_params['port'][$i],
!empty($this->_params['weight'][$i]) ? $this->_params['weight'][$i] : 0
);
} else {
$res = $this->_memcache->addServer(
$this->_params['hostspec'][$i],
empty($this->_params['port'][$i]) ? 0 : $this->_params['port'][$i],
!empty($this->_params['persistent']),
!empty($this->_params['weight'][$i]) ? $this->_params['weight'][$i] : 1,
1,
15,
true,
array($this, 'failover')
);
}

if ($res) {
$this->_servers[] = $this->_params['hostspec'][$i] . (!empty($this->_params['port'][$i]) ? ':' . $this->_params['port'][$i] : '');
Expand All @@ -158,13 +198,6 @@ public function _init()
throw new Horde_Memcache_Exception('Could not connect to any defined memcache servers.');
}

if (!empty($this->_params['c_threshold'])) {
$this->_memcache->setCompressThreshold($this->_params['c_threshold']);
}

// Force consistent hashing
ini_set('memcache.hash_strategy', 'consistent');

if (isset($this->_params['logger'])) {
$this->_logger = $this->_params['logger'];
$this->_logger->log('Connected to the following memcache servers:' . implode($this->_servers, ', '), 'DEBUG');
Expand Down Expand Up @@ -224,7 +257,12 @@ public function get($keys)
$key_map[$v] = $this->_key($v);
}

if (($res = $this->_memcache->get(array_values($key_map), $flags)) === false) {
if ($this->_memcache instanceof Memcached) {
$res = $this->_memcache->getMulti(array_values($key_map));
} else {
$res = $this->_memcache->get(array_values($key_map), $flags);
}
if ($res === false) {
return false;
}

Expand Down Expand Up @@ -334,9 +372,14 @@ protected function _set($key, $var, $expire = 0, $len = null)

for ($i = 0; ($i * self::MAX_SIZE) < $len; ++$i) {
$curr_key = $i ? ($key . '_s' . $i) : $key;

$flags = $this->_getFlags($i ? 0 : ceil($len / self::MAX_SIZE));
$res = $this->_memcache->set($this->_key($curr_key), substr($var, $i * self::MAX_SIZE, self::MAX_SIZE), $flags, $expire);
$res = $this->_memcache instanceof Memcached
? $this->_memcache->set($curr_key, $var, $expire)
: $this->_memcache->set(
$this->_key($curr_key),
substr($var, $i * self::MAX_SIZE, self::MAX_SIZE),
$this->_getFlags($i ? 0 : ceil($len / self::MAX_SIZE)),
$expire
);
if ($res === false) {
$this->delete($key);
break;
Expand Down Expand Up @@ -371,7 +414,11 @@ public function replace($key, $var, $expire = 0)
return false;
}

return $this->_memcache->replace($this->_key($key), $var, $this->_getFlags(1), $expire);
return $this->_memcache instanceof Memcached
? $this->_memcache->replace($key, $var, $expire)
: $this->_memcache->replace(
$this->_key($key), $var, $this->_getFlags(1), $expire
);
}

/**
Expand All @@ -383,7 +430,7 @@ public function lock($key)
{
$i = 0;

while ($this->_memcache->add($this->_key($key . self::LOCK_SUFFIX), 1, 0, self::LOCK_TIMEOUT) === false) {
while ($this->_memcache->add($this->_key($key . self::LOCK_SUFFIX), 1, self::LOCK_TIMEOUT) === false) {
usleep(min(pow(2, $i++) * 10000, 100000));
}

Expand Down Expand Up @@ -435,7 +482,9 @@ public function flush()
*/
public function stats()
{
return $this->_memcache->getExtendedStats();
return $this->_memcache instanceof Memcached
? $this->_memcache->getStats()
: $this->_memcache->getExtendedStats();
}

/**
Expand Down Expand Up @@ -468,7 +517,9 @@ public function failover($host, $port)
*/
protected function _key($key)
{
return hash('md5', $this->_params['prefix'] . $key);
return $this->_memcache instanceof Memcached
? $key
: hash('md5', $this->_params['prefix'] . $key);
}

/**
Expand Down
31 changes: 19 additions & 12 deletions framework/Memcache/package.xml
Expand Up @@ -10,9 +10,9 @@
<email>slusarz@horde.org</email>
<active>yes</active>
</lead>
<date>2014-12-01</date>
<date>2016-07-01</date>
<version>
<release>2.0.8</release>
<release>2.1.0</release>
<api>1.1.0</api>
</version>
<stability>
Expand All @@ -21,7 +21,7 @@
</stability>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
*
* [jan] Add support for memcached extension and PHP 7.
</notes>
<contents>
<dir baseinstalldir="/" name="/">
Expand All @@ -46,8 +46,8 @@
<required>
<php>
<min>5.3.0</min>
<max>6.0.0alpha1</max>
<exclude>6.0.0alpha1</exclude>
<max>8.0.0alpha1</max>
<exclude>8.0.0alpha1</exclude>
</php>
<pearinstaller>
<min>1.7.0</min>
Expand All @@ -59,16 +59,23 @@
<max>3.0.0alpha1</max>
<exclude>3.0.0alpha1</exclude>
</package>
<extension>
<name>hash</name>
</extension>
</required>
<optional>
<package>
<name>memcache</name>
<channel>pecl.php.net</channel>
<min>2.0.0</min>
<providesextension>memcache</providesextension>
</package>
<extension>
<name>hash</name>
</extension>
</required>
<package>
<name>memcached</name>
<channel>pecl.php.net</channel>
<providesextension>memcached</providesextension>
</package>
</optional>
</dependencies>
<phprelease>
<filelist>
Expand Down Expand Up @@ -379,15 +386,15 @@
</release>
<release>
<version>
<release>2.0.8</release>
<release>2.1.0</release>
<api>1.1.0</api></version>
<stability>
<release>stable</release>
<api>stable</api></stability>
<date>2014-12-01</date>
<date>2016-07-01</date>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
*
* [jan] Add support for memcached extension and PHP 7.
</notes>
</release>
</changelog>
Expand Down

0 comments on commit 7e5502b

Please sign in to comment.