Skip to content

Commit 6ee6166

Browse files
authored
Merge pull request php-memcached-dev#303 from sodabrew/compression_conditions
Compression conditions adjustments
2 parents 8924e3d + c85f34c commit 6ee6166

File tree

3 files changed

+151
-26
lines changed

3 files changed

+151
-26
lines changed

package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ Tests
9494
<file role='test' name='check_if_persistent.phpt'/>
9595
<file role='test' name='check_if_pristine.phpt'/>
9696
<file role='test' name='clone.phpt'/>
97+
<file role='test' name='compression_conditions.phpt'/>
9798
<file role='test' name='compression_types.phpt'/>
9899
<file role='test' name='conf_persist.phpt'/>
99100
<file role='test' name='construct.phpt'/>

php_memcached.c

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
830830
/* status */
831831
zend_bool compress_status = 0;
832832
zend_string *payload = *payload_in;
833+
uint32_t compression_type_flag = 0;
833834

834835
/* Additional 5% for the data */
835836
size_t buffer_size = (size_t) (((double) ZSTR_LEN(payload) * 1.05) + 1.0);
@@ -847,7 +848,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
847848

848849
if (compressed_size > 0) {
849850
compress_status = 1;
850-
MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSION_FASTLZ);
851+
compression_type_flag = MEMC_VAL_COMPRESSION_FASTLZ;
851852
}
852853
}
853854
break;
@@ -859,7 +860,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
859860

860861
if (status == Z_OK) {
861862
compress_status = 1;
862-
MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSION_ZLIB);
863+
compression_type_flag = MEMC_VAL_COMPRESSION_ZLIB;
863864
}
864865
}
865866
break;
@@ -869,31 +870,29 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
869870
break;
870871
}
871872

872-
if (!compress_status) {
873-
php_error_docref(NULL, E_WARNING, "could not compress value");
874-
efree (buffer);
875-
return 0;
876-
}
877-
878-
/* This means the value was too small to be compressed, still a success */
873+
/* This means the value was too small to be compressed and ended up larger */
879874
if (ZSTR_LEN(payload) <= (compressed_size * MEMC_G(compression_factor))) {
880-
MEMC_VAL_DEL_FLAG(*flags, MEMC_VAL_COMPRESSION_FASTLZ | MEMC_VAL_COMPRESSION_ZLIB);
881-
efree (buffer);
882-
return 1;
875+
compress_status = 0;
883876
}
884877

885-
MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED);
878+
/* Replace the payload with the compressed copy */
879+
if (compress_status) {
880+
MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED | compression_type_flag);
881+
payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0);
886882

887-
payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0);
883+
/* Copy the uin32_t at the beginning */
884+
memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t));
885+
memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size);
886+
efree(buffer);
888887

889-
/* Copy the uin32_t at the beginning */
890-
memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t));
891-
memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size);
892-
efree(buffer);
888+
zend_string_forget_hash_val(payload);
889+
*payload_in = payload;
893890

894-
zend_string_forget_hash_val(payload);
895-
*payload_in = payload;
896-
return 1;
891+
return 1;
892+
}
893+
894+
/* Original payload was not modified */
895+
return 0;
897896
}
898897

899898
static
@@ -1043,11 +1042,13 @@ zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t
10431042

10441043
/* If we have compression flag, compress the value */
10451044
if (should_compress) {
1046-
/* status */
1047-
if (!s_compress_value (memc_user_data->compression_type, &payload, flags)) {
1048-
zend_string_release(payload);
1049-
return NULL;
1050-
}
1045+
/* s_compress_value() will always leave a valid payload, even if that payload
1046+
* did not actually get compressed. The flags will be set according to the
1047+
* to the compression type or no compression.
1048+
*
1049+
* No need to check the return value because the payload is always valid.
1050+
*/
1051+
(void)s_compress_value (memc_user_data->compression_type, &payload, flags);
10511052
}
10521053

