Memcached-libmemcached

 view release on metacpan or  search on metacpan

libmemcached.xs  view on Meta::CPAN

    return MEMCACHED_SUCCESS;
}



MODULE=Memcached::libmemcached  PACKAGE=Memcached::libmemcached

PROTOTYPES: DISABLED

INCLUDE: const-xs.inc


=head2 Functions For Managing libmemcached Objects

=cut

Memcached__libmemcached
memcached_create(Memcached__libmemcached ptr=NULL)
    ALIAS:
        new = 1
    PREINIT:
        SV *class_sv = (items >= 1) ? ST(0) : NULL;
    INIT:
        ptr = NULL; /* force null even if arg provided */
        PERL_UNUSED_VAR(ix);


Memcached__libmemcached
memcached_clone(Memcached__libmemcached clone, Memcached__libmemcached source)
    PREINIT:
        SV *class_sv = (items >= 1) ? ST(0) : NULL;
    INIT:
        clone = NULL; /* force null even if arg provided */


unsigned int
memcached_server_count(Memcached__libmemcached ptr)

memcached_return
memcached_server_add(Memcached__libmemcached ptr, char *hostname, unsigned int port=0)

memcached_return
memcached_server_add_with_weight(Memcached__libmemcached ptr, char *hostname, unsigned int port=0, unsigned int weight)

memcached_return
memcached_server_add_unix_socket(Memcached__libmemcached ptr, char *socket)

memcached_return
memcached_server_add_unix_socket_with_weight(Memcached__libmemcached ptr, char *socket, unsigned int weight)

void
memcached_free(Memcached__libmemcached ptr)
    INIT:
        if (!ptr)   /* garbage or already freed this sv */
            XSRETURN_EMPTY;
    POSTCALL:
        LMC_STATE_FROM_PTR(ptr)->ptr = NULL;

void
DESTROY(SV *sv)
    PPCODE:
    lmc_state_st *lmc_state;
    lmc_cb_context_st *lmc_cb_context;

    lmc_state = (lmc_state_st*)LMC_STATE_FROM_SV(sv);
    if (lmc_state->trace_level >= 2) {
        warn("DESTROY sv %p, state %p, ptr %p", SvRV(sv), lmc_state, lmc_state->ptr);
        if (lmc_state->trace_level >= 9)
            sv_dump(sv);
    }
    if (lmc_state->ptr)
        memcached_free(lmc_state->ptr);

    lmc_cb_context = lmc_state->cb_context;
    sv_free(lmc_cb_context->get_cb);
    sv_free(lmc_cb_context->set_cb);
    Safefree(lmc_cb_context->key_strings);
    Safefree(lmc_cb_context->key_lengths);

    sv_unmagic(SvRV(sv), '~'); /* disconnect lmc_state from HV */
    Safefree(lmc_state);

UV
memcached_behavior_get(Memcached__libmemcached ptr, memcached_behavior flag)

memcached_return
memcached_behavior_set(Memcached__libmemcached ptr, memcached_behavior flag, uint64_t data)

memcached_return
memcached_callback_set(Memcached__libmemcached ptr, memcached_callback flag, SV *data)
    CODE:
    /* we only allow setting of known-safe flags */
    switch (flag) {
    case MEMCACHED_CALLBACK_PREFIX_KEY:
        RETVAL = memcached_callback_set(ptr, flag, SvPV_nolen(data));
        break;
    default:
        RETVAL = MEMCACHED_FAILURE;
        break;
    }
    OUTPUT:
        RETVAL

SV *
memcached_callback_get(Memcached__libmemcached ptr, memcached_callback flag, IN_OUT memcached_return ret=NO_INIT)
    PREINIT:
        void *data = NULL;
    CODE:
    RETVAL = &PL_sv_undef;
    /* we only allow setting of known-safe flags */
    switch (flag) {
    case MEMCACHED_CALLBACK_PREFIX_KEY:
        data = memcached_callback_get(ptr, flag, &ret);
        /* libmemcached treats empty prefix as an error */
        /* we treat it more pragmatically */
        RETVAL = newSVpv((data) ? data : "", 0);
        break;
    default:
        ret = MEMCACHED_FAILURE;
        break;
    }

libmemcached.xs  view on Meta::CPAN



