Exemple #1
0
static struct item* _item_alloc(uint8_t id, char *key, uint16_t nkey, int exptime, char *value, uint32_t nbyte) {
    struct item *it;
    struct item *uit;
    assert(id >= SLABCLASS_MIN_ID && id <= SLABCLASS_MAX_ID);
    it = item_get_from_lruq(id);
    if (it != NULL && item_expired(it)) {
        item_reuse(it);
        goto done;
    }
    uit = (settings.evict_opt & EVICT_LRU)? it : NULL;
    it = slab_get_item(id);
    if (it != NULL) {
        goto done;
    }
    if (uit != NULL) {
        it = uit;
        item_reuse(it);
        goto done;
    }
    return NULL;
done:
    assert(it->id == id);
    assert(!item_is_linked(it));
    assert(!item_is_slabbed(it));
    assert(it->offset != 0);
    assert(it->refcount == 0);
    it->flags = 0;
    it->nbyte = nbyte;
    it->exptime = exptime + time_now();
    it->nkey = nkey;
    memcpy(item_key(it), key, nkey);
    memcpy(item_key(it) + nkey, value, nbyte);
    return it;
}
Exemple #2
0
struct item *
slab_get_item(uint8_t cid)
{
    rstatus_t status;
    struct slabclass *c;
    struct slabinfo *sinfo;
    struct slab *slab;

    ASSERT(cid >= SLABCLASS_MIN_ID && cid < nctable);
    c = &ctable[cid];

    if (itemx_empty()) {
        status = slab_evict();
        if (status != FC_OK) {
            return NULL;
        }
    }

    if (!TAILQ_EMPTY(&c->partial_msinfoq)) {
        return _slab_get_item(cid);
    }

    if (!TAILQ_EMPTY(&free_msinfoq)) {
        /* move memory slab from free to partial q */
        sinfo = TAILQ_FIRST(&free_msinfoq);
        ASSERT(nfree_msinfoq > 0);
        nfree_msinfoq--;
        TAILQ_REMOVE(&free_msinfoq, sinfo, tqe);

        /* init partial sinfo */
        TAILQ_INSERT_HEAD(&c->partial_msinfoq, sinfo, tqe);
        /* sid is already initialized by slab_init */
        /* addr is already initialized by slab_init */
        sinfo->nalloc = 0;
        sinfo->nfree = 0;
        sinfo->cid = cid;
        /* mem is already initialized by slab_init */
        ASSERT(sinfo->mem == 1);

        /* init slab of partial sinfo */
        slab = slab_from_maddr(sinfo->addr, false);
        slab->magic = SLAB_MAGIC;
        slab->cid = cid;
        /* unused[] is left uninitialized */
        slab->sid = sinfo->sid;
        /* data[] is initialized on-demand */

        return _slab_get_item(cid);
    }

    ASSERT(!TAILQ_EMPTY(&full_msinfoq));
    ASSERT(nfull_msinfoq > 0);

    status = slab_drain();
    if (status != FC_OK) {
        return NULL;
    }

    return slab_get_item(cid);
}
Exemple #3
0
/*
 * Allocate an item. We allocate an item by consuming the next free item
 * from slab of the item's slab class.
 *
 * On success we return the pointer to the allocated item.
 */
static item_rstatus_e
_item_alloc(struct item **it_p, uint8_t klen, uint32_t vlen, uint8_t olen)
{
    uint8_t id = slab_id(item_ntotal(klen, vlen, olen));
    struct item *it;

    log_verb("allocate item with klen %u vlen %u", klen, vlen);

    *it_p = NULL;
    if (id == SLABCLASS_INVALID_ID) {
        return ITEM_EOVERSIZED;
    }

    it = slab_get_item(id);
    *it_p = it;
    if (it != NULL) {
        _item_reset(it);
        slab_ref(item_to_slab(it)); /* slab to be deref'ed in _item_link */
        INCR(slab_metrics, item_curr);
        INCR(slab_metrics, item_alloc);
        PERSLAB_INCR(id, item_curr);

        log_verb("alloc it %p of id %"PRIu8" at offset %"PRIu32, it, it->id,
                it->offset);

        return ITEM_OK;
    } else {
        INCR(slab_metrics, item_alloc_ex);
        log_warn("server error on allocating item in slab %"PRIu8, id);

        return ITEM_ENOMEM;
    }
}