Cache-Memcached-Fast
view release on metacpan or search on metacpan
PROTOTYPE: $
CODE:
client_destroy(memd->c);
if (memd->compress_method)
{
SvREFCNT_dec(memd->compress_method);
SvREFCNT_dec(memd->decompress_method);
}
if (memd->serialize_method)
{
SvREFCNT_dec(memd->serialize_method);
SvREFCNT_dec(memd->deserialize_method);
}
SvREFCNT_dec(memd->servers);
Safefree(memd);
void
_weaken(sv)
SV *sv
PROTOTYPE: $
CODE:
sv_rvweaken(sv);
void
enable_compress(memd, enable)
Cache_Memcached_Fast * memd
bool enable
PROTOTYPE: $$
CODE:
if (enable && ! memd->compress_method)
warn("Compression module was not found, can't enable compression");
else if ((memd->compress_threshold > 0) != enable)
memd->compress_threshold = -memd->compress_threshold;
void
set(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
add = CMD_ADD
replace = CMD_REPLACE
append = CMD_APPEND
prepend = CMD_PREPEND
cas = CMD_CAS
PROTOTYPE: $@
PREINIT:
int noreply;
struct result_object object =
{ NULL, result_store, NULL, NULL };
const char *key;
STRLEN key_len;
cas_type cas = 0;
const void *buf;
STRLEN buf_len;
flags_type flags = 0;
exptime_type exptime = 0;
int arg = 1;
SV *sv;
PPCODE:
object.arg = newAV();
sv_2mortal((SV *) object.arg);
noreply = (GIMME_V == G_VOID);
client_reset(memd->c, &object, noreply);
key = SvPV_stable_storage(aTHX_ ST(arg), &key_len);
++arg;
if (ix == CMD_CAS)
{
cas = SvUV(ST(arg));
++arg;
}
sv = ST(arg);
++arg;
sv = serialize(aTHX_ memd, sv, &flags);
sv = compress(aTHX_ memd, sv, &flags);
buf = (void *) SvPV_stable_storage(aTHX_ sv, &buf_len);
if (buf_len > memd->max_size)
XSRETURN_EMPTY;
if (items > arg)
{
/* exptime doesn't have to be defined. */
sv = ST(arg);
SvGETMAGIC(sv);
if (SvOK(sv))
exptime = SvIV(sv);
}
if (ix != CMD_CAS)
{
client_prepare_set(memd->c, ix, 0, key, key_len, flags,
exptime, buf, buf_len);
}
else
{
client_prepare_cas(memd->c, 0, key, key_len, cas, flags,
exptime, buf, buf_len);
}
client_execute(memd->c, 2);
if (! noreply)
{
SV **val = av_fetch(object.arg, 0, 0);
if (val)
{
PUSHs(*val);
XSRETURN(1);
}
XSRETURN_EMPTY;
}
void
set_multi(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
add_multi = CMD_ADD
replace_multi = CMD_REPLACE
append_multi = CMD_APPEND
prepend_multi = CMD_PREPEND
cas_multi = CMD_CAS
PROTOTYPE: $@
PREINIT:
int i, noreply;
struct result_object object =
{ NULL, result_store, NULL, NULL };
PPCODE:
object.arg = newAV();
sv_2mortal((SV *) object.arg);
noreply = (GIMME_V == G_VOID);
client_reset(memd->c, &object, noreply);
for (i = 1; i < items; ++i)
{
SV *sv;
AV *av;
const char *key;
STRLEN key_len;
/*
gcc-3.4.2 gives a warning about possibly uninitialized
cas, so we set it to zero.
*/
cas_type cas = 0;
const void *buf;
STRLEN buf_len;
flags_type flags = 0;
exptime_type exptime = 0;
int arg = 0;
sv = ST(i);
if (! (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVAV))
croak("Not an array reference");
av = (AV *) SvRV(sv);
key = SvPV_stable_storage(aTHX_ *safe_av_fetch(aTHX_ av, arg, 0), &key_len);
++arg;
if (ix == CMD_CAS)
{
cas = SvUV(*safe_av_fetch(aTHX_ av, arg, 0));
++arg;
}
sv = *safe_av_fetch(aTHX_ av, arg, 0);
++arg;
sv = serialize(aTHX_ memd, sv, &flags);
sv = compress(aTHX_ memd, sv, &flags);
buf = (void *) SvPV_stable_storage(aTHX_ sv, &buf_len);
if (buf_len > memd->max_size)
continue;
if (av_len(av) >= arg)
{
/* exptime doesn't have to be defined. */
SV **ps = av_fetch(av, arg, 0);
if (ps)
SvGETMAGIC(*ps);
if (ps && SvOK(*ps))
exptime = SvIV(*ps);
}
if (ix != CMD_CAS)
{
client_prepare_set(memd->c, ix, i - 1, key, key_len, flags,
exptime, buf, buf_len);
}
else
{
client_prepare_cas(memd->c, i - 1, key, key_len, cas, flags,
exptime, buf, buf_len);
}
}
client_execute(memd->c, 2);
if (! noreply)
{
if (GIMME_V == G_SCALAR)
{
HV *hv = newHV();
for (i = 0; i <= av_len(object.arg); ++i)
{
SV **val = av_fetch(object.arg, i, 0);
if (val && SvOK(*val))
{
SV *key = *av_fetch((AV *) SvRV(ST(i + 1)), 0, 0);
HE *he = hv_store_ent(hv, key,
SvREFCNT_inc(*val), 0);
if (! he)
SvREFCNT_dec(*val);
}
}
mPUSHs(newRV_noinc((SV *) hv));
XSRETURN(1);
}
else
{
I32 max_index = av_len(object.arg);
EXTEND(SP, max_index + 1);
for (i = 0; i <= max_index; ++i)
{
SV **val = av_fetch(object.arg, i, 0);
if (val)
PUSHs(*val);
else
PUSHs(&PL_sv_undef);
}
XSRETURN(max_index + 1);
}
}
void
get(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
gets = CMD_GETS
PROTOTYPE: $@
PREINIT:
struct xs_value_result value_res;
struct result_object object =
{ alloc_value, svalue_store, free_value, &value_res };
const char *key;
STRLEN key_len;
PPCODE:
value_res.memd = memd;
value_res.vals = NULL;
client_reset(memd->c, &object, 0);
key = SvPV(ST(1), key_len);
client_prepare_get(memd->c, ix, 0, key, key_len);
client_execute(memd->c, 2);
if (value_res.vals)
{
mPUSHs(value_res.vals);
XSRETURN(1);
}
XSRETURN_EMPTY;
void
get_multi(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
gets_multi = CMD_GETS
PROTOTYPE: $@
PREINIT:
struct xs_value_result value_res;
struct result_object object =
{ alloc_value, mvalue_store, free_value, &value_res };
int i, key_count;
HV *hv;
PPCODE:
key_count = items - 1;
value_res.memd = memd;
value_res.vals = (SV *) newAV();
sv_2mortal(value_res.vals);
av_extend((AV *) value_res.vals, key_count - 1);
client_reset(memd->c, &object, 0);
for (i = 0; i < key_count; ++i)
{
const char *key;
STRLEN key_len;
key = SvPV_stable_storage(aTHX_ ST(i + 1), &key_len);
client_prepare_get(memd->c, ix, i, key, key_len);
}
client_execute(memd->c, 2);
hv = newHV();
for (i = 0; i <= av_len((AV *) value_res.vals); ++i)
{
SV **val = av_fetch((AV *) value_res.vals, i, 0);
if (val && SvOK(*val))
{
SV *key = ST(i + 1);
HE *he = hv_store_ent(hv, key,
SvREFCNT_inc(*val), 0);
if (! he)
SvREFCNT_dec(*val);
}
}
mPUSHs(newRV_noinc((SV *) hv));
XSRETURN(1);
void
gat(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
gats = CMD_GATS
PROTOTYPE: $@
PREINIT:
struct xs_value_result value_res;
struct result_object object =
{ alloc_value, svalue_store, free_value, &value_res };
const char *key;
STRLEN key_len;
const char *exptime = "0";
STRLEN exptime_len = 1;
SV *sv;
PPCODE:
value_res.memd = memd;
value_res.vals = NULL;
client_reset(memd->c, &object, 0);
sv = ST(1);
SvGETMAGIC(sv);
if (SvOK(sv))
exptime = SvPV(sv, exptime_len);
key = SvPV(ST(2), key_len);
client_prepare_gat(memd->c, ix, 0, key, key_len, exptime, exptime_len);
client_execute(memd->c, 4);
if (value_res.vals)
{
mPUSHs(value_res.vals);
XSRETURN(1);
}
XSRETURN_EMPTY;
void
gat_multi(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
gats_multi = CMD_GATS
PROTOTYPE: $@
PREINIT:
struct xs_value_result value_res;
struct result_object object =
{ alloc_value, mvalue_store, free_value, &value_res };
int i, key_count;
HV *hv;
SV *sv;
const char *exptime = "0";
STRLEN exptime_len = 1;
PPCODE:
key_count = items - 2;
value_res.memd = memd;
value_res.vals = (SV *) newAV();
sv_2mortal(value_res.vals);
if (key_count > 1)
av_extend((AV *) value_res.vals, key_count - 1);
client_reset(memd->c, &object, 0);
sv = ST(1);
SvGETMAGIC(sv);
if (SvOK(sv))
exptime = SvPV(sv, exptime_len);
for (i = 0; i < key_count; ++i)
{
const char *key;
STRLEN key_len;
key = SvPV_stable_storage(aTHX_ ST(i + 2), &key_len);
client_prepare_gat(memd->c, ix, i, key, key_len, exptime, exptime_len);
}
client_execute(memd->c, 4);
hv = newHV();
for (i = 0; i <= av_len((AV *) value_res.vals); ++i)
{
SV **val = av_fetch((AV *) value_res.vals, i, 0);
if (val && SvOK(*val))
{
SV *key = ST(i + 2);
HE *he = hv_store_ent(hv, key,
SvREFCNT_inc(*val), 0);
if (! he)
SvREFCNT_dec(*val);
}
}
mPUSHs(newRV_noinc((SV *) hv));
XSRETURN(1);
void
incr(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
decr = CMD_DECR
PROTOTYPE: $@
PREINIT:
struct result_object object =
{ alloc_value, embedded_store, NULL, NULL };
int noreply;
const char *key;
STRLEN key_len;
arith_type arg = 1;
PPCODE:
object.arg = newAV();
sv_2mortal((SV *) object.arg);
noreply = (GIMME_V == G_VOID);
client_reset(memd->c, &object, noreply);
key = SvPV_stable_storage(aTHX_ ST(1), &key_len);
if (items > 2)
{
/* increment doesn't have to be defined. */
SV *sv = ST(2);
SvGETMAGIC(sv);
if (SvOK(sv))
arg = SvUV(sv);
}
client_prepare_incr(memd->c, ix, 0, key, key_len, arg);
client_execute(memd->c, 2);
if (! noreply)
{
SV **val = av_fetch(object.arg, 0, 0);
if (val)
{
PUSHs(*val);
XSRETURN(1);
}
XSRETURN_EMPTY;
}
void
incr_multi(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
decr_multi = CMD_DECR
PROTOTYPE: $@
PREINIT:
struct result_object object =
{ alloc_value, embedded_store, NULL, NULL };
int i, noreply;
PPCODE:
object.arg = newAV();
sv_2mortal((SV *) object.arg);
noreply = (GIMME_V == G_VOID);
client_reset(memd->c, &object, noreply);
for (i = 1; i < items; ++i)
{
SV *sv;
AV *av;
const char *key;
STRLEN key_len;
arith_type arg = 1;
sv = ST(i);
if (! SvROK(sv))
{
key = SvPV_stable_storage(aTHX_ sv, &key_len);
}
else
{
if (SvTYPE(SvRV(sv)) != SVt_PVAV)
croak("Not an array reference");
av = (AV *) SvRV(sv);
key = SvPV_stable_storage(aTHX_ *safe_av_fetch(aTHX_ av, 0, 0), &key_len);
if (av_len(av) >= 1)
{
/* increment doesn't have to be defined. */
SV **ps = av_fetch(av, 1, 0);
if (ps)
SvGETMAGIC(*ps);
if (ps && SvOK(*ps))
arg = SvUV(*ps);
}
}
client_prepare_incr(memd->c, ix, i - 1, key, key_len, arg);
}
client_execute(memd->c, 2);
if (! noreply)
{
if (GIMME_V == G_SCALAR)
{
HV *hv = newHV();
for (i = 0; i <= av_len(object.arg); ++i)
{
SV **val = av_fetch(object.arg, i, 0);
if (val && SvOK(*val))
{
SV *key;
HE *he;
key = ST(i + 1);
if (SvROK(key))
key = *av_fetch((AV *) SvRV(key), 0, 0);
he = hv_store_ent(hv, key, SvREFCNT_inc(*val), 0);
if (! he)
SvREFCNT_dec(*val);
}
}
mPUSHs(newRV_noinc((SV *) hv));
XSRETURN(1);
}
else
{
I32 max_index = av_len(object.arg);
EXTEND(SP, max_index + 1);
for (i = 0; i <= max_index; ++i)
{
SV **val = av_fetch(object.arg, i, 0);
if (val)
PUSHs(*val);
else
PUSHs(&PL_sv_undef);
}
XSRETURN(max_index + 1);
}
}
void
delete(memd, ...)
Cache_Memcached_Fast * memd
ALIAS:
remove = CMD_REMOVE
PROTOTYPE: $@
PREINIT:
struct result_object object =
{ NULL, result_store, NULL, NULL };
int noreply;
const char *key;
STRLEN key_len;
PPCODE:
PERL_UNUSED_ARG(ix);
object.arg = newAV();
sv_2mortal((SV *) object.arg);
noreply = (GIMME_V == G_VOID);
client_reset(memd->c, &object, noreply);
key = SvPV_stable_storage(aTHX_ ST(1), &key_len);
if (items > 2)
{
/* Compatibility with old (key, delay) syntax. */
/* delay doesn't have to be defined. */
SV *sv = ST(2);
SvGETMAGIC(sv);
if (SvOK(sv) && SvUV(sv) != 0)
warn("non-zero delete expiration time is ignored");
}
client_prepare_delete(memd->c, 0, key, key_len);
client_execute(memd->c, 2);
if (! noreply)
{
SV **val = av_fetch(object.arg, 0, 0);
if (val)
{
PUSHs(*val);
XSRETURN(1);
}
XSRETURN_EMPTY;
}
void
delete_multi(memd, ...)
Cache_Memcached_Fast * memd
PROTOTYPE: $@
PREINIT:
struct result_object object =
{ NULL, result_store, NULL, NULL };
int i, noreply;
PPCODE:
object.arg = newAV();
sv_2mortal((SV *) object.arg);
noreply = (GIMME_V == G_VOID);
client_reset(memd->c, &object, noreply);
for (i = 1; i < items; ++i)
{
SV *sv;
const char *key;
STRLEN key_len;
sv = ST(i);
if (! SvROK(sv))
{
key = SvPV_stable_storage(aTHX_ sv, &key_len);
}
else
{
/* Compatibility with old [key, delay] syntax. */
AV *av;
if (SvTYPE(SvRV(sv)) != SVt_PVAV)
croak("Not an array reference");
av = (AV *) SvRV(sv);
key = SvPV_stable_storage(aTHX_ *safe_av_fetch(aTHX_ av, 0, 0), &key_len);
if (av_len(av) >= 1)
{
/* delay doesn't have to be defined. */
SV **ps = av_fetch(av, 1, 0);
if (ps)
SvGETMAGIC(*ps);
if (ps && SvOK(*ps) && SvUV(*ps) != 0)
warn("non-zero delete expiration time is ignored");
}
}
client_prepare_delete(memd->c, i - 1, key, key_len);
}
client_execute(memd->c, 2);
if (! noreply)
{
if (GIMME_V == G_SCALAR)
{
HV *hv = newHV();
for (i = 0; i <= av_len(object.arg); ++i)
{
SV **val = av_fetch(object.arg, i, 0);
if (val && SvOK(*val))
{
SV *key;
HE *he;
key = ST(i + 1);
if (SvROK(key))
key = *av_fetch((AV *) SvRV(key), 0, 0);
he = hv_store_ent(hv, key, SvREFCNT_inc(*val), 0);
if (! he)
SvREFCNT_dec(*val);
}
}
mPUSHs(newRV_noinc((SV *) hv));
XSRETURN(1);
}
else
{
I32 max_index = av_len(object.arg);
EXTEND(SP, max_index + 1);
for (i = 0; i <= max_index; ++i)
{
SV **val = av_fetch(object.arg, i, 0);
if (val)
PUSHs(*val);
else
PUSHs(&PL_sv_undef);
}
XSRETURN(max_index + 1);
}
}
void
touch(memd, ...)
Cache_Memcached_Fast * memd
PROTOTYPE: $@
PREINIT:
struct result_object object =
{ NULL, result_store, NULL, NULL };
int noreply;
const char *key;
STRLEN key_len;
exptime_type exptime = 0;
SV *sv;
PPCODE:
object.arg = newAV();
sv_2mortal((SV *) object.arg);
noreply = (GIMME_V == G_VOID);
client_reset(memd->c, &object, noreply);
key = SvPV_stable_storage(aTHX_ ST(1), &key_len);
if (items > 2)
{
/* exptime doesn't have to be defined. */
sv = ST(2);
SvGETMAGIC(sv);
if (SvOK(sv))
exptime = SvIV(sv);
}
client_prepare_touch(memd->c, 0, key, key_len, exptime);
client_execute(memd->c, 2);
if (! noreply)
{
SV **val = av_fetch(object.arg, 0, 0);
if (val)
{
PUSHs(*val);
XSRETURN(1);
}
XSRETURN_EMPTY;
}
void
touch_multi(memd, ...)
Cache_Memcached_Fast * memd
PROTOTYPE: $@
PREINIT:
struct result_object object =
{ NULL, result_store, NULL, NULL };
int i, noreply;
PPCODE:
object.arg = newAV();
sv_2mortal((SV *) object.arg);
noreply = (GIMME_V == G_VOID);
client_reset(memd->c, &object, noreply);
for (i = 1; i < items; ++i)
{
SV *sv;
AV *av;
const char *key;
STRLEN key_len;
exptime_type exptime = 0;
int arg = 0;
sv = ST(i);
if (! (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVAV))
croak("Not an array reference");
av = (AV *) SvRV(sv);
key = SvPV_stable_storage(aTHX_ *safe_av_fetch(aTHX_ av, arg, 0), &key_len);
++arg;
if (av_len(av) >= 1)
{
/* exptime doesn't have to be defined. */
SV **ps = av_fetch(av, arg, 0);
if (ps)
SvGETMAGIC(*ps);
if (ps && SvOK(*ps))
exptime = SvIV(*ps);
}
client_prepare_touch(memd->c, i - 1, key, key_len, exptime);
}
client_execute(memd->c, 2);
if (! noreply)
{
if (GIMME_V == G_SCALAR)
{
HV *hv = newHV();
for (i = 0; i <= av_len(object.arg); ++i)
{
SV **val = av_fetch(object.arg, i, 0);
if (val && SvOK(*val))
{
SV *key;
HE *he;
key = ST(i + 1);
if (SvROK(key))
key = *av_fetch((AV *) SvRV(key), 0, 0);
he = hv_store_ent(hv, key, SvREFCNT_inc(*val), 0);
if (! he)
SvREFCNT_dec(*val);
}
}
mPUSHs(newRV_noinc((SV *) hv));
XSRETURN(1);
}
else
( run in 1.834 second using v1.01-cache-2.11-cpan-71847e10f99 )