diff --git a/mc_util.c b/mc_util.c index f29c7cb92..8e932e444 100644 --- a/mc_util.c +++ b/mc_util.c @@ -31,7 +31,7 @@ static void do_mblck_pool_init(mblck_pool_t *pool, uint32_t blck_len) pool->tail = NULL; pool->head = NULL; pool->blck_len = blck_len; - pool->body_len = blck_len - sizeof(void *); + pool->body_len = blck_len - (sizeof(void *) + sizeof(uint32_t)); pool->used_cnt = 0; pool->free_cnt = 0; } @@ -107,16 +107,29 @@ int mblck_list_alloc(mblck_pool_t *pool, uint32_t item_len, uint32_t item_cnt, } assert(pool->free_cnt >= blck_cnt); + if (blck_cnt > 1) { + list->addnl = (value_item **)malloc(sizeof(value_item *) * (blck_cnt - 1)); + if (list->addnl == NULL) { + return -1; + } + } else { + list->addnl = NULL; + } + + uint32_t cnt = 0; list->pool = (void*)pool; list->head = pool->head; list->tail = list->head; list->blck_cnt = 1; - while (list->blck_cnt < blck_cnt) { + while (list->blck_cnt + cnt < blck_cnt) { list->tail = list->tail->next; - list->blck_cnt += 1; + list->addnl[cnt] = &list->tail->data; + list->addnl[cnt]->len = nitems_per_blck * item_len; + cnt += 1; } pool->head = list->tail->next; list->tail->next = NULL; + list->blck_cnt += cnt; if (pool->head == NULL) { pool->tail = NULL; @@ -141,7 +154,11 @@ void mblck_list_merge(mblck_list_t *pri_list, mblck_list_t *add_list) add_list->head = NULL; add_list->tail = NULL; add_list->blck_cnt = 0; - /* FIXME: item_cnt and item_len: how to merge them ? */ + if (add_list->addnl != NULL) { + free(add_list->addnl); + add_list->addnl = NULL; + } + /* FIXME: item_cnt, item_len and addnl: how to merge them ? */ } void mblck_list_free(mblck_pool_t *pool, mblck_list_t *list) @@ -160,6 +177,10 @@ void mblck_list_free(mblck_pool_t *pool, mblck_list_t *list) list->head = NULL; list->tail = NULL; list->blck_cnt = 0; + if (list->addnl != NULL) { + free(list->addnl); + list->addnl = NULL; + } } list->pool = NULL; } diff --git a/mc_util.h b/mc_util.h index 2c09b1c54..335308986 100644 --- a/mc_util.h +++ b/mc_util.h @@ -37,13 +37,14 @@ typedef struct _token_buff { */ typedef struct _mblck_node { struct _mblck_node *next; - char data[1]; + value_item data; } mblck_node_t; typedef struct _mblck_list { void *pool; mblck_node_t *head; mblck_node_t *tail; + value_item **addnl; uint32_t blck_cnt; uint32_t body_len; uint32_t item_cnt; @@ -68,8 +69,9 @@ typedef struct _mblck_pool { #define MBLCK_GET_BODYLEN(l) ((l)->body_len) #define MBLCK_GET_ITEMCNT(l) ((l)->item_cnt) #define MBLCK_GET_ITEMLEN(l) ((l)->item_len) +#define MBLCK_GET_ADDLIST(l) ((l)->addnl) #define MBLCK_GET_NEXTBLK(b) ((b)->next) -#define MBLCK_GET_BODYPTR(b) ((b)->data) +#define MBLCK_GET_BODYPTR(b) ((b)->data.ptr) /* memory block functions */ int mblck_pool_create(mblck_pool_t *pool, uint32_t blck_len, uint32_t blck_cnt); diff --git a/memcached.c b/memcached.c index 3b4ab7d9b..bee60f44e 100644 --- a/memcached.c +++ b/memcached.c @@ -1017,11 +1017,11 @@ static void ritem_set_first(conn *c, int rtype, int vleng) c->rtype = rtype; if (c->rtype == CONN_RTYPE_MBLCK) { - c->membk = MBLCK_GET_HEADBLK(&c->memblist); - c->ritem = MBLCK_GET_BODYPTR(c->membk); + c->ritem = MBLCK_GET_BODYPTR(MBLCK_GET_HEADBLK(&c->memblist)); c->rlbytes = vleng < MBLCK_GET_BODYLEN(&c->memblist) ? vleng : MBLCK_GET_BODYLEN(&c->memblist); c->rltotal = vleng; + c->rindex = 0; } else if (c->rtype == CONN_RTYPE_HINFO) { if (c->hinfo.naddnl == 0) { @@ -1069,24 +1069,22 @@ static void ritem_set_next(conn *c) { assert(c->rltotal > 0); + value_item *ritem = NULL; + if (c->rtype == CONN_RTYPE_MBLCK) { - c->membk = MBLCK_GET_NEXTBLK(c->membk); - c->ritem = MBLCK_GET_BODYPTR(c->membk); - c->rlbytes = c->rltotal < MBLCK_GET_BODYLEN(&c->memblist) - ? c->rltotal : MBLCK_GET_BODYLEN(&c->memblist); - } - else if (c->rtype == CONN_RTYPE_HINFO) { - c->ritem = c->hinfo.addnl[c->rindex]->ptr; - c->rlbytes = c->rltotal < c->hinfo.addnl[c->rindex]->len - ? c->rltotal : c->hinfo.addnl[c->rindex]->len; - c->rindex += 1; - } - else if (c->rtype == CONN_RTYPE_EINFO) { - c->ritem = c->einfo.addnl[c->rindex]->ptr; - c->rlbytes = c->rltotal < c->einfo.addnl[c->rindex]->len - ? c->rltotal : c->einfo.addnl[c->rindex]->len; - c->rindex += 1; + ritem = MBLCK_GET_ADDLIST(&c->memblist)[c->rindex]; + } else if (c->rtype == CONN_RTYPE_HINFO) { + ritem = c->hinfo.addnl[c->rindex]; + } else if (c->rtype == CONN_RTYPE_EINFO) { + ritem = c->einfo.addnl[c->rindex]; + } else { + /* Invalid rtype */ + return; } + + c->ritem = ritem->ptr; + c->rlbytes = c->rltotal < ritem->len ? c->rltotal : ritem->len; + c->rindex += 1; } /** diff --git a/memcached.h b/memcached.h index 1a50b5f50..f61c73c11 100644 --- a/memcached.h +++ b/memcached.h @@ -296,7 +296,6 @@ struct conn { uint32_t rlbytes; /* use memory blocks */ uint32_t rltotal; /* Used when read data with memory block */ - mblck_node_t *membk; /* current memory block pointer */ mblck_list_t memblist; /* (key or field) string memory block list */ /* hash item and elem item info */