Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE : Add block allocator for more efficient memory management #129

Open
wants to merge 1 commit into
base: task/eblocks
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 61 additions & 25 deletions engines/COMMON/mblock_allocator.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ static void do_mblock_allocator_free_all() {
pool_tail = NULL;
}

static void prepare_eblk_add_elem(eblock_result_t *result) {
if (result->tail_blk == NULL) {
result->tail_blk = result->head_blk;
result->elem_cnt = 0;
} else {
assert(result->elem_cnt > 0);
if (result->elem_cnt % EITEMS_PER_BLOCK == 0)
result->tail_blk = result->tail_blk->next;
}
}

int mblock_allocator_init(size_t nblocks) {
mem_block_t *helper = NULL;
int i;
Expand All @@ -49,7 +60,7 @@ int mblock_allocator_init(size_t nblocks) {
else nblk = nblocks;

for (i = 0; i < nblk; i++) {
helper = (mem_block_t *)malloc(sizeof(mem_block_t));
helper = (mem_block_t *)malloc(EITEMS_BLCK_SIZE);
if (helper == NULL) break;

helper->next = NULL;
Expand Down Expand Up @@ -105,7 +116,7 @@ void *allocate_single_block() {
// This malloc() inside mutex may raise some performance issue,
// Is there any way to execute malloc and counter adjustment
// outside the mutex lock?
ret = (mem_block_t *)malloc(sizeof(mem_block_t));
ret = (mem_block_t *)malloc(EITEMS_BLCK_SIZE);
if (ret != NULL) {
total_blocks++;
ret->next = NULL;
Expand Down Expand Up @@ -157,7 +168,7 @@ bool mblock_list_alloc(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **
mem_block_t *new_blk = NULL;
uint32_t new_cnt = 0;
while (alloc_cnt < blck_cnt) {
if ((new_blk = (mem_block_t *)malloc(sizeof(mem_block_t))) == NULL) break;
if ((new_blk = (mem_block_t *)malloc(EITEMS_BLCK_SIZE)) == NULL) break;
new_blk->next = NULL;

if (*head_blk) (*tail_blk)->next = new_blk;
Expand All @@ -171,32 +182,33 @@ bool mblock_list_alloc(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **
total_mblocks += new_cnt;
//pthread_mutex_unlock(&pool_mutex);
if (alloc_cnt < blck_cnt) {
mblock_list_free(alloc_cnt, *head_blk, *tail_blk);
mblock_list_free(alloc_cnt, head_blk, tail_blk);
return false;
}
}

return true;
}

void mblock_list_free(uint32_t blck_cnt, mem_block_t *head_blk, mem_block_t *tail_blk) {
void mblock_list_free(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **tail_blk) {
//mem_block_t *bye = NULL;
//mem_block_t *bye_helper = NULL;

//pthread_mutex_lock(&pool_mutex);
if (head_blk == NULL || blck_cnt == 0)
if (*head_blk == NULL || blck_cnt == 0)
return;

assert(pool_tail == NULL || pool_tail->next == NULL);
assert(tail_blk->next == NULL);
assert((*tail_blk)->next == NULL);

if (pool_head == NULL) {
pool_head = head_blk;
pool_head = *head_blk;
} else {
pool_tail->next = head_blk;
pool_tail->next = *head_blk;
}
pool_tail = tail_blk;
pool_tail = *tail_blk;

*head_blk = *tail_blk = NULL;
free_mblocks += blck_cnt;
assert(free_mblocks <= total_mblocks);

Expand All @@ -223,17 +235,35 @@ void mblock_list_free(uint32_t blck_cnt, mem_block_t *head_blk, mem_block_t *tai
free(bye_helper);
}*/
}

bool eblk_prepare(eblock_result_t *result, uint32_t elem_count) {
assert(elem_count > 0);
uint32_t blkcnt = ((elem_count - 1) / EITEMS_PER_BLOCK) + 1;
if (!mblock_list_alloc(blkcnt, &result->head_blk, &result->last_blk)) {
result->elem_cnt = 0;
return false;
uint32_t blkcnt;
if (result->head_blk == NULL) { // empty block
blkcnt = ((elem_count - 1) / EITEMS_PER_BLOCK) + 1;
if (!mblock_list_alloc(blkcnt, &result->head_blk, &result->last_blk)) {
result->elem_cnt = 0;
return false;
}
result->tail_blk = NULL;
} else {
mem_block_t *head;
mem_block_t *last;
uint32_t curr_blkcnt = result->blck_cnt;
int alloc_blkcnt;
blkcnt = ((result->elem_cnt + elem_count - 1) / EITEMS_PER_BLOCK) + 1;
alloc_blkcnt = blkcnt - curr_blkcnt;
if (alloc_blkcnt > 0) { // need append block
if (!mblock_list_alloc((alloc_blkcnt), &head, &last))
return false;
result->last_blk->next = head;
result->last_blk = last;
}
}
result->tail_blk = NULL;
result->blck_cnt = blkcnt;
return true;
}

void eblk_truncate(eblock_result_t *result) {
assert(result->last_blk->next == NULL);
/* returns empty blocklist */
Expand All @@ -244,27 +274,33 @@ void eblk_truncate(eblock_result_t *result) {
uint32_t used_nblks = ((result->elem_cnt - 1) / EITEMS_PER_BLOCK) + 1;
uint32_t free_nblks = result->blck_cnt - used_nblks;

mblock_list_free(free_nblks, free_head, free_tail);
mblock_list_free(free_nblks, &free_head, &free_tail);
result->tail_blk->next = NULL;
result->last_blk = result->tail_blk;
result->blck_cnt -= free_nblks;
}
} else { /* ENGINE_ELEM_ENOENT case */
mblock_list_free(result->blck_cnt, result->head_blk, result->last_blk);
mblock_list_free(result->blck_cnt, &result->head_blk, &result->last_blk);
result->head_blk = result->tail_blk = result->last_blk = NULL;
result->elem_cnt = result->blck_cnt = 0;
}
}

void eblk_add_elem(eblock_result_t *result, eitem *elem) {
if (result->tail_blk == NULL) {
result->tail_blk = result->head_blk;
result->elem_cnt = 0;
} else {
assert(result->elem_cnt > 0);
if (result->elem_cnt % EITEMS_PER_BLOCK == 0)
result->tail_blk = result->tail_blk->next;
prepare_eblk_add_elem(result);
result->tail_blk->items[result->elem_cnt++ % EITEMS_PER_BLOCK] = (eitem *)elem;
}

void eblk_add_elem_with_posi(eblock_result_t *result, eitem *elem, int posi) {
mem_block_t *curr_blk = result->head_blk;
int move_block_count = (posi / EITEMS_PER_BLOCK);

while (move_block_count > 0) {
curr_blk = curr_blk->next;
move_block_count--;
}

result->tail_blk->items[result->elem_cnt++ % EITEMS_PER_BLOCK] = (eitem *)elem;
prepare_eblk_add_elem(result);
curr_blk->items[posi % EITEMS_PER_BLOCK] = (eitem *)elem;
result->elem_cnt++;
}
4 changes: 2 additions & 2 deletions engines/COMMON/mblock_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ void mblock_allocator_destroy(void);
void mblock_allocator_stats(mblock_stats *blk_stat);

bool mblock_list_alloc(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **tail_blk);
void mblock_list_free(uint32_t blck_cnt, mem_block_t *head_blk, mem_block_t *tail_blk);
void mblock_list_free(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **tail_blk);

bool eblk_prepare(eblock_result_t *result, uint32_t elem_count);
void eblk_truncate(eblock_result_t *result);
void eblk_add_elem(eblock_result_t *result, eitem *elem);

void eblk_add_elem_with_posi(eblock_result_t *result, eitem *elem, int posi);
#endif
47 changes: 47 additions & 0 deletions engines/default/default_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,13 +777,23 @@ default_btree_elem_alloc(ENGINE_HANDLE* handle, const void* cookie,
return ret;
}

#ifdef USE_EBLOCK_RESULT
static void
default_btree_elem_release(ENGINE_HANDLE* handle, const void *cookie,
eitem *eitem, EITEM_TYPE type)
{
struct default_engine *engine = get_handle(handle);
btree_elem_release(engine, eitem, type);
}
#else
static void
default_btree_elem_release(ENGINE_HANDLE* handle, const void *cookie,
eitem **eitem_array, const int eitem_count)
{
struct default_engine *engine = get_handle(handle);
btree_elem_release(engine, (btree_elem_item**)eitem_array, eitem_count);
}
#endif

static ENGINE_ERROR_CODE
default_btree_elem_insert(ENGINE_HANDLE* handle, const void* cookie,
Expand Down Expand Up @@ -879,7 +889,11 @@ default_btree_elem_get(ENGINE_HANDLE* handle, const void* cookie,
const bkey_range *bkrange, const eflag_filter *efilter,
const uint32_t offset, const uint32_t req_count,
const bool delete, const bool drop_if_empty,
#ifdef USE_EBLOCK_RESULT
eblock_result_t *eblk_ret,
#else
eitem** eitem_array, uint32_t* eitem_count,
#endif
uint32_t *access_count, uint32_t* flags,
bool* dropped_trimmed, uint16_t vbucket)
{
Expand All @@ -890,7 +904,11 @@ default_btree_elem_get(ENGINE_HANDLE* handle, const void* cookie,
if (delete) ACTION_BEFORE_WRITE(cookie, key, nkey);
ret = btree_elem_get(engine, key, nkey, bkrange, efilter,
offset, req_count, delete, drop_if_empty,
#ifdef USE_EBLOCK_RESULT
eblk_ret,
#else
(btree_elem_item**)eitem_array, eitem_count,
#endif
access_count, flags, dropped_trimmed);
if (delete) ACTION_AFTER_WRITE(cookie, ret);
return ret;
Expand Down Expand Up @@ -932,17 +950,27 @@ default_btree_posi_find_with_get(ENGINE_HANDLE* handle, const void* cookie,
const char *key, const size_t nkey,
const bkey_range *bkrange,
ENGINE_BTREE_ORDER order, const uint32_t count,
#ifdef USE_EBLOCK_RESULT
int *position, eblock_result_t *eblk_ret,
uint32_t *eitem_index,
#else
int *position, eitem **eitem_array,
uint32_t *eitem_count, uint32_t *eitem_index,
#endif
uint32_t *flags, uint16_t vbucket)
{
struct default_engine *engine = get_handle(handle);
ENGINE_ERROR_CODE ret;
VBUCKET_GUARD(engine, vbucket);

ret = btree_posi_find_with_get(engine, key, nkey, bkrange, order, count,
#ifdef USE_EBLOCK_RESULT
position, eblk_ret,
eitem_index, flags);
#else
position, (btree_elem_item**)eitem_array,
eitem_count, eitem_index, flags);
#endif
return ret;
}

Expand All @@ -951,15 +979,23 @@ default_btree_elem_get_by_posi(ENGINE_HANDLE* handle, const void* cookie,
const char *key, const size_t nkey,
ENGINE_BTREE_ORDER order,
uint32_t from_posi, uint32_t to_posi,
#ifdef USE_EBLOCK_RESULT
eblock_result_t *eblk_ret,
#else
eitem **eitem_array, uint32_t *eitem_count,
#endif
uint32_t *flags, uint16_t vbucket)
{
struct default_engine *engine = get_handle(handle);
ENGINE_ERROR_CODE ret;
VBUCKET_GUARD(engine, vbucket);

ret = btree_elem_get_by_posi(engine, key, nkey, order, from_posi, to_posi,
#ifdef USE_EBLOCK_RESULT
eblk_ret,
#else
(btree_elem_item**)eitem_array, eitem_count,
#endif
flags);
return ret;
}
Expand All @@ -973,10 +1009,16 @@ default_btree_elem_smget_old(ENGINE_HANDLE* handle, const void* cookie,
const bkey_range *bkrange,
const eflag_filter *efilter,
const uint32_t offset, const uint32_t count,
#ifdef USE_EBLOCK_RESULT
eblock_result_t *eblk_ret,
uint32_t* kfnd_array,
uint32_t* flag_array,
#else
eitem** eitem_array,
uint32_t* kfnd_array,
uint32_t* flag_array,
uint32_t* eitem_count,
#endif
uint32_t* missed_key_array,
uint32_t* missed_key_count,
bool *trimmed, bool *duplicated,
Expand All @@ -987,8 +1029,13 @@ default_btree_elem_smget_old(ENGINE_HANDLE* handle, const void* cookie,
VBUCKET_GUARD(engine, vbucket);

ret = btree_elem_smget_old(engine, karray, kcount, bkrange, efilter,
#ifdef USE_EBLOCK_RESULT
offset, count, eblk_ret,
kfnd_array, flag_array,
#else
offset, count, (btree_elem_item**)eitem_array,
kfnd_array, flag_array, eitem_count,
#endif
missed_key_array, missed_key_count,
trimmed, duplicated);
return ret;
Expand Down
Loading