Skip to content

Commit

Permalink
MDL-66428 cachestore_redis: add Zstd compression support
Browse files Browse the repository at this point in the history
  • Loading branch information
mdjnelson committed Oct 7, 2019
1 parent 493295e commit de0b6d9
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
1 change: 1 addition & 0 deletions cache/stores/redis/lang/en/cachestore_redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

$string['compressor_none'] = 'No compression.';
$string['compressor_php_gzip'] = 'Use gzip compression.';
$string['compressor_php_zstd'] = 'Use Zstandard compression.';
$string['pluginname'] = 'Redis';
$string['prefix'] = 'Key prefix';
$string['prefix_help'] = 'This prefix is used for all key names on the Redis server.
Expand Down
20 changes: 19 additions & 1 deletion cache/stores/redis/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_
*/
const COMPRESSOR_PHP_GZIP = 1;

/**
* Compressor: PHP Zstandard.
*/
const COMPRESSOR_PHP_ZSTD = 2;

/**
* Name of this store.
*
Expand Down Expand Up @@ -597,10 +602,17 @@ public static function config_get_serializer_options() {
* @return array
*/
public static function config_get_compressor_options() {
return [
$arr = [
self::COMPRESSOR_NONE => get_string('compressor_none', 'cachestore_redis'),
self::COMPRESSOR_PHP_GZIP => get_string('compressor_php_gzip', 'cachestore_redis'),
];

// Check if the Zstandard PHP extension is installed.
if (extension_loaded('zstd')) {
$arr[self::COMPRESSOR_PHP_ZSTD] = get_string('compressor_php_zstd', 'cachestore_redis');
}

return $arr;
}

/**
Expand All @@ -619,6 +631,9 @@ private function compress($value) {
case self::COMPRESSOR_PHP_GZIP:
return gzencode($value);

case self::COMPRESSOR_PHP_ZSTD:
return zstd_compress($value);

default:
debugging("Invalid compressor: {$this->compressor}");
return $value;
Expand All @@ -642,6 +657,9 @@ private function uncompress($value) {
case self::COMPRESSOR_PHP_GZIP:
$value = gzdecode($value);
break;
case self::COMPRESSOR_PHP_ZSTD:
$value = zstd_uncompress($value);
break;
default:
debugging("Invalid compressor: {$this->compressor}");
}
Expand Down
37 changes: 29 additions & 8 deletions cache/stores/redis/tests/compressor_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,11 @@ public function test_it_works_with_different_types_for_many() {
}

/**
* Provider for serializer tests.
* Provider for set/get combination tests.
*
* @return array
*/
public function provider_for_test_it_can_use_serializers() {
public function provider_for_tests_setget() {
$data = [
['none, none',
Redis::SERIALIZER_NONE, cachestore_redis::COMPRESSOR_NONE,
Expand Down Expand Up @@ -199,20 +199,41 @@ public function provider_for_test_it_can_use_serializers() {
];
}

if (extension_loaded('zstd')) {
$data[] = [
'none, zstd',
Redis::SERIALIZER_NONE, cachestore_redis::COMPRESSOR_PHP_ZSTD,
zstd_compress('value1'), zstd_compress('value2'),
];
$data[] = [
'php, zstd',
Redis::SERIALIZER_PHP, cachestore_redis::COMPRESSOR_PHP_ZSTD,
zstd_compress(serialize('value1')), zstd_compress(serialize('value2')),
];

if (defined('Redis::SERIALIZER_IGBINARY')) {
$data[] = [
'igbinary, zstd',
Redis::SERIALIZER_IGBINARY, cachestore_redis::COMPRESSOR_PHP_ZSTD,
zstd_compress(igbinary_serialize('value1')), zstd_compress(igbinary_serialize('value2')),
];
}
}

return $data;
}

/**
* Test it can use serializers with get and set.
* Test we can use get and set with all combinations.
*
* @dataProvider provider_for_test_it_can_use_serializers
* @dataProvider provider_for_tests_setget
* @param string $name
* @param int $serializer
* @param int $compressor
* @param string $rawexpected1
* @param string $rawexpected2
*/
public function test_it_can_use_serializers_getset($name, $serializer, $compressor, $rawexpected1, $rawexpected2) {
public function test_it_can_use_getset($name, $serializer, $compressor, $rawexpected1, $rawexpected2) {
// Create a connection with the desired serialisation.
$store = $this->create_store($compressor, $serializer);
$store->set('key', 'value1');
Expand All @@ -227,16 +248,16 @@ public function test_it_can_use_serializers_getset($name, $serializer, $compress
}

/**
* Test it can use serializers with get and set many.
* Test we can use get and set many with all combinations.
*
* @dataProvider provider_for_test_it_can_use_serializers
* @dataProvider provider_for_tests_setget
* @param string $name
* @param int $serializer
* @param int $compressor
* @param string $rawexpected1
* @param string $rawexpected2
*/
public function test_it_can_use_serializers_getsetmany($name, $serializer, $compressor, $rawexpected1, $rawexpected2) {
public function test_it_can_use_getsetmany($name, $serializer, $compressor, $rawexpected1, $rawexpected2) {
$many = [
['key' => 'key1', 'value' => 'value1'],
['key' => 'key2', 'value' => 'value2'],
Expand Down
3 changes: 3 additions & 0 deletions cache/upgrade.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
This files describes API changes in /cache/stores/* - cache store plugins.
Information provided here is intended especially for developers.

=== 3.8 ===
* The Redis cache store can now make use of the Zstandard compression algorithm (see MDL-66428).

=== 3.7 ===
* Upgraded MongoDB cache store to use the new lower level PHP-driver and MongoDB PHP Library.
* The mongodb extension has replaced the old mongo extension. The mongodb pecl extension >= 1.5 must be installed to use MongoDB
Expand Down

0 comments on commit de0b6d9

Please sign in to comment.