Arcus-Client
view release on metacpan or search on metacpan
int arg = 4;
CODE:
RETVAL = NULL;
memcached_return_t ret;
STRLEN key_length, value_length;
char *key_ptr = NULL;
uint64_t cas_value = 0;
char *value_ptr = NULL;
SV *sv;
memcached_st *mc = memcached_pool_pop(arcus->pool, true, &ret);
if (mc == NULL) {
warn("Failed to create the memcached object : %d (%s)", ret, memcached_strerror(NULL, ret));
goto do_return;
}
if (!SvOK(key) || (key_ptr = SvPV(key, key_length)) == NULL) {
warn("key argument is invalid.");
goto do_return;
}
if (!SvIOK(cas) || (cas_value = SvIV(cas)) == 0) {
warn("cas argument is invalid.");
goto do_return;
}
if (!SvOK(value) || (value_ptr = SvPV(value, value_length)) == NULL) {
warn("value argument is invalid.");
goto do_return;
}
if (items > arg && (sv = safe_sv(aTHX_ ST(arg++))) != NULL) {
if (!SvIOK(sv)) {
warn("exptime argument is invalid.");
goto do_return;
}
exptime = (time_t) SvIV(sv);
}
if (items > arg && (sv = safe_sv(aTHX_ ST(arg++))) != NULL) {
if (!SvIOK(sv)) {
warn("flags argument is invalid.");
goto do_return;
}
flags = (int) SvIV(sv);
}
ret = memcached_cas(mc, key_ptr, key_length, value_ptr, value_length, exptime, flags, cas_value);
if (memcached_success(ret)) {
RETVAL = newSViv(true);
} else if (ret == MEMCACHED_DATA_EXISTS || ret == MEMCACHED_NOTFOUND) {
RETVAL = newSViv(false);
} else {
warn("failed to memcached_cas: %d (%s)", ret, memcached_strerror(mc, ret));
}
do_return:
if (mc != NULL) {
memcached_pool_push(arcus->pool, mc);
}
if (RETVAL == NULL) {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
SV *
set(arcus, key, value, ...)
Arcus_API *arcus
SV *key
SV *value
ALIAS:
set = ARCUS_SET
add = ARCUS_ADD
replace = ARCUS_REPLACE
append = ARCUS_APPEND
prepend = ARCUS_PREPEND
PREINIT:
time_t exptime = 0;
int flags = 0;
int arg = 3;
CODE:
RETVAL = NULL;
memcached_return_t ret;
STRLEN key_length, value_length;
char *key_ptr = NULL;
char *value_ptr = NULL;
SV *sv;
memcached_st *mc = memcached_pool_pop(arcus->pool, true, &ret);
if (mc == NULL) {
warn("Failed to create the memcached object : %d (%s)", ret, memcached_strerror(NULL, ret));
goto do_return;
}
if (!SvOK(key) || (key_ptr = SvPV(key, key_length)) == NULL) {
warn("key argument is invalid.");
goto do_return;
}
if (!SvOK(value) || (value_ptr = SvPV(value, value_length)) == NULL) {
warn("value argument is invalid.");
goto do_return;
}
if (items > arg && (sv = safe_sv(aTHX_ ST(arg++))) != NULL) {
if (!SvIOK(sv)) {
warn("exptime argument is invalid.");
goto do_return;
}
exptime = (time_t) SvIV(sv);
}
if (items > arg && (sv = safe_sv(aTHX_ ST(arg++))) != NULL) {
if (!SvIOK(sv)) {
warn("flags argument is invalid.");
goto do_return;
}
flags = (int) SvIV(sv);
}
switch (ix) {
case ARCUS_SET:
ret = memcached_set(mc, key_ptr, key_length, value_ptr, value_length, exptime, flags);
break;
case ARCUS_ADD:
ret = memcached_add(mc, key_ptr, key_length, value_ptr, value_length, exptime, flags);
break;
case ARCUS_REPLACE:
ret = memcached_replace(mc, key_ptr, key_length, value_ptr, value_length, exptime, flags);
break;
case ARCUS_APPEND:
ret = memcached_append(mc, key_ptr, key_length, value_ptr, value_length, exptime, flags);
break;
case ARCUS_PREPEND:
ret = memcached_prepend(mc, key_ptr, key_length, value_ptr, value_length, exptime, flags);
break;
default:
ret = MEMCACHED_FAILURE;
break;
}
if (memcached_success(ret)) {
RETVAL = newSViv(true);
} else if (ret == MEMCACHED_NOTSTORED) {
RETVAL = newSViv(false);
} else {
warn("failed to memcached_%s: %d (%s)", ARCUS_OP_NAME[ix], ret, memcached_strerror(mc, ret));
}
do_return:
if (mc != NULL) {
memcached_pool_push(arcus->pool, mc);
}
if (RETVAL == NULL) {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
void
set_multi(arcus, ...)
Arcus_API *arcus
ALIAS:
set_multi = ARCUS_SET
add_multi = ARCUS_ADD
replace_multi = ARCUS_REPLACE
append_multi = ARCUS_APPEND
prepend_multi = ARCUS_PREPEND
PREINIT:
size_t finished = 0;
size_t arg = 1;
PPCODE:
memcached_return_t ret;
memcached_storage_request_st req[MAX_KEYS_FOR_MULTI_STORE_OPERATION];
memcached_return_t results[MAX_KEYS_FOR_MULTI_STORE_OPERATION];
int req_index[MAX_KEYS_FOR_MULTI_STORE_OPERATION];
SV **result_buf;
memcached_st *mc = memcached_pool_pop(arcus->pool, true, &ret);
if (mc == NULL) {
warn("Failed to create the memcached object : %d (%s)", ret, memcached_strerror(NULL, ret));
goto do_return;
}
size_t number_of_kvs = items - arg;
if (number_of_kvs == 0) {
warn("kvs argument is empty.");
goto do_return;
}
size_t leftover = number_of_kvs;
Newx(result_buf, number_of_kvs, SV *);
SV *req_sv, **req_elem;
size_t i, consume, valid_kvs;
while (leftover > 0) {
valid_kvs = 0;
consume = leftover < MAX_KEYS_FOR_MULTI_STORE_OPERATION
? leftover : MAX_KEYS_FOR_MULTI_STORE_OPERATION;
for (i = 0; i < consume; i++) {
req_index[i] = -1;
req_sv = safe_sv(aTHX_ ST(arg++));
if (req_sv == NULL || !SvROK(req_sv) || SvTYPE(SvRV(req_sv)) != SVt_PVAV) {
warn("kvs[%zu] arugment is not array reference.", finished + i);
continue;
}
AV *req_av = (AV *) SvRV(req_sv);
size_t idx = 0, size = av_count(req_av);
if (size < 2) {
warn("kvs[%zu] arugment is not sufficient.", finished + i);
continue;
}
decr = ARCUS_DECR
PROTOTYPE: $@
PREINIT:
int offset = 1;
int arg = 2;
CODE:
RETVAL = NULL;
memcached_return_t ret;
char *key_ptr;
size_t key_length;
uint64_t value;
memcached_st *mc = memcached_pool_pop(arcus->pool, true, &ret);
if (mc == NULL) {
warn("Failed to create the memcached object : %d (%s)", ret, memcached_strerror(NULL, ret));
goto do_return;
}
if (!SvOK(key) || (key_ptr = SvPV(key, key_length)) == NULL) {
warn("key argument is invalid.");
goto do_return;
}
SV *sv;
if (items > arg && (sv = safe_sv(aTHX_ ST(arg++))) != NULL) {
if (!SvIOK(sv)) {
warn("offset argument is invalid.");
goto do_return;
}
offset = (int) SvIV(sv);
}
switch(ix) {
case ARCUS_INCR:
ret = memcached_increment(mc, key_ptr, key_length, offset, &value);
break;
case ARCUS_DECR:
ret = memcached_decrement(mc, key_ptr, key_length, offset, &value);
break;
default:
ret = MEMCACHED_FAILURE;
break;
}
if (memcached_success(ret)) {
if (value) {
RETVAL = newSViv(value);
} else {
RETVAL = newSVpv("0E0", 0);
}
} else if (ret != MEMCACHED_NOTFOUND) {
warn("failed to memcached_%s: %d (%s)", ARCUS_OP_NAME[ix], ret, memcached_strerror(mc, ret));
}
do_return:
if (mc != NULL) {
memcached_pool_push(arcus->pool, mc);
}
if (RETVAL == NULL) {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
void
get(arcus, key)
Arcus_API *arcus
SV *key
ALIAS:
get = ARCUS_GET
gets = ARCUS_GETS
PPCODE:
memcached_return_t ret;
size_t key_length = 0;
char *key_ptr = NULL;
size_t value_length;
char *value;
uint32_t flags;
bool is_gets = false;
bool do_free_value = true;
dSP;
PUSHMARK(SP);
memcached_st *mc = memcached_pool_pop(arcus->pool, true, &ret);
if (mc == NULL) {
warn("Failed to create the memcached object : %d (%s)", ret, memcached_strerror(NULL, ret));
goto do_return;
}
if (!SvOK(key) || (key_ptr = SvPV(key, key_length)) == NULL) {
warn("key argument is invalid.");
goto do_return;
}
if ((is_gets = (ix == ARCUS_GETS))) {
memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true);
}
value = memcached_get(mc, key_ptr, key_length, &value_length, &flags, &ret);
if (memcached_success(ret) && value_length == 0 && value == NULL) {
do_free_value = false;
value = "";
}
if (value != NULL) {
if (is_gets) {
mXPUSHs(newSViv(((memcached_st *) mc)->result.item_cas));
}
mXPUSHs(newSVpv(value, value_length));
mXPUSHs(newSViv(flags));
if (do_free_value) {
free(value);
}
} else if (ret != MEMCACHED_NOTFOUND) {
warn("failed to memcached_get: %d (%s), value == NULL: %d",
ret, memcached_strerror(mc, ret), value == NULL);
}
if (is_gets) {
memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, false);
}
do_return:
if (mc != NULL) {
memcached_pool_push(arcus->pool, mc);
}
PUTBACK;
HV *
get_multi(arcus, ...)
Arcus_API *arcus
ALIAS:
get_multi = ARCUS_GET
gets_multi = ARCUS_GETS
PREINIT:
size_t arg = 1;
size_t i = 0;
size_t valid_keys = 0;
bool is_gets = false;
CODE:
memcached_return_t ret;
char **keys_ptr = NULL;
size_t *keys_length = NULL;
SV *sv;
RETVAL = newHV();
memcached_st *mc = memcached_pool_pop(arcus->pool, true, &ret);
if (mc == NULL) {
warn("Failed to create the memcached object : %d (%s)", ret, memcached_strerror(NULL, ret));
goto do_return;
}
size_t number_of_keys = items - arg;
if (number_of_keys == 0) {
warn("keys argument is empty.");
goto do_return;
}
Newx(keys_ptr, number_of_keys, char *);
Newx(keys_length, number_of_keys, size_t);
for (i = 0; i < number_of_keys; i++) {
if ((sv = safe_sv(aTHX_ ST(arg++))) != NULL) {
keys_ptr[valid_keys] = SvPV(sv, keys_length[valid_keys]);
} else {
keys_ptr[valid_keys] = NULL;
}
if (keys_ptr[valid_keys] == NULL || keys_length[valid_keys] == 0) {
warn("keys[%zu] argument is invalid.", i);
} else {
valid_keys++;
}
}
if ((is_gets = (ix == ARCUS_GETS))) {
memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true);
}
ret = memcached_mget(mc, (const char * const *) keys_ptr, keys_length, valid_keys);
if (memcached_failed(ret) && ret != MEMCACHED_SOME_ERRORS) {
warn("failed to mget: %d (%s)\n", ret, memcached_strerror(mc, ret));
goto do_return;
}
while (true) {
size_t key_len, value_len;
char key[MEMCACHED_MAX_KEY];
uint32_t flags = 0;
char *value = memcached_fetch(mc, key, &key_len, &value_len, &flags, &ret);
bool do_free_value = true;
if (ret == MEMCACHED_END) {
break;
}
if (memcached_success(ret) && value_len == 0 && value == NULL) {
do_free_value = false;
value = "";
}
if (value == NULL || memcached_failed(ret)) {
warn("failed to fetch: %d (%s), value == NULL: %d", ret, memcached_strerror(mc, ret), value == NULL);
break;
}
AV *arr = newAV();
if (is_gets) {
av_push(arr, newSViv(((memcached_st *) mc)->result.item_cas));
}
av_push(arr, newSVpv(value, value_len));
av_push(arr, newSViv(flags));
hv_store(RETVAL, key, key_len, newRV_noinc((SV *) arr), 0);
if (do_free_value) {
free(value);
}
value = NULL;
}
do_return:
if (is_gets) {
memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, false);
}
if (mc != NULL) {
memcached_pool_push(arcus->pool, mc);
}
if (keys_ptr != NULL) {
Safefree(keys_ptr);
}
if (keys_length != NULL) {
Safefree(keys_length);
}
OUTPUT:
RETVAL
SV *
delete(arcus, key)
Arcus_API *arcus
SV *key
CODE:
memcached_return_t ret;
RETVAL = NULL;
STRLEN key_length;
char *key_ptr = NULL;
memcached_st *mc = memcached_pool_pop(arcus->pool, true, &ret);
if (mc == NULL) {
warn("Failed to create the memcached object : %d (%s)", ret, memcached_strerror(NULL, ret));
goto do_return;
}
if (!SvOK(key) || (key_ptr = SvPV(key, key_length)) == NULL) {
warn("key argument is invalid.");
goto do_return;
}
ret = memcached_delete(mc, key_ptr, key_length, 0);
RETVAL = newSViv(memcached_success(ret));
do_return:
if (mc != NULL) {
memcached_pool_push(arcus->pool, mc);
}
if (RETVAL == NULL) {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
SV *
flush_all(arcus, ...)
Arcus_API *arcus
PREINIT:
time_t exptime = 0;
int arg = 1;
CODE:
memcached_return_t ret;
SV *sv = NULL;
RETVAL = NULL;
memcached_st *mc = memcached_pool_pop(arcus->pool, true, &ret);
if (mc == NULL) {
warn("Failed to create the memcached object : %d (%s)", ret, memcached_strerror(NULL, ret));
goto do_return;
}
if (items > arg && (sv = safe_sv(aTHX_ ST(arg++))) != NULL) {
if (!SvIOK(sv)) {
warn("exptime argument is invalid.");
goto do_return;
}
exptime = (time_t) SvIV(sv);
}
ret = memcached_flush(mc, exptime);
RETVAL = newSViv(memcached_success(ret));
do_return:
if (mc != NULL) {
memcached_pool_push(arcus->pool, mc);
}
if (RETVAL == NULL) {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
HV *
server_versions(arcus)
Arcus_API *arcus
CODE:
memcached_return_t ret;
RETVAL = newHV();
int i;
memcached_st *mc = arcus->global;
if (mc == NULL) {
warn("invalid mc.");
goto do_return;
}
ret = memcached_version(mc);
if (memcached_failed(ret)) {
warn("failed to memcached_version: %d (%s)", ret, memcached_strerror(mc, ret));
goto do_return;
}
for (i = 0; i < memcached_server_count(mc); i++) {
memcached_server_instance_st server = memcached_server_instance_by_position(mc, i);
SV *host = newSVpvf("%s:%d", server->hostname, server->port);
SV *version = newSVpvf("%d.%d.%d", server->major_version,
server->minor_version,
server->micro_version);
hv_store(RETVAL, SvPV_nolen(host), SvCUR(host), version, 0);
}
do_return:
sv_2mortal((SV *) RETVAL);
OUTPUT:
RETVAL
( run in 1.311 second using v1.01-cache-2.11-cpan-39bf76dae61 )