diff --git a/README.txt b/README.txt index 1d6555b1026bca6d3dd19313c9ef83d9dbfd163b..4f520ab36b5b84ccc0216b239d9b9c1a4e1c2952 100644 --- a/README.txt +++ b/README.txt @@ -225,6 +225,17 @@ array of settings.php: $conf['memcache_key_prefix'] = 'something_unique'; +Note: if the length of your prefix + key + bin combine to be more than 250 +characters, they will be automatically hashed. Memcache only supports key +lengths up to 250 bytes. You can optionally configure the hashing algorithm +used, however sha1 was selected as the default because it performs quickly with +minimal collisions. + +$conf['memcache_key_hash_algorithm'] = 'sha1'; + +Visit http://www.php.net/manual/en/function.hash-algos.php to learn more about +which hash algorithms are available. + ## MULTIPLE SERVERS ## To use this module with multiple memcached servers, it is important that you set diff --git a/dmemcache.inc b/dmemcache.inc index be252ef09284449286a1cb7bad86e0c7343a529c..40e9db6b4c113ca29549b0704ea0f86c16da627e 100644 --- a/dmemcache.inc +++ b/dmemcache.inc @@ -452,10 +452,11 @@ function dmemcache_key($key, $bin = 'cache') { $full_key = urlencode($prefix . $bin . '-' . $key); // Memcache only supports key lengths up to 250 bytes. If we have generated - // a longer key, hash it with sha1 which will shrink the key down to 40 bytes - // while still keeping it unique. + // a longer key, we shrink it to an acceptible length with a configurable + // hashing algorithm. Sha1 was selected as the default as it performs + // quickly with minimal collisions. if (strlen($full_key) > 250) { - $full_key = $prefix . $bin . '-' . sha1($key); + $full_key = urlencode(hash(variable_get('memcache_key_hash_algorithm', 'sha1'), $prefix . $bin . '-' . $key)); } return $full_key; diff --git a/tests/memcache.test b/tests/memcache.test index 6cce36582bf7b98d6731fb48f5598037d178b57c..11f0e4c1725eebaa81e1388fba72b70aace16ea3 100644 --- a/tests/memcache.test +++ b/tests/memcache.test @@ -158,13 +158,27 @@ class MemCacheSavingCase extends MemcacheTestCase { $this->assertTrue(isset($cache->data) && $cache->data == $test_object, t('Object is saved and restored properly.')); } + /** + * Test save and restoring a string with a long key. + */ + function testStringLongKey() { + $this->checkVariable($this->randomName(100), 'ThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydog'); + } + + /** + * Test save and restoring a string using a key with special characters. + */ + function testStringSpecialKey() { + $this->checkVariable($this->randomName(100), 'Qwerty!@#$%^&*()_+-=[]\;\',./<>?:"{}|£¢'); + } + /* * Check or a variable is stored and restored properly. **/ - function checkVariable($var) { - cache_set('test_var', $var, 'cache'); - $cache = cache_get('test_var', 'cache'); - $this->assertTrue(isset($cache->data) && $cache->data === $var, t('@type is saved and restored properly.', array('@type' => ucfirst(gettype($var))))); + function checkVariable($var, $key = 'test_var') { + cache_set($key, $var, 'cache'); + $cache = cache_get($key, 'cache'); + $this->assertTrue(isset($cache->data) && $cache->data === $var, t('@type is saved and restored properly!key.', array('@type' => ucfirst(gettype($var)), '!key' => ($key != 'test_var') ? t(' with key @key', array('@key' => $key)) : ''))); } }