SV *
errstr(Memcached__libmemcached ptr)
    ALIAS:
        memcached_errstr = 1
    PREINIT:
        lmc_state_st* lmc_state;
    CODE:
        if (!ptr)
            XSRETURN_UNDEF;
        PERL_UNUSED_VAR(ix);
        RETVAL = newSV(0);
        lmc_state = LMC_STATE_FROM_PTR(ptr);
        /* setup return value as a dualvar with int err code and string error message */
        sv_setiv(RETVAL, lmc_state->last_return);
        sv_setpv(RETVAL, memcached_strerror(ptr, lmc_state->last_return));
        if (lmc_state->last_return == MEMCACHED_ERRNO) {
            /* lmc_state->last_errno should be meaningful here but sometimes isn't */
            /* See https://rt.cpan.org/Ticket/Display.html?id=41299 */
            sv_catpvf(RETVAL, " %s", (lmc_state->last_errno) ? strerror(lmc_state->last_errno) : "(last_errno==0!)");
        }
        SvIOK_on(RETVAL); /* set as dualvar */
    OUTPUT:
        RETVAL


SV *
get(Memcached__libmemcached ptr, SV *key_sv)
    PREINIT:
        char *master_key = NULL;
        size_t master_key_len = 0;
        char *key;
        size_t key_len;
        memcached_return error;
        uint32_t flags;
    CODE:
        if (SvROK(key_sv) && SvTYPE(SvRV(key_sv)) == SVt_PVAV) {
            AV *av = (AV*)SvRV(key_sv);
            master_key = SvPV(AvARRAY(av)[0], master_key_len);
            key_sv = AvARRAY(av)[1];
            warn("get with array ref as key is deprecated");
        }
        key = SvPV(key_sv, key_len);
        error = memcached_mget_by_key(ptr, master_key, master_key_len, (const char * const*)&key, &key_len, 1);
        RETVAL = _fetch_one_sv(ptr, &flags, &error);
    OUTPUT:
        RETVAL


void
get_multi(Memcached__libmemcached ptr, ...)
    PREINIT:
        HV *hv = newHV();
        SV *dest_ref = sv_2mortal(newRV_noinc((SV*)hv));
        char **keys;
        size_t *key_length;
        unsigned int number_of_keys = --items;
        memcached_return ret;
        lmc_cb_context_st *lmc_cb_context;
    PPCODE:
        /* XXX does not support keys being [ $master_key, $key ] */
        lmc_cb_context = LMC_STATE_FROM_PTR(ptr)->cb_context;

        if (number_of_keys > lmc_cb_context->key_alloc_count)
            _prep_keys_buffer(lmc_cb_context, number_of_keys);
        keys       = lmc_cb_context->key_strings;
        key_length = lmc_cb_context->key_lengths;
        while (--items >= 0) {
            keys[items] = SvPV(ST(items+1), key_length[items]);
        }

        ret = memcached_mget(ptr, (const char * const*)keys, key_length, number_of_keys);
        _fetch_all_into_hashref(ptr, ret, hv);
        if (lmc_cb_context->lmc_state->trace_level)
            warn("get_multi of %d keys: mget %s, fetched %d",
                number_of_keys, memcached_strerror(ptr,ret), (int)lmc_cb_context->result_count);
        PUSHs(dest_ref);
        XSRETURN(1);



memcached_return
mget_into_hashref(Memcached__libmemcached ptr, SV *keys_ref, HV *dest_ref)
    ALIAS:
        memcached_mget_into_hashref = 1
    PREINIT:
        char **keys;
        size_t *key_length;
        unsigned int number_of_keys;
    CODE:
        PERL_UNUSED_VAR(ix);
        if ((RETVAL = _prep_keys_lengths(ptr, keys_ref, &keys, &key_length, &number_of_keys)) == MEMCACHED_SUCCESS) {
            RETVAL = memcached_mget(ptr, (const char * const*)keys, key_length, number_of_keys);
            RETVAL = _fetch_all_into_hashref(ptr, RETVAL, dest_ref);
        }
    OUTPUT:
        RETVAL


void
set_callback_coderefs(Memcached__libmemcached ptr, SV *set_cb, SV *get_cb)
    ALIAS:
        memcached_set_callback_coderefs = 1
    PREINIT:
        lmc_state_st *lmc_state;
    CODE:
        PERL_UNUSED_VAR(ix);
        if (SvOK(set_cb) && !(SvROK(set_cb) && SvTYPE(SvRV(set_cb)) == SVt_PVCV))
            croak("set_cb is not a reference to a subroutine");
        if (SvOK(get_cb) && !(SvROK(get_cb) && SvTYPE(SvRV(get_cb)) == SVt_PVCV))
            croak("get_cb is not a reference to a subroutine");
        lmc_state = LMC_STATE_FROM_PTR(ptr);
        sv_setsv(lmc_state->cb_context->set_cb, set_cb);
        sv_setsv(lmc_state->cb_context->get_cb, get_cb);


memcached_return
walk_stats(Memcached__libmemcached ptr, SV *stats_args, CV *cb)
    PREINIT:
        Memcached__libmemcached clone;



( run in 0.689 second using v1.01-cache-2.11-cpan-5511b514fd6 )