Data-HashMap-Shared
view release on metacpan or search on metacpan
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
RETVAL = (UV)shm_i16_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI16 *nodes = (ShmNodeI16 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].key);
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI16 *nodes = (ShmNodeI16 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].value);
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI16 *nodes = (ShmNodeI16 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
mXPUSHi(nodes[i].key);
mXPUSHi(nodes[i].value);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
int16_t out_key, out_value;
if (shm_i16_each(h, &out_key, &out_value)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
mXPUSHi(out_value);
XSRETURN(2);
}
shm_i16_flush_deferred(h);
XSRETURN_EMPTY;
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
int16_t out_value;
if (!shm_i16_take(h, key, &out_value)) XSRETURN_UNDEF;
RETVAL = newSViv(out_value);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
int16_t out_key;
int16_t out_val;
if (!shm_i16_pop(h, &out_key, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
mPUSHi(out_val);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
int16_t out_key;
int16_t out_val;
if (!shm_i16_shift(h, &out_key, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
mPUSHi(out_val);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_i16_drain_entry *entries;
Newxz(entries, limit, shm_i16_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_i16_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
RETVAL = (UV)shm_i16_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
int done = 0;
uint32_t flushed = shm_i16_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
bool
set_ttl(SV* self_sv, int16_t key, UV ttl_sec)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
RETVAL = shm_i16_set_ttl(h, key, (uint32_t)ttl_sec);
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
int16_t key = (int16_t)SvIV(ST(i + 1));
int16_t val;
if (shm_i16_get(h, key, &val))
mPUSHi(val);
if (i + 1 < nkeys) {
uint32_t npos = hashes[i + 1] & mask;
__builtin_prefetch(&states[npos], 0, 0);
__builtin_prefetch(&nodes[npos], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, int16_t key)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
int16_t out_value;
int64_t out_ttl;
if (!shm_i16_get_with_ttl(h, key, &out_value, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_value);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
SV*
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_i16_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::I16::Cursor", self_sv);
int16_t out_key, out_value;
if (shm_i16_cursor_next(c, &out_key, &out_value)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
mXPUSHi(out_value);
XSRETURN(2);
}
XSRETURN_EMPTY;
for (int i = 1; i < items; i++)
count += shm_i16s_remove_inner(h, (int16_t)SvIV(ST(i)));
if (count) shm_i16s_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
int16_t key = (int16_t)SvIV(ST(i + 1));
const char *out_s; uint32_t out_l; bool out_u;
if (shm_i16s_get(h, key, &out_s, &out_l, &out_u)) {
SV *sv = newSVpvn(out_s, out_l);
if (i + 1 < nkeys) {
uint32_t npos = hashes[i + 1] & mask;
__builtin_prefetch(&states[npos], 0, 0);
__builtin_prefetch(&nodes[npos], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, int16_t key)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
const char *out_s; uint32_t out_l; bool out_u;
int64_t out_ttl;
if (!shm_i16s_get_with_ttl(h, key, &out_s, &out_l, &out_u, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *vsv = newSVpvn(out_s, out_l);
if (out_u) SvUTF8_on(vsv);
mPUSHs(vsv);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
RETVAL = (UV)shm_i16s_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI16S *nodes = (ShmNodeI16S *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].key);
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI16S *nodes = (ShmNodeI16S *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
const char *vp = shm_str_ptr(nodes[i].val_off, nodes[i].val_len, sh->arena, _ib, &vlen);
SV* sv = newSVpvn(vp, vlen);
if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI16S *nodes = (ShmNodeI16S *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
SV* sv = newSVpvn(vp, vlen);
if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
int16_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (shm_i16s_each(h, &out_key, &out_val, &out_vlen, &out_vutf8)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
SV* sv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(sv);
mXPUSHs(sv);
XSRETURN(2);
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
const char *out_str; uint32_t out_len; bool out_utf8;
if (!shm_i16s_take(h, key, &out_str, &out_len, &out_utf8)) XSRETURN_UNDEF;
RETVAL = newSVpvn(out_str, out_len);
if (out_utf8) SvUTF8_on(RETVAL);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
int16_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (!shm_i16s_pop(h, &out_key, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
SV *vsv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(vsv);
mPUSHs(vsv);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
int16_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (!shm_i16s_shift(h, &out_key, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
SV *vsv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(vsv);
mPUSHs(vsv);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_i16s_drain_entry *entries;
Newxz(entries, limit, shm_i16s_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_i16s_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
RETVAL = (UV)shm_i16s_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
int done = 0;
uint32_t flushed = shm_i16s_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_i16s_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::I16S::Cursor", self_sv);
int16_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (shm_i16s_cursor_next(c, &out_key, &out_val, &out_vlen, &out_vutf8)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
SV* sv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(sv);
mXPUSHs(sv);
XSRETURN(2);
for (int i = 1; i < items; i++)
count += shm_i32_remove_inner(h, (int32_t)SvIV(ST(i)));
if (count) shm_i32_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
int32_t key = (int32_t)SvIV(ST(i + 1));
int32_t val;
if (shm_i32_get(h, key, &val))
mPUSHi(val);
if (i + 1 < nkeys) {
uint32_t npos = hashes[i + 1] & mask;
__builtin_prefetch(&states[npos], 0, 0);
__builtin_prefetch(&nodes[npos], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, int32_t key)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
int32_t out_value;
int64_t out_ttl;
if (!shm_i32_get_with_ttl(h, key, &out_value, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_value);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
SV*
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
RETVAL = (UV)shm_i32_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI32 *nodes = (ShmNodeI32 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].key);
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI32 *nodes = (ShmNodeI32 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].value);
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI32 *nodes = (ShmNodeI32 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
mXPUSHi(nodes[i].key);
mXPUSHi(nodes[i].value);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
int32_t out_key, out_value;
if (shm_i32_each(h, &out_key, &out_value)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
mXPUSHi(out_value);
XSRETURN(2);
}
shm_i32_flush_deferred(h);
XSRETURN_EMPTY;
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
int32_t out_value;
if (!shm_i32_take(h, key, &out_value)) XSRETURN_UNDEF;
RETVAL = newSViv(out_value);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
int32_t out_key;
int32_t out_val;
if (!shm_i32_pop(h, &out_key, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
mPUSHi(out_val);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
int32_t out_key;
int32_t out_val;
if (!shm_i32_shift(h, &out_key, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
mPUSHi(out_val);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_i32_drain_entry *entries;
Newxz(entries, limit, shm_i32_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_i32_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
RETVAL = (UV)shm_i32_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
int done = 0;
uint32_t flushed = shm_i32_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_i32_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::I32::Cursor", self_sv);
int32_t out_key; int32_t out_value;
if (shm_i32_cursor_next(c, &out_key, &out_value)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
mXPUSHi(out_value);
XSRETURN(2);
}
XSRETURN_EMPTY;
for (int i = 1; i < items; i++)
count += shm_i32s_remove_inner(h, (int32_t)SvIV(ST(i)));
if (count) shm_i32s_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
int32_t key = (int32_t)SvIV(ST(i + 1));
const char *out_s; uint32_t out_l; bool out_u;
if (shm_i32s_get(h, key, &out_s, &out_l, &out_u)) {
SV *sv = newSVpvn(out_s, out_l);
if (i + 1 < nkeys) {
uint32_t npos = hashes[i + 1] & mask;
__builtin_prefetch(&states[npos], 0, 0);
__builtin_prefetch(&nodes[npos], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, int32_t key)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
const char *out_s; uint32_t out_l; bool out_u;
int64_t out_ttl;
if (!shm_i32s_get_with_ttl(h, key, &out_s, &out_l, &out_u, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *vsv = newSVpvn(out_s, out_l);
if (out_u) SvUTF8_on(vsv);
mPUSHs(vsv);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
RETVAL = (UV)shm_i32s_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI32S *nodes = (ShmNodeI32S *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].key);
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI32S *nodes = (ShmNodeI32S *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
const char *vp = shm_str_ptr(nodes[i].val_off, nodes[i].val_len, sh->arena, _ib, &vlen);
SV* sv = newSVpvn(vp, vlen);
if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeI32S *nodes = (ShmNodeI32S *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
SV* sv = newSVpvn(vp, vlen);
if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
int32_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (shm_i32s_each(h, &out_key, &out_val, &out_vlen, &out_vutf8)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
SV* sv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(sv);
mXPUSHs(sv);
XSRETURN(2);
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
const char *out_str; uint32_t out_len; bool out_utf8;
if (!shm_i32s_take(h, key, &out_str, &out_len, &out_utf8)) XSRETURN_UNDEF;
RETVAL = newSVpvn(out_str, out_len);
if (out_utf8) SvUTF8_on(RETVAL);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
int32_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (!shm_i32s_pop(h, &out_key, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
SV *vsv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(vsv);
mPUSHs(vsv);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
int32_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (!shm_i32s_shift(h, &out_key, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
SV *vsv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(vsv);
mPUSHs(vsv);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_i32s_drain_entry *entries;
Newxz(entries, limit, shm_i32s_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_i32s_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
RETVAL = (UV)shm_i32s_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::I32S", self_sv);
int done = 0;
uint32_t flushed = shm_i32s_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_i32s_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::I32S::Cursor", self_sv);
int32_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (shm_i32s_cursor_next(c, &out_key, &out_val, &out_vlen, &out_vutf8)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
SV* sv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(sv);
mXPUSHs(sv);
XSRETURN(2);
for (int i = 1; i < items; i++)
count += shm_ii_remove_inner(h, (int64_t)SvIV(ST(i)));
if (count) shm_ii_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
int64_t key = (int64_t)SvIV(ST(i + 1));
int64_t val;
if (shm_ii_get(h, key, &val))
mPUSHi(val);
if (i + 1 < nkeys) {
uint32_t npos = hashes[i + 1] & mask;
__builtin_prefetch(&states[npos], 0, 0);
__builtin_prefetch(&nodes[npos], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, int64_t key)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
int64_t out_value;
int64_t out_ttl;
if (!shm_ii_get_with_ttl(h, key, &out_value, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_value);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
SV*
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
RETVAL = (UV)shm_ii_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeII *nodes = (ShmNodeII *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].key);
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeII *nodes = (ShmNodeII *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].value);
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeII *nodes = (ShmNodeII *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
mXPUSHi(nodes[i].key);
mXPUSHi(nodes[i].value);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
int64_t out_key, out_value;
if (shm_ii_each(h, &out_key, &out_value)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
mXPUSHi(out_value);
XSRETURN(2);
}
shm_ii_flush_deferred(h);
XSRETURN_EMPTY;
CODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
int64_t out_value;
if (!shm_ii_take(h, key, &out_value)) XSRETURN_UNDEF;
RETVAL = newSViv(out_value);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
int64_t out_key;
int64_t out_val;
if (!shm_ii_pop(h, &out_key, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
mPUSHi(out_val);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
int64_t out_key;
int64_t out_val;
if (!shm_ii_shift(h, &out_key, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
mPUSHi(out_val);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_ii_drain_entry *entries;
Newxz(entries, limit, shm_ii_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_ii_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
RETVAL = (UV)shm_ii_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::II", self_sv);
int done = 0;
uint32_t flushed = shm_ii_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_ii_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::II::Cursor", self_sv);
int64_t out_key; int64_t out_value;
if (shm_ii_cursor_next(c, &out_key, &out_value)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
mXPUSHi(out_value);
XSRETURN(2);
}
XSRETURN_EMPTY;
for (int i = 1; i < items; i++)
count += shm_is_remove_inner(h, (int64_t)SvIV(ST(i)));
if (count) shm_is_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
int64_t key = (int64_t)SvIV(ST(i + 1));
const char *out_s; uint32_t out_l; bool out_u;
if (shm_is_get(h, key, &out_s, &out_l, &out_u)) {
SV *sv = newSVpvn(out_s, out_l);
if (i + 1 < nkeys) {
uint32_t npos = hashes[i + 1] & mask;
__builtin_prefetch(&states[npos], 0, 0);
__builtin_prefetch(&nodes[npos], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, int64_t key)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
const char *out_s; uint32_t out_l; bool out_u;
int64_t out_ttl;
if (!shm_is_get_with_ttl(h, key, &out_s, &out_l, &out_u, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *vsv = newSVpvn(out_s, out_l);
if (out_u) SvUTF8_on(vsv);
mPUSHs(vsv);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
RETVAL = (UV)shm_is_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeIS *nodes = (ShmNodeIS *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].key);
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeIS *nodes = (ShmNodeIS *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
const char *vp = shm_str_ptr(nodes[i].val_off, nodes[i].val_len, sh->arena, _ib, &vlen);
SV* sv = newSVpvn(vp, vlen);
if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeIS *nodes = (ShmNodeIS *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
SV* sv = newSVpvn(vp, vlen);
if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
int64_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (shm_is_each(h, &out_key, &out_val, &out_vlen, &out_vutf8)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
SV* sv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(sv);
mXPUSHs(sv);
XSRETURN(2);
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
const char *out_str; uint32_t out_len; bool out_utf8;
if (!shm_is_take(h, key, &out_str, &out_len, &out_utf8)) XSRETURN_UNDEF;
RETVAL = newSVpvn(out_str, out_len);
if (out_utf8) SvUTF8_on(RETVAL);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
int64_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (!shm_is_pop(h, &out_key, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
SV *vsv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(vsv);
mPUSHs(vsv);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
int64_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (!shm_is_shift(h, &out_key, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_key);
SV *vsv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(vsv);
mPUSHs(vsv);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_is_drain_entry *entries;
Newxz(entries, limit, shm_is_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_is_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
RETVAL = (UV)shm_is_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::IS", self_sv);
int done = 0;
uint32_t flushed = shm_is_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_is_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::IS::Cursor", self_sv);
int64_t out_key;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (shm_is_cursor_next(c, &out_key, &out_val, &out_vlen, &out_vutf8)) {
EXTEND(SP, 2);
mXPUSHi(out_key);
SV* sv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(sv);
mXPUSHs(sv);
XSRETURN(2);
count += shm_si_remove_inner(h, _ks, (uint32_t)_kl, _ku);
}
if (count) shm_si_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
STRLEN _kl; const char *_ks = SvPV(ST(i + 1), _kl);
bool _ku = SvUTF8(ST(i + 1)) ? 1 : 0;
int64_t val;
if (shm_si_get(h, _ks, (uint32_t)_kl, _ku, &val))
if (i + 1 < nkeys) {
STRLEN nkl; const char *nks = SvPV(ST(i + 2), nkl);
uint32_t nh = shm_hash_string(nks, (uint32_t)nkl);
__builtin_prefetch(&states[nh & mask], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, SV* key_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
EXTRACT_STR_KEY(key_sv);
int64_t out_value;
int64_t out_ttl;
if (!shm_si_get_with_ttl(h, _kstr, (uint32_t)_klen, _kutf8, &out_value, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_value);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
RETVAL = (UV)shm_si_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI *nodes = (ShmNodeSI *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
const char *kp = shm_str_ptr(nodes[i].key_off, nodes[i].key_len, sh->arena, _ib, &klen);
SV* sv = newSVpvn(kp, klen);
if (SHM_UNPACK_UTF8(nodes[i].key_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI *nodes = (ShmNodeSI *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].value);
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI *nodes = (ShmNodeSI *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_UNPACK_UTF8(nodes[i].key_len)) SvUTF8_on(sv);
mXPUSHs(sv);
mXPUSHi(nodes[i].value);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int64_t out_value;
if (shm_si_each(h, &out_key, &out_klen, &out_kutf8, &out_value)) {
EXTEND(SP, 2);
SV* ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mXPUSHs(ksv);
mXPUSHi(out_value);
XSRETURN(2);
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
EXTRACT_STR_KEY(key_sv);
int64_t out_value;
if (!shm_si_take(h, _kstr, (uint32_t)_klen, _kutf8, &out_value)) XSRETURN_UNDEF;
RETVAL = newSViv(out_value);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int64_t out_val;
if (!shm_si_pop(h, &out_key, &out_klen, &out_kutf8, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mPUSHs(ksv);
mPUSHi(out_val);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int64_t out_val;
if (!shm_si_shift(h, &out_key, &out_klen, &out_kutf8, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mPUSHs(ksv);
mPUSHi(out_val);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_si_drain_entry *entries;
Newxz(entries, limit, shm_si_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_si_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
RETVAL = (UV)shm_si_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI", self_sv);
int done = 0;
uint32_t flushed = shm_si_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_si_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::SI::Cursor", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int64_t out_value;
if (shm_si_cursor_next(c, &out_key, &out_klen, &out_kutf8, &out_value)) {
EXTEND(SP, 2);
SV* ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mXPUSHs(ksv);
mXPUSHi(out_value);
XSRETURN(2);
count += shm_si16_remove_inner(h, _ks, (uint32_t)_kl, _ku);
}
if (count) shm_si16_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
STRLEN _kl; const char *_ks = SvPV(ST(i + 1), _kl);
bool _ku = SvUTF8(ST(i + 1)) ? 1 : 0;
int16_t val;
if (shm_si16_get(h, _ks, (uint32_t)_kl, _ku, &val))
if (i + 1 < nkeys) {
STRLEN nkl; const char *nks = SvPV(ST(i + 2), nkl);
uint32_t nh = shm_hash_string(nks, (uint32_t)nkl);
__builtin_prefetch(&states[nh & mask], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, SV* key_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
EXTRACT_STR_KEY(key_sv);
int16_t out_value;
int64_t out_ttl;
if (!shm_si16_get_with_ttl(h, _kstr, (uint32_t)_klen, _kutf8, &out_value, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_value);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
RETVAL = (UV)shm_si16_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI16 *nodes = (ShmNodeSI16 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
const char *kp = shm_str_ptr(nodes[i].key_off, nodes[i].key_len, sh->arena, _ib, &klen);
SV* sv = newSVpvn(kp, klen);
if (SHM_UNPACK_UTF8(nodes[i].key_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI16 *nodes = (ShmNodeSI16 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].value);
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI16 *nodes = (ShmNodeSI16 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_UNPACK_UTF8(nodes[i].key_len)) SvUTF8_on(sv);
mXPUSHs(sv);
mXPUSHi(nodes[i].value);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int16_t out_value;
if (shm_si16_each(h, &out_key, &out_klen, &out_kutf8, &out_value)) {
EXTEND(SP, 2);
SV* ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mXPUSHs(ksv);
mXPUSHi(out_value);
XSRETURN(2);
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
EXTRACT_STR_KEY(key_sv);
int16_t out_value;
if (!shm_si16_take(h, _kstr, (uint32_t)_klen, _kutf8, &out_value)) XSRETURN_UNDEF;
RETVAL = newSViv(out_value);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int16_t out_val;
if (!shm_si16_pop(h, &out_key, &out_klen, &out_kutf8, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mPUSHs(ksv);
mPUSHi(out_val);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int16_t out_val;
if (!shm_si16_shift(h, &out_key, &out_klen, &out_kutf8, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mPUSHs(ksv);
mPUSHi(out_val);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_si16_drain_entry *entries;
Newxz(entries, limit, shm_si16_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_si16_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
RETVAL = (UV)shm_si16_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI16", self_sv);
int done = 0;
uint32_t flushed = shm_si16_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_si16_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::SI16::Cursor", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int16_t out_value;
if (shm_si16_cursor_next(c, &out_key, &out_klen, &out_kutf8, &out_value)) {
EXTEND(SP, 2);
SV* ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mXPUSHs(ksv);
mXPUSHi(out_value);
XSRETURN(2);
count += shm_si32_remove_inner(h, _ks, (uint32_t)_kl, _ku);
}
if (count) shm_si32_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
STRLEN _kl; const char *_ks = SvPV(ST(i + 1), _kl);
bool _ku = SvUTF8(ST(i + 1)) ? 1 : 0;
int32_t val;
if (shm_si32_get(h, _ks, (uint32_t)_kl, _ku, &val))
if (i + 1 < nkeys) {
STRLEN nkl; const char *nks = SvPV(ST(i + 2), nkl);
uint32_t nh = shm_hash_string(nks, (uint32_t)nkl);
__builtin_prefetch(&states[nh & mask], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, SV* key_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
EXTRACT_STR_KEY(key_sv);
int32_t out_value;
int64_t out_ttl;
if (!shm_si32_get_with_ttl(h, _kstr, (uint32_t)_klen, _kutf8, &out_value, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
mPUSHi(out_value);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
else mPUSHi(out_ttl);
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
RETVAL = (UV)shm_si32_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI32 *nodes = (ShmNodeSI32 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
const char *kp = shm_str_ptr(nodes[i].key_off, nodes[i].key_len, sh->arena, _ib, &klen);
SV* sv = newSVpvn(kp, klen);
if (SHM_UNPACK_UTF8(nodes[i].key_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI32 *nodes = (ShmNodeSI32 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
mXPUSHi(nodes[i].value);
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSI32 *nodes = (ShmNodeSI32 *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
if (SHM_UNPACK_UTF8(nodes[i].key_len)) SvUTF8_on(sv);
mXPUSHs(sv);
mXPUSHi(nodes[i].value);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int32_t out_value;
if (shm_si32_each(h, &out_key, &out_klen, &out_kutf8, &out_value)) {
EXTEND(SP, 2);
SV* ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mXPUSHs(ksv);
mXPUSHi(out_value);
XSRETURN(2);
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
EXTRACT_STR_KEY(key_sv);
int32_t out_value;
if (!shm_si32_take(h, _kstr, (uint32_t)_klen, _kutf8, &out_value)) XSRETURN_UNDEF;
RETVAL = newSViv(out_value);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int32_t out_val;
if (!shm_si32_pop(h, &out_key, &out_klen, &out_kutf8, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mPUSHs(ksv);
mPUSHi(out_val);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int32_t out_val;
if (!shm_si32_shift(h, &out_key, &out_klen, &out_kutf8, &out_val)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mPUSHs(ksv);
mPUSHi(out_val);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_si32_drain_entry *entries;
Newxz(entries, limit, shm_si32_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_si32_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
RETVAL = (UV)shm_si32_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SI32", self_sv);
int done = 0;
uint32_t flushed = shm_si32_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_si32_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::SI32::Cursor", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
int32_t out_value;
if (shm_si32_cursor_next(c, &out_key, &out_klen, &out_kutf8, &out_value)) {
EXTEND(SP, 2);
SV* ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mXPUSHs(ksv);
mXPUSHi(out_value);
XSRETURN(2);
count += shm_ss_remove_inner(h, _ks, (uint32_t)_kl, _ku);
}
if (count) shm_ss_maybe_shrink(h);
}
RETVAL = count;
OUTPUT:
RETVAL
void
get_multi(SV* self_sv, ...)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
int nkeys = items - 1;
if (nkeys == 0) XSRETURN_EMPTY;
EXTEND(SP, nkeys);
if (h->shard_handles) {
for (int i = 0; i < nkeys; i++) {
STRLEN _kl; const char *_ks = SvPV(ST(i + 1), _kl);
bool _ku = SvUTF8(ST(i + 1)) ? 1 : 0;
const char *out_s; uint32_t out_l; bool out_u;
if (shm_ss_get(h, _ks, (uint32_t)_kl, _ku, &out_s, &out_l, &out_u)) {
if (i + 1 < nkeys) {
STRLEN nkl; const char *nks = SvPV(ST(i + 2), nkl);
uint32_t nh = shm_hash_string(nks, (uint32_t)nkl);
__builtin_prefetch(&states[nh & mask], 0, 0);
}
}
}
void
get_with_ttl(SV* self_sv, SV* key_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
EXTRACT_STR_KEY(key_sv);
const char *out_s; uint32_t out_l; bool out_u;
int64_t out_ttl;
if (!shm_ss_get_with_ttl(h, _kstr, (uint32_t)_klen, _kutf8, &out_s, &out_l, &out_u, &out_ttl)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *vsv = newSVpvn(out_s, out_l);
if (out_u) SvUTF8_on(vsv);
mPUSHs(vsv);
if (out_ttl < 0) PUSHs(&PL_sv_undef);
UV
max_entries(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
RETVAL = (UV)shm_ss_max_entries(h);
OUTPUT:
RETVAL
void
keys(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSS *nodes = (ShmNodeSS *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
const char *kp = shm_str_ptr(nodes[i].key_off, nodes[i].key_len, sh->arena, _ib, &klen);
SV* sv = newSVpvn(kp, klen);
if (SHM_UNPACK_UTF8(nodes[i].key_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
values(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSS *nodes = (ShmNodeSS *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
const char *vp = shm_str_ptr(nodes[i].val_off, nodes[i].val_len, sh->arena, _ib, &vlen);
SV* sv = newSVpvn(vp, vlen);
if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
mXPUSHs(sv);
}
}
}
void
items(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
uint32_t ns = h->shard_handles ? h->num_shards : 1;
for (uint32_t si = 0; si < ns; si++) {
ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
ShmHeader *hdr = sh->hdr;
ShmNodeSS *nodes = (ShmNodeSS *)sh->nodes;
uint32_t now = sh->expires_at ? shm_now() : 0;
RDLOCK_GUARD(sh);
EXTEND(SP, hdr->size * 2);
for (uint32_t i = 0; i < hdr->table_cap; i++) {
SV* vsv = newSVpvn(vp, vlen);
if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(vsv);
mXPUSHs(vsv);
}
}
}
void
each(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
const char *out_key, *out_val;
uint32_t out_klen, out_vlen;
bool out_kutf8, out_vutf8;
if (shm_ss_each(h, &out_key, &out_klen, &out_kutf8, &out_val, &out_vlen, &out_vutf8)) {
EXTEND(SP, 2);
SV* ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mXPUSHs(ksv);
SV* vsv = newSVpvn(out_val, out_vlen);
EXTRACT_STR_KEY(key_sv);
const char *out_str; uint32_t out_len; bool out_utf8;
if (!shm_ss_take(h, _kstr, (uint32_t)_klen, _kutf8, &out_str, &out_len, &out_utf8)) XSRETURN_UNDEF;
RETVAL = newSVpvn(out_str, out_len);
if (out_utf8) SvUTF8_on(RETVAL);
OUTPUT:
RETVAL
void
pop(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (!shm_ss_pop(h, &out_key, &out_klen, &out_kutf8, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mPUSHs(ksv);
SV *vsv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(vsv);
mPUSHs(vsv);
void
shift(SV* self_sv)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
const char *out_key; uint32_t out_klen; bool out_kutf8;
const char *out_val; uint32_t out_vlen; bool out_vutf8;
if (!shm_ss_shift(h, &out_key, &out_klen, &out_kutf8, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
EXTEND(SP, 2);
SV *ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mPUSHs(ksv);
SV *vsv = newSVpvn(out_val, out_vlen);
if (out_vutf8) SvUTF8_on(vsv);
mPUSHs(vsv);
void
drain(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
if (limit == 0) XSRETURN_EMPTY;
shm_ss_drain_entry *entries;
Newxz(entries, limit, shm_ss_drain_entry);
SAVEFREEPV(entries);
char *buf = NULL; uint32_t buf_cap = 0;
uint32_t n = shm_ss_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
UV
flush_expired(SV* self_sv)
CODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
RETVAL = (UV)shm_ss_flush_expired(h);
OUTPUT:
RETVAL
void
flush_expired_partial(SV* self_sv, UV limit)
PPCODE:
EXTRACT_MAP("Data::HashMap::Shared::SS", self_sv);
int done = 0;
uint32_t flushed = shm_ss_flush_expired_partial(h, (uint32_t)limit, &done);
EXTEND(SP, 2);
mPUSHu(flushed);
mPUSHi(done);
UV
mmap_size(SV* self_sv)
CODE:
if (!SvROK(self_sv)) return;
ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
if (!c) return;
ShmHandle* h = c->current;
shm_cursor_destroy(c);
if (h) shm_ss_flush_deferred(h);
sv_setiv(SvRV(self_sv), 0);
void
next(SV* self_sv)
PPCODE:
EXTRACT_CURSOR("Data::HashMap::Shared::SS::Cursor", self_sv);
const char *out_key, *out_val;
uint32_t out_klen, out_vlen;
bool out_kutf8, out_vutf8;
if (shm_ss_cursor_next(c, &out_key, &out_klen, &out_kutf8, &out_val, &out_vlen, &out_vutf8)) {
EXTEND(SP, 2);
SV* ksv = newSVpvn(out_key, out_klen);
if (out_kutf8) SvUTF8_on(ksv);
mXPUSHs(ksv);
SV* vsv = newSVpvn(out_val, out_vlen);
( run in 1.377 second using v1.01-cache-2.11-cpan-71847e10f99 )