Skip to content

Commit

Permalink
FEATURE : Add block allocator for more efficient memory management
Browse files Browse the repository at this point in the history
- This feature is applied only on btree collection
  • Loading branch information
jooho812 committed Nov 28, 2017
1 parent 2de526b commit e14571b
Show file tree
Hide file tree
Showing 9 changed files with 1,036 additions and 53 deletions.
80 changes: 58 additions & 22 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 Down Expand Up @@ -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

0 comments on commit e14571b

Please sign in to comment.