10531054
if (memc_user_data->set_udf_flags >= 0) {

tests/compression_conditions.phpt

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
--TEST--
2+
Memcached compression test
3+
--SKIPIF--
4+
<?php if (!extension_loaded("memcached")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
include dirname (__FILE__) . '/config.inc';
8+
$m = memc_get_instance ();
9+
10+
$short_data = "abcdefg";
11+
$data = file_get_contents(dirname(__FILE__) . '/testdata.res');
12+
13+
set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
14+
echo "$errstr\n";
15+
return true;
16+
}, E_WARNING);
17+
18+
function get_compression($name) {
19+
switch (strtolower($name)) {
20+
case 'zlib':
21+
return Memcached::COMPRESSION_ZLIB;
22+
case 'fastlz':
23+
return Memcached::COMPRESSION_FASTLZ;
24+
default:
25+
echo "Strange compression type: $name\n";
26+
return 0;
27+
}
28+
}
29+
30+
function fetch_with_compression($m, $key, $value, $set_compression = '', $factor = 1.3, $threshold = 2000) {
31+
ini_set("memcached.compression_factor", $factor);
32+
ini_set("memcached.compression_threshold", $threshold);
33+
34+
$len=strlen($value);
35+
echo "len=[$len] set=[$set_compression] factor=[$factor] threshold=[$threshold]\n";
36+
37+
if (!$set_compression) {
38+
$m->setOption(Memcached::OPT_COMPRESSION, false);
39+
} else {
40+
$m->setOption(Memcached::OPT_COMPRESSION, true);
41+
$m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($set_compression));
42+
}
43+
44+
$m->set($key, $value, 1800);
45+
46+
$value_back = $m->get($key);
47+
var_dump($value === $value_back);
48+
}
49+
50+
fetch_with_compression($m, 'hello01', $data, 'zlib', 1.3, 4);
51+
fetch_with_compression($m, 'hello02', $data, 'fastlz', 1.3, 4);
52+
fetch_with_compression($m, 'hello03', $data, '', 1.3, 4);
53+
fetch_with_compression($m, 'hello04', $short_data, 'zlib', 1.3, 4);
54+
fetch_with_compression($m, 'hello05', $short_data, 'fastlz', 1.3, 4);
55+
fetch_with_compression($m, 'hello06', $short_data, '', 1.3, 4);
56+
fetch_with_compression($m, 'hello11', $data, 'zlib', 0.3, 4);
57+
fetch_with_compression($m, 'hello12', $data, 'fastlz', 0.3, 4);
58+
fetch_with_compression($m, 'hello13', $data, '', 0.3, 4);
59+
fetch_with_compression($m, 'hello14', $short_data, 'zlib', 0.3, 4);
60+
fetch_with_compression($m, 'hello15', $short_data, 'fastlz', 0.3, 4);
61+
fetch_with_compression($m, 'hello16', $short_data, '', 0.3, 4);
62+
fetch_with_compression($m, 'hello21', $data, 'zlib', 1.3, 2000);
63+
fetch_with_compression($m, 'hello22', $data, 'fastlz', 1.3, 2000);
64+
fetch_with_compression($m, 'hello23', $data, '', 1.3, 2000);
65+
fetch_with_compression($m, 'hello24', $short_data, 'zlib', 1.3, 2000);
66+
fetch_with_compression($m, 'hello25', $short_data, 'fastlz', 1.3, 2000);
67+
fetch_with_compression($m, 'hello26', $short_data, '', 1.3, 2000);
68+
fetch_with_compression($m, 'hello31', $data, 'zlib', 0.3, 2000);
69+
fetch_with_compression($m, 'hello32', $data, 'fastlz', 0.3, 2000);
70+
fetch_with_compression($m, 'hello33', $data, '', 0.3, 2000);
71+
fetch_with_compression($m, 'hello34', $short_data, 'zlib', 0.3, 2000);
72+
fetch_with_compression($m, 'hello35', $short_data, 'fastlz', 0.3, 2000);
73+
fetch_with_compression($m, 'hello36', $short_data, '', 0.3, 2000);
74+
?>
75+
--EXPECT--
76+
len=[4877] set=[zlib] factor=[1.3] threshold=[4]
77+
bool(true)
78+
len=[4877] set=[fastlz] factor=[1.3] threshold=[4]
79+
bool(true)
80+
len=[4877] set=[] factor=[1.3] threshold=[4]
81+
bool(true)
82+
len=[7] set=[zlib] factor=[1.3] threshold=[4]
83+
bool(true)
84+
len=[7] set=[fastlz] factor=[1.3] threshold=[4]
85+
bool(true)
86+
len=[7] set=[] factor=[1.3] threshold=[4]
87+
bool(true)
88+
len=[4877] set=[zlib] factor=[0.3] threshold=[4]
89+
bool(true)
90+
len=[4877] set=[fastlz] factor=[0.3] threshold=[4]
91+
bool(true)
92+
len=[4877] set=[] factor=[0.3] threshold=[4]
93+
bool(true)
94+
len=[7] set=[zlib] factor=[0.3] threshold=[4]
95+
bool(true)
96+
len=[7] set=[fastlz] factor=[0.3] threshold=[4]
97+
bool(true)
98+
len=[7] set=[] factor=[0.3] threshold=[4]
99+
bool(true)
100+
len=[4877] set=[zlib] factor=[1.3] threshold=[2000]
101+
bool(true)
102+
len=[4877] set=[fastlz] factor=[1.3] threshold=[2000]
103+
bool(true)
104+
len=[4877] set=[] factor=[1.3] threshold=[2000]
105+
bool(true)
106+
len=[7] set=[zlib] factor=[1.3] threshold=[2000]
107+
bool(true)
108+
len=[7] set=[fastlz] factor=[1.3] threshold=[2000]
109+
bool(true)
110+
len=[7] set=[] factor=[1.3] threshold=[2000]
111+
bool(true)
112+
len=[4877] set=[zlib] factor=[0.3] threshold=[2000]
113+
bool(true)
114+
len=[4877] set=[fastlz] factor=[0.3] threshold=[2000]
115+
bool(true)
116+
len=[4877] set=[] factor=[0.3] threshold=[2000]
117+
bool(true)
118+
len=[7] set=[zlib] factor=[0.3] threshold=[2000]
119+
bool(true)
120+
len=[7] set=[fastlz] factor=[0.3] threshold=[2000]
121+
bool(true)
122+
len=[7] set=[] factor=[0.3] threshold=[2000]
123+
bool(true)

0 commit comments

Comments
 (0)