Couchbase-Client
view release on metacpan or search on metacpan
xs/Client_multi.xs view on Meta::CPAN
void **keys;
size_t *sizes;
time_t *exps;
SV **tmpsv;
PLCB_sync_t *syncp;
void *keys_stacked[MULTI_STACK_ELEM];
size_t sizes_stacked[MULTI_STACK_ELEM];
time_t exps_stacked[MULTI_STACK_ELEM];
mk_instance_vars(self, instance, object);
_MULTI_INIT_COMMON(object, ret, nreq, args, now);
syncp = &object->sync;
syncp->parent = object;
syncp->ret = (AV*)ret;
if(nreq <= MULTI_STACK_ELEM) {
keys = keys_stacked;
sizes = sizes_stacked;
exps = (cmd == MULTI_CMD_GET) ? NULL : exps_stacked;
} else {
Newx(keys, nreq, void*); SAVEFREEPV(keys);
Newx(sizes, nreq, size_t); SAVEFREEPV(sizes);
if(cmd == MULTI_CMD_GET) {
exps = NULL;
} else {
Newx(exps, nreq, time_t); SAVEFREEPV(exps);
}
}
for(i = 0; i < nreq; i++) {
_fetch_assert(tmpsv, args, i, "arguments");
if(SvTYPE(*tmpsv) <= SVt_PV) {
if(exps) {
die("This command requires a valid expiry");
}
plcb_get_str_or_die(*tmpsv, keys[i], sizes[i], "key");
} else {
AV *argav;
if(SvROK(*tmpsv) == 0 || ( (argav = (AV*)SvRV(*tmpsv))
&& SvTYPE(argav) != SVt_PVAV)) {
die("Expected an array reference");
}
_fetch_assert(tmpsv, argav, 0, "missing key");
plcb_get_str_or_die(*tmpsv, keys[i], sizes[i], "key");
if(exps) {
_fetch_assert(tmpsv, argav, 1, "expiry");
if(! (exps[i] = SvUV(*tmpsv)) ) {
die("expiry of 0 passed. This is not what you want");
}
}
}
}
plcb_callbacks_set_multi(object);
if(cmd == MULTI_CMD_TOUCH) {
err = libcouchbase_mtouch(instance, syncp, nreq,
(const void* const*)keys, sizes, exps);
} else {
err = libcouchbase_mget(instance, syncp, nreq,
(const void* const*)keys, sizes, NULL);
}
if(err == LIBCOUCHBASE_SUCCESS) {
object->io_ops->run_event_loop(object->io_ops);
} else {
for(i = 0; i < nreq; i++) {
AV *errav = newAV();
plcb_ret_set_err(object, errav, err);
hv_store(ret, keys[i], sizes[i],
plcb_ret_blessed_rv(object, errav), 0);
}
}
plcb_callbacks_set_single(object);
return newRV_inc( (SV*)ret);
}
static SV*
PLCB_multi_set_common(SV *self, AV *args, int cmd)
{
_dMULTI_VARS
PLCB_sync_t *syncs = NULL;
PLCB_sync_t syncs_stacked[MULTI_STACK_ELEM];
libcouchbase_storage_t storop;
int nwait;
mk_instance_vars(self, instance, object);
_MULTI_INIT_COMMON(object, ret, nreq, args, now);
if(nreq <= MULTI_STACK_ELEM) {
syncs = syncs_stacked;
} else {
Newx(syncs, nreq, PLCB_sync_t);
SAVEFREEPV(syncs);
}
nwait = 0;
storop = _cmd2storop(cmd);
for(i = 0; i < nreq; i++) {
AV *argav;
SV **tmpsv;
char *value;
STRLEN nvalue;
SV *value_sv = NULL;
uint32_t store_flags = 0;
uint64_t cas = 0;
time_t exp = 0;
_fetch_assert(tmpsv, args, i, "empty argument in spec");
if (SvROK(*tmpsv) == 0 || ( ((argav = (AV*)SvRV(*tmpsv)) &&
SvTYPE(argav) != SVt_PVAV))) {
die("Expected array reference");
}
_fetch_assert(tmpsv, argav, 0, "expected key");
plcb_get_str_or_die(*tmpsv, syncs[i].key, syncs[i].nkey, "key");
_fetch_assert(tmpsv, argav, 1, "expected_value");
plcb_get_str_or_die(*tmpsv, value, nvalue, "value");
value_sv = *tmpsv;
switch(cmd) {
case MULTI_CMD_SET:
case MULTI_CMD_ADD:
case MULTI_CMD_REPLACE:
case MULTI_CMD_APPEND:
case MULTI_CMD_PREPEND:
_exp_from_av(argav, 2, now, exp, tmpsv);
_cas_from_av(argav, 3, cas, tmpsv);
break;
case MULTI_CMD_CAS:
( run in 0.895 second using v1.01-cache-2.11-cpan-140bd7fdf52 )