37
37
#endif
38
38
#include <zlib.h>
39
39
40
+ #ifdef HAVE_ZSTD_H
41
+ #include <zstd.h>
42
+ #endif
43
+
40
44
#ifdef HAVE_JSON_API
41
45
# include "ext/json/php_json.h"
42
46
#endif
@@ -77,6 +81,7 @@ static int php_memc_list_entry(void) {
77
81
#define MEMC_OPT_COMPRESSION_TYPE -1004
78
82
#define MEMC_OPT_STORE_RETRY_COUNT -1005
79
83
#define MEMC_OPT_USER_FLAGS -1006
84
+ #define MEMC_OPT_COMPRESSION_LEVEL -1007
80
85
81
86
/****************************************
82
87
Custom result codes
@@ -107,6 +112,7 @@ static int php_memc_list_entry(void) {
107
112
#define MEMC_VAL_COMPRESSED (1<<0)
108
113
#define MEMC_VAL_COMPRESSION_ZLIB (1<<1)
109
114
#define MEMC_VAL_COMPRESSION_FASTLZ (1<<2)
115
+ #define MEMC_VAL_COMPRESSION_ZSTD (1<<3)
110
116
111
117
#define MEMC_VAL_GET_FLAGS (internal_flags ) (((internal_flags) & MEMC_MASK_INTERNAL) >> 4)
112
118
#define MEMC_VAL_SET_FLAG (internal_flags , internal_flag ) ((internal_flags) |= (((internal_flag) << 4) & MEMC_MASK_INTERNAL))
@@ -152,6 +158,7 @@ typedef struct {
152
158
153
159
zend_long serializer ;
154
160
zend_long compression_type ;
161
+ zend_long compression_level ;
155
162
156
163
zend_long store_retry_count ;
157
164
zend_long set_udf_flags ;
@@ -278,6 +285,10 @@ static PHP_INI_MH(OnUpdateCompressionType)
278
285
MEMC_G (compression_type ) = COMPRESSION_TYPE_FASTLZ ;
279
286
} else if (!strcmp (ZSTR_VAL (new_value ), "zlib" )) {
280
287
MEMC_G (compression_type ) = COMPRESSION_TYPE_ZLIB ;
288
+ #ifdef HAVE_ZSTD_H
289
+ } else if (!strcmp (ZSTR_VAL (new_value ), "zstd" )) {
290
+ MEMC_G (compression_type ) = COMPRESSION_TYPE_ZSTD ;
291
+ #endif
281
292
} else {
282
293
return FAILURE ;
283
294
}
@@ -408,6 +419,7 @@ PHP_INI_BEGIN()
408
419
409
420
MEMC_INI_ENTRY ("compression_type" , "fastlz" , OnUpdateCompressionType , compression_name )
410
421
MEMC_INI_ENTRY ("compression_factor" , "1.3" , OnUpdateReal , compression_factor )
422
+ MEMC_INI_ENTRY ("compression_level" , "3" , OnUpdateLong , compression_level )
411
423
MEMC_INI_ENTRY ("compression_threshold" , "2000" , OnUpdateLong , compression_threshold )
412
424
MEMC_INI_ENTRY ("serializer" , SERIALIZER_DEFAULT_NAME , OnUpdateSerializer , serializer_name )
413
425
MEMC_INI_ENTRY ("store_retry_count" , "0" , OnUpdateLong , store_retry_count )
@@ -897,6 +909,19 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
897
909
}
898
910
break ;
899
911
912
+ #ifdef HAVE_ZSTD_H
913
+ case COMPRESSION_TYPE_ZSTD :
914
+ {
915
+ compressed_size = ZSTD_compress ((void * )buffer , buffer_size , ZSTR_VAL (payload ), ZSTR_LEN (payload ), MEMC_G (compression_level ));
916
+
917
+ if (!ZSTD_isError (compressed_size )) {
918
+ compress_status = 1 ;
919
+ compression_type_flag = MEMC_VAL_COMPRESSION_ZSTD ;
920
+ }
921
+ }
922
+ break ;
923
+ #endif
924
+
900
925
case COMPRESSION_TYPE_ZLIB :
901
926
{
902
927
compressed_size = buffer_size ;
@@ -2939,6 +2964,9 @@ static PHP_METHOD(Memcached, getOption)
2939
2964
case MEMC_OPT_COMPRESSION_TYPE :
2940
2965
RETURN_LONG (memc_user_data -> compression_type );
2941
2966
2967
+ case MEMC_OPT_COMPRESSION_LEVEL :
2968
+ RETURN_LONG (memc_user_data -> compression_level );
2969
+
2942
2970
case MEMC_OPT_COMPRESSION :
2943
2971
RETURN_BOOL (memc_user_data -> compression_enabled );
2944
2972
@@ -3001,6 +3029,9 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value)
3001
3029
case MEMC_OPT_COMPRESSION_TYPE :
3002
3030
lval = zval_get_long (value );
3003
3031
if (lval == COMPRESSION_TYPE_FASTLZ ||
3032
+ #ifdef HAVE_ZSTD_H
3033
+ lval == COMPRESSION_TYPE_ZSTD ||
3034
+ #endif
3004
3035
lval == COMPRESSION_TYPE_ZLIB ) {
3005
3036
memc_user_data -> compression_type = lval ;
3006
3037
} else {
@@ -3608,16 +3639,24 @@ zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32
3608
3639
uint32_t stored_length ;
3609
3640
unsigned long length ;
3610
3641
zend_bool decompress_status = 0 ;
3611
- zend_bool is_fastlz = 0 , is_zlib = 0 ;
3642
+ zend_bool is_fastlz = 0 , is_zlib = 0 , is_zstd = 0 ;
3612
3643
3613
3644
if (payload_len < sizeof (uint32_t )) {
3614
3645
return NULL ;
3615
3646
}
3616
3647
3617
3648
is_fastlz = MEMC_VAL_HAS_FLAG (flags , MEMC_VAL_COMPRESSION_FASTLZ );
3649
+ is_zstd = MEMC_VAL_HAS_FLAG (flags , MEMC_VAL_COMPRESSION_ZSTD );
3618
3650
is_zlib = MEMC_VAL_HAS_FLAG (flags , MEMC_VAL_COMPRESSION_ZLIB );
3619
3651
3620
- if (!is_fastlz && !is_zlib ) {
3652
+ #ifndef HAVE_ZSTD_H
3653
+ if (is_zstd ) {
3654
+ php_error_docref (NULL , E_WARNING , "could not decompress value: value was compressed with zstd but zstd support has not been compiled in" );
3655
+ return NULL ;
3656
+ }
3657
+ #endif
3658
+
3659
+ if (!is_fastlz && !is_zlib && !is_zstd ) {
3621
3660
php_error_docref (NULL , E_WARNING , "could not decompress value: unrecognised compression type" );
3622
3661
return NULL ;
3623
3662
}
@@ -3629,6 +3668,23 @@ zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32
3629
3668
3630
3669
buffer = zend_string_alloc (stored_length , 0 );
3631
3670
3671
+ #ifdef HAVE_ZSTD_H
3672
+ if (is_zstd ) {
3673
+ length = ZSTD_getFrameContentSize (payload , payload_len );
3674
+ if (length == ZSTD_CONTENTSIZE_ERROR ) {
3675
+ php_error_docref (NULL , E_WARNING , "value was not compressed by zstd" );
3676
+ zend_string_release (buffer );
3677
+ return NULL ;
3678
+ } else if (length == ZSTD_CONTENTSIZE_UNKNOWN ) {
3679
+ php_error_docref (NULL , E_WARNING , "zstd streaming decompression not supported" );
3680
+ zend_string_release (buffer );
3681
+ return NULL ;
3682
+ }
3683
+ decompress_status = !ZSTD_isError (ZSTD_decompress (& buffer -> val , buffer -> len , payload , payload_len ));
3684
+
3685
+ }
3686
+ else
3687
+ #endif
3632
3688
if (is_fastlz ) {
3633
3689
decompress_status = ((length = fastlz_decompress (payload , payload_len , & buffer -> val , buffer -> len )) > 0 );
3634
3690
}
@@ -3955,6 +4011,7 @@ PHP_GINIT_FUNCTION(php_memcached)
3955
4011
php_memcached_globals -> memc .compression_threshold = 2000 ;
3956
4012
php_memcached_globals -> memc .compression_type = COMPRESSION_TYPE_FASTLZ ;
3957
4013
php_memcached_globals -> memc .compression_factor = 1.30 ;
4014
+ php_memcached_globals -> memc .compression_level = 3 ;
3958
4015
php_memcached_globals -> memc .store_retry_count = 2 ;
3959
4016
3960
4017
php_memcached_globals -> memc .sasl_initialised = 0 ;
@@ -4000,6 +4057,7 @@ static void php_memc_register_constants(INIT_FUNC_ARGS)
4000
4057
4001
4058
REGISTER_MEMC_CLASS_CONST_LONG (OPT_COMPRESSION , MEMC_OPT_COMPRESSION );
4002
4059
REGISTER_MEMC_CLASS_CONST_LONG (OPT_COMPRESSION_TYPE , MEMC_OPT_COMPRESSION_TYPE );
4060
+ REGISTER_MEMC_CLASS_CONST_LONG (OPT_COMPRESSION_LEVEL , MEMC_OPT_COMPRESSION_LEVEL );
4003
4061
REGISTER_MEMC_CLASS_CONST_LONG (OPT_PREFIX_KEY , MEMC_OPT_PREFIX_KEY );
4004
4062
REGISTER_MEMC_CLASS_CONST_LONG (OPT_SERIALIZER , MEMC_OPT_SERIALIZER );
4005
4063
@@ -4015,6 +4073,15 @@ static void php_memc_register_constants(INIT_FUNC_ARGS)
4015
4073
REGISTER_MEMC_CLASS_CONST_BOOL (HAVE_IGBINARY , 0 );
4016
4074
#endif
4017
4075
4076
+ /*
4077
+ * Indicate whether zstd compression is available
4078
+ */
4079
+ #ifdef HAVE_ZSTD_H
4080
+ REGISTER_MEMC_CLASS_CONST_BOOL (HAVE_ZSTD , 1 );
4081
+ #else
4082
+ REGISTER_MEMC_CLASS_CONST_BOOL (HAVE_ZSTD , 0 );
4083
+ #endif
4084
+
4018
4085
/*
4019
4086
* Indicate whether json serializer is available
4020
4087
*/
@@ -4186,6 +4253,7 @@ static void php_memc_register_constants(INIT_FUNC_ARGS)
4186
4253
*/
4187
4254
REGISTER_MEMC_CLASS_CONST_LONG (COMPRESSION_FASTLZ , COMPRESSION_TYPE_FASTLZ );
4188
4255
REGISTER_MEMC_CLASS_CONST_LONG (COMPRESSION_ZLIB , COMPRESSION_TYPE_ZLIB );
4256
+ REGISTER_MEMC_CLASS_CONST_LONG (COMPRESSION_ZSTD , COMPRESSION_TYPE_ZSTD );
4189
4257
4190
4258
/*
4191
4259
* Flags.
@@ -4351,6 +4419,12 @@ PHP_MINFO_FUNCTION(memcached)
4351
4419
php_info_print_table_row (2 , "msgpack support" , "no" );
4352
4420
#endif
4353
4421
4422
+ #ifdef HAVE_ZSTD_H
4423
+ php_info_print_table_row (2 , "zstd support" , "yes" );
4424
+ #else
4425
+ php_info_print_table_row (2 , "zstd support" , "no" );
4426
+ #endif
4427
+
4354
4428
php_info_print_table_end ();
4355
4429
4356
4430
DISPLAY_INI_ENTRIES ();
0 commit comments