Created
April 25, 2023 04:13
-
-
Save rlerdorf/b0e06c139bc7e1f7dd93b9da6a9c8160 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/php_memcached.c b/php_memcached.c | |
index 8e4fa41..252f0c1 100644 | |
--- a/php_memcached.c | |
+++ b/php_memcached.c | |
@@ -37,6 +37,8 @@ | |
#endif | |
#include <zlib.h> | |
+#include <zstd.h> | |
+ | |
#ifdef HAVE_JSON_API | |
# include "ext/json/php_json.h" | |
#endif | |
@@ -107,6 +109,7 @@ static int php_memc_list_entry(void) { | |
#define MEMC_VAL_COMPRESSED (1<<0) | |
#define MEMC_VAL_COMPRESSION_ZLIB (1<<1) | |
#define MEMC_VAL_COMPRESSION_FASTLZ (1<<2) | |
+#define MEMC_VAL_COMPRESSION_ZSTD (1<<3) | |
#define MEMC_VAL_GET_FLAGS(internal_flags) (((internal_flags) & MEMC_MASK_INTERNAL) >> 4) | |
#define MEMC_VAL_SET_FLAG(internal_flags, internal_flag) ((internal_flags) |= (((internal_flag) << 4) & MEMC_MASK_INTERNAL)) | |
@@ -278,6 +281,8 @@ static PHP_INI_MH(OnUpdateCompressionType) | |
MEMC_G(compression_type) = COMPRESSION_TYPE_FASTLZ; | |
} else if (!strcmp(ZSTR_VAL(new_value), "zlib")) { | |
MEMC_G(compression_type) = COMPRESSION_TYPE_ZLIB; | |
+ } else if (!strcmp(ZSTR_VAL(new_value), "zstd")) { | |
+ MEMC_G(compression_type) = COMPRESSION_TYPE_ZSTD; | |
} else { | |
return FAILURE; | |
} | |
@@ -897,6 +902,17 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str | |
} | |
break; | |
+ case COMPRESSION_TYPE_ZSTD: | |
+ { | |
+ compressed_size = ZSTD_compress((void *)buffer, buffer_size, ZSTR_VAL(payload), ZSTR_LEN(payload), 3); | |
+ | |
+ if (!ZSTD_isError(compressed_size)) { | |
+ compress_status = 1; | |
+ compression_type_flag = MEMC_VAL_COMPRESSION_ZSTD; | |
+ } | |
+ } | |
+ break; | |
+ | |
case COMPRESSION_TYPE_ZLIB: | |
{ | |
compressed_size = buffer_size; | |
@@ -3002,6 +3018,7 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) | |
case MEMC_OPT_COMPRESSION_TYPE: | |
lval = zval_get_long(value); | |
if (lval == COMPRESSION_TYPE_FASTLZ || | |
+ lval == COMPRESSION_TYPE_ZSTD || | |
lval == COMPRESSION_TYPE_ZLIB) { | |
memc_user_data->compression_type = lval; | |
} else { | |
@@ -3606,16 +3623,17 @@ zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32 | |
uint32_t stored_length; | |
unsigned long length; | |
zend_bool decompress_status = 0; | |
- zend_bool is_fastlz = 0, is_zlib = 0; | |
+ zend_bool is_fastlz = 0, is_zlib = 0, is_zstd = 0; | |
if (payload_len < sizeof (uint32_t)) { | |
return NULL; | |
} | |
is_fastlz = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_FASTLZ); | |
+ is_zstd = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_ZSTD); | |
is_zlib = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_ZLIB); | |
- if (!is_fastlz && !is_zlib) { | |
+ if (!is_fastlz && !is_zlib && !is_zstd) { | |
php_error_docref(NULL, E_WARNING, "could not decompress value: unrecognised compression type"); | |
return NULL; | |
} | |
@@ -3627,7 +3645,21 @@ zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32 | |
buffer = zend_string_alloc (stored_length, 0); | |
- if (is_fastlz) { | |
+ if (is_zstd) { | |
+ length = ZSTD_getFrameContentSize(payload, payload_len); | |
+ if (length == ZSTD_CONTENTSIZE_ERROR) { | |
+ php_error_docref(NULL, E_WARNING, "value was not compressed by zstd"); | |
+ zend_string_release (buffer); | |
+ return NULL; | |
+ } else if (length == ZSTD_CONTENTSIZE_UNKNOWN) { | |
+ php_error_docref(NULL, E_WARNING, "zstd streaming decompression not supported"); | |
+ zend_string_release (buffer); | |
+ return NULL; | |
+ } | |
+ decompress_status = !ZSTD_isError(ZSTD_decompress(&buffer->val, buffer->len, payload, payload_len)); | |
+ | |
+ } | |
+ else if (is_fastlz) { | |
decompress_status = ((length = fastlz_decompress(payload, payload_len, &buffer->val, buffer->len)) > 0); | |
} | |
else if (is_zlib) { | |
@@ -4180,6 +4212,7 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) | |
*/ | |
REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_FASTLZ, COMPRESSION_TYPE_FASTLZ); | |
REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_ZLIB, COMPRESSION_TYPE_ZLIB); | |
+ REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_ZSTD, COMPRESSION_TYPE_ZSTD); | |
/* | |
* Flags. | |
diff --git a/php_memcached_private.h b/php_memcached_private.h | |
index 3e1f358..ae74dbc 100644 | |
--- a/php_memcached_private.h | |
+++ b/php_memcached_private.h | |
@@ -94,7 +94,8 @@ typedef enum { | |
typedef enum { | |
COMPRESSION_TYPE_ZLIB = 1, | |
- COMPRESSION_TYPE_FASTLZ = 2 | |
+ COMPRESSION_TYPE_FASTLZ = 2, | |
+ COMPRESSION_TYPE_ZSTD = 3 | |
} php_memc_compression_type; | |
typedef struct { | |
diff --git a/tests/compression_conditions.phpt b/tests/compression_conditions.phpt | |
index 749ebe8..960058b 100644 | |
--- a/tests/compression_conditions.phpt | |
+++ b/tests/compression_conditions.phpt | |
@@ -21,6 +21,8 @@ function get_compression($name) { | |
return Memcached::COMPRESSION_ZLIB; | |
case 'fastlz': | |
return Memcached::COMPRESSION_FASTLZ; | |
+ case 'zstd': | |
+ return Memcached::COMPRESSION_ZSTD; | |
default: | |
echo "Strange compression type: $name\n"; | |
return 0; | |
diff --git a/tests/compression_types.phpt b/tests/compression_types.phpt | |
index ce07aed..809dbb1 100644 | |
--- a/tests/compression_types.phpt | |
+++ b/tests/compression_types.phpt | |
@@ -15,6 +15,8 @@ function get_compression($name) { | |
return Memcached::COMPRESSION_ZLIB; | |
case 'fastlz': | |
return Memcached::COMPRESSION_FASTLZ; | |
+ case 'zstd': | |
+ return Memcached::COMPRESSION_ZSTD; | |
default: | |
echo "Strange compression type: $name\n"; | |
return 0; | |
@@ -54,6 +56,11 @@ fetch_with_compression($m, 'hello6', $data, '', 'fastlz'); | |
fetch_with_compression($m, 'hello7', $data, 'zlib', ''); | |
fetch_with_compression($m, 'hello8', $data, 'fastlz', ''); | |
fetch_with_compression($m, 'hello9', $data, '', ''); | |
+fetch_with_compression($m, 'hello10', $data, 'zstd', 'zstd'); | |
+fetch_with_compression($m, 'hello11', $data, 'zstd', 'fastlz'); | |
+fetch_with_compression($m, 'hello12', $data, 'fastlz', 'zstd'); | |
+fetch_with_compression($m, 'hello13', $data, '', 'zstd'); | |
+fetch_with_compression($m, 'hello14', $data, 'zstd', ''); | |
?> | |
--EXPECT-- | |
set=[zlib] get=[zlib] | |
@@ -74,3 +81,13 @@ set=[fastlz] get=[] | |
bool(true) | |
set=[] get=[] | |
bool(true) | |
+set=[zstd] get=[zstd] | |
+bool(true) | |
+set=[zstd] get=[fastlz] | |
+bool(true) | |
+set=[fastlz] get=[zstd] | |
+bool(true) | |
+set=[] get=[zstd] | |
+bool(true) | |
+set=[zstd] get=[] | |
+bool(true) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment