Skip to content

Commit 8ee6495

Browse files
committed
Avoid re-allocating data for scalar data types
Conflicts: php_memcached.c
1 parent 8c36e84 commit 8ee6495

File tree

1 file changed

+56
-31
lines changed

1 file changed

+56
-31
lines changed

php_memcached.c

Lines changed: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,37 +2468,44 @@ static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRM
24682468
static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t *flags, enum memcached_serializer serializer, enum memcached_compression_type compression_type TSRMLS_DC)
24692469
{
24702470
char *payload;
2471+
char *p;
2472+
int l;
2473+
zend_bool buf_used = 0;
24712474
smart_str buf = {0};
2475+
char tmp[40] = {0};
24722476

24732477
switch (Z_TYPE_P(value)) {
24742478

24752479
case IS_STRING:
2476-
smart_str_appendl(&buf, Z_STRVAL_P(value), Z_STRLEN_P(value));
2480+
p = Z_STRVAL_P(value);
2481+
l = Z_STRLEN_P(value);
24772482
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_STRING);
24782483
break;
24792484

24802485
case IS_LONG:
2481-
case IS_DOUBLE:
2482-
case IS_BOOL:
2483-
{
2484-
zval value_copy;
2486+
l = sprintf(tmp, "%ld", Z_LVAL_P(value));
2487+
p = tmp;
2488+
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_LONG);
2489+
break;
24852490

2486-
value_copy = *value;
2487-
zval_copy_ctor(&value_copy);
2488-
convert_to_string(&value_copy);
2489-
smart_str_appendl(&buf, Z_STRVAL(value_copy), Z_STRLEN(value_copy));
2490-
zval_dtor(&value_copy);
2491+
case IS_DOUBLE:
2492+
l = sprintf(tmp, "%f", Z_DVAL_P(value));
2493+
p = tmp;
2494+
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_DOUBLE);
2495+
break;
24912496

2492-
*flags &= ~MEMC_VAL_COMPRESSED;
2493-
if (Z_TYPE_P(value) == IS_LONG) {
2494-
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_LONG);
2495-
} else if (Z_TYPE_P(value) == IS_DOUBLE) {
2496-
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_DOUBLE);
2497-
} else if (Z_TYPE_P(value) == IS_BOOL) {
2498-
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL);
2497+
case IS_BOOL:
2498+
if (Z_BVAL_P(value)) {
2499+
l = 1;
2500+
tmp[0] = '1';
2501+
tmp[1] = '\0';
2502+
} else {
2503+
l = 0;
2504+
tmp[0] = '\0';
24992505
}
2506+
p = tmp;
2507+
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL);
25002508
break;
2501-
}
25022509

25032510
default:
25042511
switch (serializer) {
@@ -2508,6 +2515,9 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
25082515
smart_str_free(&buf);
25092516
return NULL;
25102517
}
2518+
p = buf.c;
2519+
l = buf.len;
2520+
buf_used = 1;
25112521
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_IGBINARY);
25122522
break;
25132523
#endif
@@ -2522,6 +2532,9 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
25222532
php_json_encode(&buf, value, 0 TSRMLS_CC); /* options */
25232533
#endif
25242534
buf.c[buf.len] = 0;
2535+
p = buf.c;
2536+
l = buf.len;
2537+
buf_used = 1;
25252538
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_JSON);
25262539
break;
25272540
}
@@ -2538,7 +2551,9 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
25382551
smart_str_free(&buf);
25392552
return NULL;
25402553
}
2541-
2554+
p = buf.c;
2555+
l = buf.len;
2556+
buf_used = 1;
25422557
MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_SERIALIZED);
25432558
break;
25442559
}
@@ -2547,6 +2562,12 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
25472562
break;
25482563
}
25492564

2565+
/* Check for exceptions caused by serializers */
2566+
if (EG(exception) && buf_used) {
2567+
smart_str_free(&buf);
2568+
return NULL;
2569+
}
2570+
25502571
/* turn off compression for values below the threshold */
25512572
if ((*flags & MEMC_VAL_COMPRESSED) && buf.len < MEMC_G(compression_threshold)) {
25522573
*flags &= ~MEMC_VAL_COMPRESSED;
@@ -2557,44 +2578,48 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
25572578
zend_bool compress_status = 0;
25582579

25592580
/* Additional 5% for the data */
2560-
unsigned long payload_comp_len = (unsigned long)((buf.len * 1.05) + 1);
2581+
unsigned long payload_comp_len = (unsigned long)((l * 1.05) + 1);
25612582
char *payload_comp = emalloc(payload_comp_len + sizeof(uint32_t));
25622583
payload = payload_comp;
2563-
memcpy(payload_comp, &buf.len, sizeof(uint32_t));
2584+
memcpy(payload_comp, &l, sizeof(uint32_t));
25642585
payload_comp += sizeof(uint32_t);
25652586

25662587
if (compression_type == COMPRESSION_TYPE_FASTLZ) {
2567-
compress_status = ((payload_comp_len = fastlz_compress(buf.c, buf.len, payload_comp)) > 0);
2588+
compress_status = ((payload_comp_len = fastlz_compress(p, l, payload_comp)) > 0);
25682589
*flags |= MEMC_VAL_COMPRESSION_FASTLZ;
25692590
} else if (compression_type == COMPRESSION_TYPE_ZLIB) {
2570-
compress_status = (compress((Bytef *)payload_comp, &payload_comp_len, (Bytef *)buf.c, buf.len) == Z_OK);
2591+
compress_status = (compress((Bytef *)payload_comp, &payload_comp_len, (Bytef *)p, l) == Z_OK);
25712592
*flags |= MEMC_VAL_COMPRESSION_ZLIB;
25722593
}
25732594

25742595
if (!compress_status) {
25752596
php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not compress value");
25762597
efree(payload);
2577-
smart_str_free(&buf);
2598+
if (buf_used) {
2599+
smart_str_free(&buf);
2600+
}
25782601
return NULL;
25792602
}
25802603

25812604
/* Check that we are above ratio */
2582-
if (buf.len > (payload_comp_len * MEMC_G(compression_factor))) {
2605+
if (l > (payload_comp_len * MEMC_G(compression_factor))) {
25832606
*payload_len = payload_comp_len + sizeof(uint32_t);
25842607
payload[*payload_len] = 0;
25852608
} else {
25862609
/* Store plain value */
25872610
*flags &= ~MEMC_VAL_COMPRESSED;
2588-
*payload_len = buf.len;
2589-
memcpy(payload, buf.c, buf.len);
2590-
payload[buf.len] = 0;
2611+
*payload_len = l;
2612+
memcpy(payload, p, l);
2613+
payload[l] = 0;
25912614
}
25922615
} else {
2593-
*payload_len = buf.len;
2594-
payload = estrndup(buf.c, buf.len);
2616+
*payload_len = l;
2617+
payload = estrndup(p, l);
25952618
}
25962619

2597-
smart_str_free(&buf);
2620+
if (buf_used) {
2621+
smart_str_free(&buf);
2622+
}
25982623
return payload;
25992624
}
26002625

0 commit comments

Comments
 (0)