Couchbase-Client
view release on metacpan or search on metacpan
xs/Client_multi.xs view on Meta::CPAN
case MULTI_CMD_PREPEND:
_exp_from_av(argav, 2, now, exp, tmpsv);
_cas_from_av(argav, 3, cas, tmpsv);
break;
case MULTI_CMD_CAS:
_fetch_assert(tmpsv, argav, 2, "Expected cas");
_cas_from_av(argav, 2, cas, tmpsv);
_exp_from_av(argav, 3, now, exp, tmpsv);
break;
default:
die("Unhandled command %d", cmd);
}
_SYNC_RESULT_INIT(object, ret, syncs[i]);
plcb_convert_storage(object, &value_sv, &nvalue, &store_flags);
err = libcouchbase_store(
instance, &syncs[i], storop, syncs[i].key, syncs[i].nkey,
SvPVX(value_sv), nvalue, store_flags, exp, cas);
plcb_convert_storage_free(object, value_sv, store_flags);
_MAYBE_SET_IMMEDIATE_ERROR(err, syncs[i].ret, nwait);
}
_MAYBE_WAIT(nwait);
return newRV_inc( (SV*)ret);
}
static SV*
PLCB_multi_arithmetic_common(SV *self, AV *args, int cmd)
{
_dMULTI_VARS
PLCB_sync_t *syncs;
PLCB_sync_t syncs_stacked[MULTI_STACK_ELEM];
int nwait = 0;
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);
}
for(i = 0; i < nreq; i++) {
AV *argav;
SV **tmpsv;
time_t exp = 0;
int64_t delta = 1;
uint64_t initial = 0;
int do_create = 0;
#define _do_arith_simple(only_sv) \
plcb_get_str_or_die(only_sv, syncs[i].key, syncs[i].nkey, "key"); \
delta = (cmd == MULTI_CMD_DECR) ? (-delta) : delta; \
goto GT_CBC_CMD;
_fetch_assert(tmpsv, args, i, "empty argument in spec");
if(SvTYPE(*tmpsv) == SVt_PV) {
/*simple key*/
if(cmd == MULTI_CMD_ARITHMETIC) {
die("Expected array reference!");
}
_do_arith_simple(*tmpsv);
} else {
if(SvROK(*tmpsv) == 0 || ( (argav = (AV*)SvRV(*tmpsv)) &&
SvTYPE(argav) != SVt_PVAV)) {
die("Expected ARRAY reference");
}
}
_fetch_assert(tmpsv, argav, 0, "expected key");
if(av_len(argav) == 0) {
_do_arith_simple(*tmpsv);
} else {
plcb_get_str_or_die(*tmpsv, syncs[i].key, syncs[i].nkey, "key");
}
_fetch_assert(tmpsv, argav, 1, "expected delta");
delta = SvIV(*tmpsv);
delta = (cmd == MULTI_CMD_DECR) ? (-delta) : delta;
if(cmd != MULTI_CMD_ARITHMETIC) {
goto GT_CBC_CMD;
}
/*fetch initial value here*/
if( (tmpsv = av_fetch(argav, 2, 0)) && SvTYPE(*tmpsv) != SVt_NULL ) {
initial = SvUV(*tmpsv);
do_create = 1;
}
if ( (tmpsv = av_fetch(argav, 3, 0)) && (exp = SvUV(*tmpsv)) ) {
PLCB_UEXP2EXP(exp, exp, now);
}
GT_CBC_CMD:
_SYNC_RESULT_INIT(object, ret, syncs[i]);
err = libcouchbase_arithmetic(instance, &syncs[i], syncs[i].key,
syncs[i].nkey,
delta, exp, do_create, initial);
_MAYBE_SET_IMMEDIATE_ERROR(err, syncs[i].ret, nwait);
}
_MAYBE_WAIT(nwait);
return newRV_inc( (SV*)ret);
}
static SV*
PLCB_multi_remove(SV *self, AV *args)
{
_dMULTI_VARS
PLCB_sync_t *syncs = NULL;
PLCB_sync_t syncs_stacked[MULTI_STACK_ELEM];
int nwait = 0;
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);
}
for(i = 0; i < nreq; i++) {
AV *argav;
SV **tmpsv;
uint64_t cas = 0;
_fetch_assert(tmpsv, args, i, "empty arguments in spec");
if(SvTYPE(*tmpsv) == SVt_PV) {
plcb_get_str_or_die(*tmpsv, syncs[i].key, syncs[i].nkey, "key");
} else {
if(SvROK(*tmpsv) == 0 || ( (argav = (AV*)SvRV(*tmpsv)) &&
SvTYPE(argav) != SVt_PVAV)) {
die("Expected ARRAY reference");
}
_fetch_assert(tmpsv, argav, 0, "key");
plcb_get_str_or_die(*tmpsv, syncs[i].key, syncs[i].nkey, "key");
_cas_from_av(argav, 1, cas, tmpsv);
}
_SYNC_RESULT_INIT(object, ret, syncs[i]);
err = libcouchbase_remove(instance, &syncs[i],
syncs[i].key, syncs[i].nkey, cas);
_MAYBE_SET_IMMEDIATE_ERROR(err, syncs[i].ret, nwait);
}
_MAYBE_WAIT(nwait);
return newRV_inc( (SV*)ret );
}
( run in 0.638 second using v1.01-cache-2.11-cpan-e1769b4cff6 )