fatcache分配空间阅读记录

来源:互联网 发布:java document类 编辑:程序博客网 时间:2024/05/29 17:04
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);    }//这个class的partial_msinfoq不为空,取一个可用的item位置返回    if (!TAILQ_EMPTY(&free_msinfoq)) {//在free_msinfoq中取一个空的,初始化        /* move memory slab from free to partial q */        sinfo = TAILQ_FIRST(&free_msinfoq);//在free_msinfoq中取一个        ASSERT(nfree_msinfoq > 0);        nfree_msinfoq--;//free的少一个        c->nmslab++;//这个class的内存中的slab多一个        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);//表明时内存中的slab        /* 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);}


若磁盘free非空,直接将内存的移至磁盘,返回,若为空,先slab_evict(),再把内存旧的移至磁盘,返回

slab_drain(void){    rstatus_t status;    if (!TAILQ_EMPTY(&free_dsinfoq)) {        ASSERT(nfree_dsinfoq > 0);        return _slab_drain();    }    status = slab_evict();    if (status != FC_OK) {        return status;    }    ASSERT(!TAILQ_EMPTY(&free_dsinfoq));    ASSERT(nfree_dsinfoq > 0);    return _slab_drain();}



将内存中老的移至磁盘中free的位置

_slab_drain(void){    struct slabinfo *msinfo, *dsinfo; /* memory and disk slabinfo */    struct slab *slab;                /* slab to write */    size_t size;                      /* bytes to write */    off_t off;                        /* offset to write at */    int n;                            /* written bytes */    ASSERT(!TAILQ_EMPTY(&full_msinfoq));    ASSERT(nfull_msinfoq > 0);    ASSERT(!TAILQ_EMPTY(&free_dsinfoq));    ASSERT(nfree_dsinfoq > 0);    /* get memory sinfo from full q */    msinfo = TAILQ_FIRST(&full_msinfoq);//从内存中满的里面取一个    nfull_msinfoq--;    TAILQ_REMOVE(&full_msinfoq, msinfo, tqe);    ASSERT(msinfo->mem);    ASSERT(slab_full(msinfo));    /* get disk sinfo from free q */    dsinfo = TAILQ_FIRST(&free_dsinfoq);//从磁盘中取一个空的    nfree_dsinfoq--;    TAILQ_REMOVE(&free_dsinfoq, dsinfo, tqe);    ASSERT(!dsinfo->mem);    /* drain the memory to disk slab */    slab = slab_from_maddr(msinfo->addr, true);    size = settings.slab_size;    off = slab_to_daddr(dsinfo);    n = pwrite(fd, slab, size, off);    if (n < size) {        log_error("pwrite fd %d %zu bytes at offset %"PRId64" failed: %s",                  fd, size, off, strerror(errno));        return FC_ERROR;    }    ctable[msinfo->cid].nmslab--;    ctable[msinfo->cid].ndslab++;    log_debug(LOG_DEBUG, "drain slab at memory (sid %"PRIu32" addr %"PRIu32") "              "to disk (sid %"PRIu32" addr %"PRIu32")", msinfo->sid,              msinfo->addr, dsinfo->sid, dsinfo->addr);    /* swap msinfo <> dsinfo addresses */    slab_swap_addr(msinfo, dsinfo);    /* move dsinfo (now a memory sinfo) to free q */    nfree_msinfoq++;    TAILQ_INSERT_TAIL(&free_msinfoq, dsinfo, tqe);    /* move msinfo (now a disk sinfo) to full q */    nfull_dsinfoq++;    TAILQ_INSERT_TAIL(&full_dsinfoq, msinfo, tqe);    return FC_OK;}


在_slab_get_item(uint8_t cid)中,若partial_msinfoq中的slab满了,则放进full_msinfoq中




原创粉丝点击