1
0
Fork 0

support for reference value

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1572 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
master
Xuefer 9 years ago
parent ef3a8f0221
commit 15ad8700a8

@ -1,8 +1,11 @@
4.0.0 2014-??-??
API Changes
========
* new: proto array xcache_get_refcount(mixed &$variable), with +1 side effect removed
* chg: proto array xcache_get_cowcount(mixed $value)
* new: proto int xcache_get_refcount(mixed &$variable), with +1 side effect removed
* chg: proto int xcache_get_cowcount(mixed $value)
* new: proto mixed &xcache_get_ref(string name): Get cached data by specified name return referenced value. Not supported in PHP_4
* new: proto mixed &xcache_get_ref(string name): Get cached data by specified name return referenced value. Not supported in PHP_4
* new: proto bool xcache_set(string name, mixed &value [, int ttl]): Store data to cache by specified name maintaining value referenced
ChangeLog
========
@ -11,6 +14,7 @@ ChangeLog
* (WIP) cache to disk
* fixed #348: added class const support for __FILE__ __DIR__
* closes #342: added support for object caching. handle IS_RESTORCE as interger
* able to return reference value by xcache_set_ref/xcache_get_ref
* disassembler, decompiler:
* PHP_5_6 support
* misc:

@ -3400,7 +3400,7 @@ PHP_FUNCTION(xcache_get)
}
}
xc_processor_restore_var(return_value, stored_entry_var, xc_vector_data(zend_class_entry *, &index_to_ce) TSRMLS_CC);
xc_processor_restore_var(return_value, ZESW(NULL, return_value_ptr), stored_entry_var, xc_vector_data(zend_class_entry *, &index_to_ce) TSRMLS_CC);
xc_cached_hit_unlocked(cache->cached TSRMLS_CC);
} LEAVE_LOCK(cache);
} while (reload_class);
@ -3473,6 +3473,38 @@ PHP_FUNCTION(xcache_set)
VAR_BUFFER_FREE(name);
}
/* }}} */
/* {{{ proto mixed &xcache_get_ref(string name)
Get cached data by specified name return referenced value. Not supported in PHP_4 */
#ifdef ZEND_BEGIN_ARG_INFO_EX
ZEND_BEGIN_ARG_INFO_EX(arginfo_xcache_get_ref, 0, 1, 1)
ZEND_ARG_INFO(0, name)
ZEND_END_ARG_INFO()
#else
static unsigned char arginfo_xcache_get_ref[] = { 1, BYREF_NONE };
#endif
PHP_FUNCTION(xcache_get_ref)
{
zif_xcache_get(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto bool xcache_set(string name, mixed &value [, int ttl])
Store data to cache by specified name maintaining value referenced */
#ifdef ZEND_BEGIN_ARG_INFO_EX
ZEND_BEGIN_ARG_INFO_EX(arginfo_xcache_set_ref, 0, 0, 2)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(1, value)
ZEND_ARG_INFO(0, ttl)
ZEND_END_ARG_INFO()
#else
static unsigned char arginfo_xcache_set_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_NONE };
#endif
PHP_FUNCTION(xcache_set_ref)
{
zif_xcache_set(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto bool xcache_isset(string name)
Check if an entry exists in cache by specified name */
#ifdef ZEND_BEGIN_ARG_INFO_EX
@ -3627,7 +3659,6 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{
zval *name;
long count = 1;
long value = 0;
zval oldzval;
VAR_BUFFER_FLAGS(name);
if (!xc_var_caches) {
@ -3680,10 +3711,11 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{
value = 0;
}
else {
xc_processor_restore_var(&oldzval, stored_entry_var, NULL TSRMLS_CC);
convert_to_long(&oldzval);
value = Z_LVAL(oldzval);
zval_dtor(&oldzval);
zval zv;
xc_processor_restore_var(&zv, NULL, stored_entry_var, NULL TSRMLS_CC);
convert_to_long(&zv);
value = Z_LVAL(zv);
zval_dtor(&zv);
}
}
else {
@ -3750,6 +3782,10 @@ static zend_function_entry xcache_cacher_functions[] = /* {{{ */
PHP_FE(xcache_set_namespace, arginfo_xcache_set_namespace)
PHP_FE(xcache_get, arginfo_xcache_get)
PHP_FE(xcache_set, arginfo_xcache_set)
PHP_FE(xcache_get_ref, arginfo_xcache_get_ref)
PHP_FE(xcache_set_ref, arginfo_xcache_set_ref)
#ifdef ZEND_BEGIN_ARG_INFO_EX
#endif
PHP_FE(xcache_isset, arginfo_xcache_isset)
PHP_FE(xcache_unset, arginfo_xcache_unset)
PHP_FE(xcache_unset_by_prefix, arginfo_xcache_unset_by_prefix)

@ -86,17 +86,15 @@ dnl }}}
DEFINE_STORE_API(`xc_entry_php_t')
DEFINE_STORE_API(`xc_entry_data_php_t')
DEFINE_STORE_API(`xc_entry_var_t')
EXPORTED_FUNCTION(`xc_entry_php_t *xc_processor_restore_xc_entry_php_t(xc_entry_php_t *dst, const xc_entry_php_t *src TSRMLS_DC)') dnl {{{
EXPORTED_FUNCTION(`void xc_processor_restore_xc_entry_php_t(xc_entry_php_t *dst, const xc_entry_php_t *src TSRMLS_DC)') dnl {{{
{
xc_processor_t processor;
memset(&processor, 0, sizeof(processor));
xc_restore_xc_entry_php_t(&processor, dst, src TSRMLS_CC);
return dst;
}
dnl }}}
EXPORTED_FUNCTION(`xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t(const xc_entry_php_t *entry_php, xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC)') dnl {{{
EXPORTED_FUNCTION(`void xc_processor_restore_xc_entry_data_php_t(const xc_entry_php_t *entry_php, xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC)') dnl {{{
{
xc_processor_t processor;
@ -115,10 +113,9 @@ EXPORTED_FUNCTION(`xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t
if (processor.handle_reference) {
zend_hash_destroy(&processor.zvalptrs);
}
return dst;
}
dnl }}}
EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_t *src, zend_class_entry **index_to_ce TSRMLS_DC)') dnl {{{
EXPORTED_FUNCTION(`void xc_processor_restore_var(zval *dst, zval **dst_ptr, const xc_entry_var_t *src, zend_class_entry **index_to_ce TSRMLS_DC)') dnl {{{
{
xc_processor_t processor;
@ -127,8 +124,9 @@ EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_
if (processor.handle_reference) {
zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
dnl fprintf(stderr, "mark[%p] = %p\n", src, dst);
zend_hash_add(&processor.zvalptrs, (char *)src->value, sizeof(src->value), (void *) &dst, sizeof(dst), NULL);
if (dst_ptr) {
zval_ptr_dtor(dst_ptr);
}
}
processor.index_to_ce = index_to_ce;
@ -146,7 +144,12 @@ EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_
}
}
#endif
xc_restore_zval(&processor, dst, src->value TSRMLS_CC);
if (dst_ptr) {
xc_restore_zval_ptr(&processor, dst_ptr, &src->value TSRMLS_CC);
}
else {
xc_restore_zval(&processor, dst, src->value TSRMLS_CC);
}
if (processor.handle_reference) {
zend_hash_destroy(&processor.zvalptrs);
}
@ -160,8 +163,6 @@ EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_
efree(processor.object_handles);
}
#endif
return dst;
}
dnl }}}
define(`DEFINE_RELOCATE_API', `

@ -283,8 +283,9 @@ DEF_STRUCT_P_FUNC(`zval_ptr', , `dnl {{{
if (zend_hash_find(&processor->zvalptrs, (char *) &SRC()[0], sizeof(SRC()[0]), (void **) &ppzv) == SUCCESS) {
IFCOPY(`
DST()[0] = *ppzv;
IFSTORE(`Z_ADDREF(**DST());')
/* *DST() is updated */
dnl fprintf(stderr, "*DST() is set to %p, PROCESSOR_TYPE is_shm %d\n", DST()[0], xc_is_shm(DST()[0]));
dnl fprintf(stderr, "*DST() is set to %p, PROCESSOR_TYPE is_shm %d\n", (void *) DST()[0], xc_is_shm(DST()[0]));
')
IFCALCSTORE(`processor->have_references = 1;')
IFSTORE(`assert(xc_is_shm(DST()[0]));')
@ -305,7 +306,8 @@ DEF_STRUCT_P_FUNC(`zval_ptr', , `dnl {{{
RELOCATE_EX(zval, pzv)
')
if (zend_hash_add(&processor->zvalptrs, (char *) &SRC()[0], sizeof(SRC()[0]), (void *) &pzv, sizeof(pzv), NULL) == SUCCESS) { /* first add, go on */
dnl fprintf(stderr, "mark[%p] = %p\n", SRC()[0], pzv);
IFSTORE(`Z_SET_REFCOUNT(**DST(), 1);')
dnl IFSTORE(`fprintf(stderr, "mark[%p] = %p\n", (void *) SRC()[0], (void *) pzv);')
}
else {
assert(0);
@ -1416,6 +1418,24 @@ DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{
IFDPRINT(`INDENT()`'fprintf(stderr, "zval:value");')
STRUCT_P_EX(zval_ptr, DST(`value'), SRC(`value'), `value', `', `&')
#if 0
IFSTORE(`
{
HashTable *ht;
zval **zv;
assert(Z_TYPE_P(SRC(`value')) == IS_ARRAY);
ht = Z_ARRVAL_P(SRC(`value'));
assert(ht->nNumOfElements == 1);
fprintf(stderr, "key %s\n", ht->pListHead->arKey);
zv = (zval **) ht->pListHead->pData;
fprintf(stderr, "%d\n", Z_TYPE_PP(zv));
assert(Z_TYPE_PP(zv) == IS_ARRAY);
assert(Z_ARRVAL_PP(zv) == ht);
}
')
#endif
#ifdef ZEND_ENGINE_2
IFCALC(`

@ -0,0 +1,41 @@
--TEST--
xcache_set/get test for reference
--SKIPIF--
<?php
require("skipif.inc");
?>
--INI--
xcache.test = 1
xcache.size = 32M
xcache.var_size = 2M
--FILE--
<?php
$ref = array();
$ref['ref'] = &$ref;
$ref['array'] = array(&$ref);
var_dump(xcache_set_ref("ref", $ref));
unset($ref);
$ref = &xcache_get_ref("ref");
var_dump(array(&$ref));
$ref['test'] = 1;
var_dump($ref['ref']['test']);
var_dump($ref['array'][0]['test']);
?>
--EXPECT--
bool(true)
array(1) {
[0]=>
&array(2) {
["ref"]=>
*RECURSION*
["array"]=>
array(1) {
[0]=>
*RECURSION*
}
}
}
int(1)
int(1)

@ -68,6 +68,9 @@
#ifndef Z_SET_REFCOUNT
# define Z_SET_REFCOUNT(z, rc) (z).refcount = rc
#endif
#ifndef Z_ADDREF
# define Z_ADDREF(z) (z).refcount++
#endif
#ifndef IS_CONSTANT_TYPE_MASK
# define IS_CONSTANT_TYPE_MASK (~IS_CONSTANT_INDEX)
#endif

Loading…
Cancel
Save