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 )