Data-HashMap

 view release on metacpan or  search on metacpan

xs/ia.xsi  view on Meta::CPAN

bool
remove(SV* self_sv, int64_t key)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        RETVAL = hashmap_ia_remove(self, key);
    OUTPUT:
        RETVAL

SV*
take(SV* self_sv, int64_t key)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        void* val;
        if (!hashmap_ia_take(self, key, &val)) XSRETURN_UNDEF;
        RETVAL = (SV*)val;
    OUTPUT:
        RETVAL

bool
exists(SV* self_sv, int64_t key)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        RETVAL = hashmap_ia_exists(self, key);
    OUTPUT:
        RETVAL

size_t
size(SV* self_sv)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        RETVAL = self->size;
    OUTPUT:
        RETVAL

size_t
max_size(SV* self_sv)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        RETVAL = self->max_size;
    OUTPUT:
        RETVAL

UV
ttl(SV* self_sv)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        RETVAL = (UV)self->default_ttl;
    OUTPUT:
        RETVAL

UV
lru_skip(SV* self_sv)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        RETVAL = (UV)self->lru_skip;
    OUTPUT:
        RETVAL

void
keys(SV* self_sv)
    PPCODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
        EXTEND(SP, self->size);
        size_t i;
        for (i = 0; i < self->capacity; i++) {
            if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
                mXPUSHi(self->nodes[i].key);
        }

void
values(SV* self_sv)
    PPCODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
        EXTEND(SP, self->size);
        size_t i;
        for (i = 0; i < self->capacity; i++) {
            if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
                SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
                mXPUSHs(sv);
            }
        }

void
items(SV* self_sv)
    PPCODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
        EXTEND(SP, self->size * 2);
        size_t i;
        for (i = 0; i < self->capacity; i++) {
            if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
                mXPUSHi(self->nodes[i].key);
                SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
                mXPUSHs(sv);
            }
        }

void
each(SV* self_sv)
    PPCODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
        while (self->iter_pos < self->capacity) {
            size_t i = self->iter_pos++;
            if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
                EXTEND(SP, 2);
                mXPUSHi(self->nodes[i].key);
                if (GIMME_V == G_SCALAR) XSRETURN(1);
                SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
                mXPUSHs(sv);
                XSRETURN(2);
            }
        }
        self->iter_pos = 0;
        XSRETURN_EMPTY;

void
iter_reset(SV* self_sv)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        self->iter_pos = 0;

void
drain(SV* self_sv, UV count)
    PPCODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
        UV n = 0;
        EXTEND(SP, (count < self->size ? count : self->size) * 2);
        while (self->iter_pos < self->capacity && n < count) {
            size_t i = self->iter_pos++;
            if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
                mXPUSHi(self->nodes[i].key);
                if (self->nodes[i].value) {
                    mXPUSHs((SV*)self->nodes[i].value);
                } else { XPUSHs(&PL_sv_undef); }
                self->nodes[i].value = NULL;
                if (HM_UNLIKELY(self->lru_prev)) hashmap_ia_lru_unlink(self, (uint32_t)i);
                hashmap_ia_tombstone_at(self, i);
                n++;
            }
        }
        if (self->iter_pos >= self->capacity) self->iter_pos = 0;
        HM_MAYBE_COMPACT_XS(self, hashmap_ia_compact);

void
pop(SV* self_sv)
    PPCODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
        if (self->lru_prev) {
            while (self->lru_tail != HM_LRU_NONE) {
                uint32_t idx = self->lru_tail;
                if (HM_UNLIKELY(HM_TTL_SKIP_EXPIRED(self, idx, now))) {
                    hashmap_ia_expire_at(self, idx, true); continue;
                }
                EXTEND(SP, 2);
                mXPUSHi(self->nodes[idx].key);
                if (self->nodes[idx].value) {
                    mXPUSHs((SV*)self->nodes[idx].value);
                } else { XPUSHs(&PL_sv_undef); }
                self->nodes[idx].value = NULL;
                hashmap_ia_lru_unlink(self, idx);
                hashmap_ia_tombstone_at(self, idx);
                HM_MAYBE_COMPACT_XS(self, hashmap_ia_compact);
                XSRETURN(2);
            }
            XSRETURN_EMPTY;
        } else {
            while (self->iter_pos < self->capacity) {
                size_t i = self->iter_pos++;
                if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
                    EXTEND(SP, 2);
                mXPUSHi(self->nodes[i].key);
                if (self->nodes[i].value) {
                    mXPUSHs((SV*)self->nodes[i].value);
                } else { XPUSHs(&PL_sv_undef); }
                self->nodes[i].value = NULL;
                    hashmap_ia_tombstone_at(self, i);
                    HM_MAYBE_COMPACT_XS(self, hashmap_ia_compact);
                    XSRETURN(2);
                }
            }
            self->iter_pos = 0;
            XSRETURN_EMPTY;
        }

void
shift(SV* self_sv)
    PPCODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
        if (self->lru_prev) {
            while (self->lru_head != HM_LRU_NONE) {
                uint32_t idx = self->lru_head;
                if (HM_UNLIKELY(HM_TTL_SKIP_EXPIRED(self, idx, now))) {
                    hashmap_ia_expire_at(self, idx, true); continue;
                }
                EXTEND(SP, 2);
                mXPUSHi(self->nodes[idx].key);
                if (self->nodes[idx].value) {
                    mXPUSHs((SV*)self->nodes[idx].value);
                } else { XPUSHs(&PL_sv_undef); }
                self->nodes[idx].value = NULL;
                hashmap_ia_lru_unlink(self, idx);
                hashmap_ia_tombstone_at(self, idx);
                HM_MAYBE_COMPACT_XS(self, hashmap_ia_compact);
                XSRETURN(2);
            }
            XSRETURN_EMPTY;
        } else {
            if (self->iter_pos == 0) self->iter_pos = self->capacity;
            while (self->iter_pos > 0) {
                size_t i = --self->iter_pos;
                if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
                    EXTEND(SP, 2);
                mXPUSHi(self->nodes[i].key);
                if (self->nodes[i].value) {
                    mXPUSHs((SV*)self->nodes[i].value);
                } else { XPUSHs(&PL_sv_undef); }
                self->nodes[i].value = NULL;
                    hashmap_ia_tombstone_at(self, i);
                    HM_MAYBE_COMPACT_XS(self, hashmap_ia_compact);
                    XSRETURN(2);
                }
            }
            XSRETURN_EMPTY;
        }


void
clear(SV* self_sv)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        hashmap_ia_clear(self);

void
reserve(SV* self_sv, UV count)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        if (!hashmap_ia_reserve(self, (size_t)count))
            croak("Failed to reserve capacity");

void
purge(SV* self_sv)
    CODE:
        EXTRACT_MAP(HashMapIA, stash_ia, "Data::HashMap::IA", self_sv);
        hashmap_ia_purge(self);

SV*



( run in 0.763 second using v1.01-cache-2.11-cpan-71847e10f99 )