Skip to content

Commit

Permalink
Moving forward.
Browse files Browse the repository at this point in the history
  • Loading branch information
tricky committed Feb 3, 2010
1 parent 6c75fa7 commit c76bb8f
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 20 deletions.
34 changes: 19 additions & 15 deletions php_memcached.c
Expand Up @@ -619,7 +619,6 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
num_keys = zend_hash_num_elements(Z_ARRVAL_P(keys));
mkeys = safe_emalloc(num_keys, sizeof(*mkeys), 0);
mkeys_len = safe_emalloc(num_keys, sizeof(*mkeys_len), 0);
mkeys_copy = safe_emalloc(num_keys, sizeof(*mkeys_copy), 0);
array_init(return_value);

/*
Expand All @@ -629,23 +628,24 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(keys));
zend_hash_get_current_data(Z_ARRVAL_P(keys), (void**)&entry) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(keys))) {
int use_copy = 0;
zval entry_copy, *entry_copy_ptr;
zval copy, *copy_ptr;

if (Z_TYPE_PP(entry) != IS_STRING) {
/* TODO(tricky): should we instead be using a zval array for copies?
* if zval structure changes, this might leed to a leak */
INIT_ZVAL(entry_copy);
zend_make_printable_zval(*entry, &entry_copy, &use_copy);
if (use_copy) {
entry_copy_ptr = &entry_copy;
entry = &entry_copy_ptr;
mkeys_copy[mkeys_ncopy] = Z_STRVAL(entry_copy);
mkeys_ncopy++;
/* this should be relatively uncommon, defer allocation */
if (UNEXPECTED(mkeys_copy == NULL)) {
mkeys_copy = safe_emalloc(num_keys, sizeof(*mkeys_copy), 0);
}

MAKE_COPY_ZVAL(entry, &copy);
convert_to_string(&copy);

mkeys_copy[mkeys_ncopy] = Z_STRVAL(copy);
copy_ptr = ©
entry = &copy_ptr;
mkeys_ncopy++;
}

if (Z_STRLEN_PP(entry) > 0) {
if (Z_TYPE_PP(entry) == IS_STRING && Z_STRLEN_PP(entry) > 0) {
mkeys[i] = Z_STRVAL_PP(entry);
mkeys_len[i] = Z_STRLEN_PP(entry);

Expand All @@ -664,7 +664,9 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
for (i = 0; i < mkeys_ncopy; i++) {
efree(mkeys_copy[i]);
}
efree(mkeys_copy);
if (mkeys_copy) {
efree(mkeys_copy);
}
return;
}

Expand Down Expand Up @@ -696,7 +698,9 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
for (i = 0; i < mkeys_ncopy; i++) {
efree(mkeys_copy[i]);
}
efree(mkeys_copy);
if (mkeys_copy) {
efree(mkeys_copy);
}

/*
* Iterate through the result set and create the result array. The CAS tokens are
Expand Down
10 changes: 5 additions & 5 deletions tests/deletemulti.phpt
Expand Up @@ -48,16 +48,16 @@ foreach ($retval as $key => $value) {
?>
--EXPECT--
array(5) {
["foo"]=>
string(8) "foo-data"
["bar"]=>
string(8) "bar-data"
["baz"]=>
string(8) "baz-data"
["lol"]=>
string(8) "lol-data"
["kek"]=>
string(8) "kek-data"
["foo"]=>
string(8) "foo-data"
["bar"]=>
string(8) "bar-data"
}
array(5) {
["foo"]=>
Expand Down Expand Up @@ -100,4 +100,4 @@ array(5) {
array(0) {
}
nothere NOT FOUND
nothere2 NOT FOUND
nothere2 NOT FOUND
73 changes: 73 additions & 0 deletions tests/experimental/getdelayed_nonstring_keys.phpt
@@ -0,0 +1,73 @@
--TEST--
Memcached getDelayed non string keys
--SKIPIF--
<?php if (!extension_loaded("memcached")) print "skip"; ?>
--FILE--
<?php
$m = new Memcached();
$m->addServer('localhost', 11211, 1);

class Bar {
public function __toString() {
return 'bar';
}
}

$data = array(
'foo' => 'foo-data',
'bar' => 'bar-data',
3 => '3-data',
);

foreach ($data as $k => $v) {
$m->set($k, $v, 3600);
}

function myfunc() {
$datas = func_get_args();
if (isset($datas[1])) {
unset($datas[1]['cas']);
var_dump($datas[1]);
}
}

$keys = array('foo',
$k = new Bar(),
3,
);

$m->getDelayed($keys, false, 'myfunc');

if ($keys[0] !== 'foo') {
echo "String 'foo' was coerced to: ";
var_dump($keys[0]);
}

if (!$keys[1] instanceof Bar) {
echo "Object was coerced to: ";
var_dump($keys[1]);
}

if ($keys[2] !== 3) {
echo "Integer 3 was coerced to: ";
var_dump($keys[2]);
}
--EXPECT--
array(2) {
["key"]=>
string(3) "foo"
["value"]=>
string(8) "foo-data"
}
array(2) {
["key"]=>
string(3) "bar"
["value"]=>
string(8) "bar-data"
}
array(2) {
["key"]=>
string(1) "3"
["value"]=>
string(6) "3-data"
}
47 changes: 47 additions & 0 deletions tests/experimental/getmulti.phpt
@@ -0,0 +1,47 @@
--TEST--
Memcached::getMulti()
--SKIPIF--
<?php if (!extension_loaded("memcached")) print "skip"; ?>
--FILE--
<?php
$m = new Memcached();
$m->addServer('localhost', 11211, 1);

class Foo {
function __toString() {
return 'a-foo';
}
}

$data = array();
for ($i = 0; $i < 1000; $i++) {
$data['key' . $i] = 'value' . $i;
}
$data['a-foo'] = 'a-last';
var_dump($m->setMulti($data));

$keys = array_keys($data);
$keys['last'] = new Foo();

$v = $m->getMulti($keys);
var_dump(is_array($v));
var_dump($m->getResultCode() == Memcached::RES_SUCCESS);
if (is_array($v)) {
foreach ($v as $key => $value) {
if (!isset($data[$key]) or $value !== $data[$key]) {
echo "mismatch \$data['$key'] = \n";
var_dump($data[$key]);
var_dump($value);
}
}
} else {
echo "Result not an array\n";
}

var_dump(is_object($keys['last']));

--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)

0 comments on commit c76bb8f

Please sign in to comment.