Skip to content

Commit 8db61d2

Browse files
committed
FEATURE : Add block allocator for more efficient memory management
- This feature is applied only on btree collection
1 parent 2de526b commit 8db61d2

File tree

9 files changed

+1041
-53
lines changed

9 files changed

+1041
-53
lines changed

engines/COMMON/mblock_allocator.c

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ static void do_mblock_allocator_free_all() {
3939
pool_tail = NULL;
4040
}
4141

42+
static void prepare_eblk_add_elem(eblock_result_t *result) {
43+
if (result->tail_blk == NULL) {
44+
result->tail_blk = result->head_blk;
45+
result->elem_cnt = 0;
46+
} else {
47+
assert(result->elem_cnt > 0);
48+
if (result->elem_cnt % EITEMS_PER_BLOCK == 0)
49+
result->tail_blk = result->tail_blk->next;
50+
}
51+
}
52+
4253
int mblock_allocator_init(size_t nblocks) {
4354
mem_block_t *helper = NULL;
4455
int i;
@@ -171,32 +182,33 @@ bool mblock_list_alloc(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **
171182
total_mblocks += new_cnt;
172183
//pthread_mutex_unlock(&pool_mutex);
173184
if (alloc_cnt < blck_cnt) {
174-
mblock_list_free(alloc_cnt, *head_blk, *tail_blk);
185+
mblock_list_free(alloc_cnt, head_blk, tail_blk);
175186
return false;
176187
}
177188
}
178189

179190
return true;
180191
}
181192

182-
void mblock_list_free(uint32_t blck_cnt, mem_block_t *head_blk, mem_block_t *tail_blk) {
193+
void mblock_list_free(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **tail_blk) {
183194
//mem_block_t *bye = NULL;
184195
//mem_block_t *bye_helper = NULL;
185196

186197
//pthread_mutex_lock(&pool_mutex);
187-
if (head_blk == NULL || blck_cnt == 0)
198+
if (*head_blk == NULL || blck_cnt == 0)
188199
return;
189200

190201
assert(pool_tail == NULL || pool_tail->next == NULL);
191-
assert(tail_blk->next == NULL);
202+
assert((*tail_blk)->next == NULL);
192203

193204
if (pool_head == NULL) {
194-
pool_head = head_blk;
205+
pool_head = *head_blk;
195206
} else {
196-
pool_tail->next = head_blk;
207+
pool_tail->next = *head_blk;
197208
}
198-
pool_tail = tail_blk;
209+
pool_tail = *tail_blk;
199210

211+
*head_blk = *tail_blk = NULL;
200212
free_mblocks += blck_cnt;
201213
assert(free_mblocks <= total_mblocks);
202214

@@ -223,17 +235,35 @@ void mblock_list_free(uint32_t blck_cnt, mem_block_t *head_blk, mem_block_t *tai
223235
free(bye_helper);
224236
}*/
225237
}
238+
226239
bool eblk_prepare(eblock_result_t *result, uint32_t elem_count) {
227240
assert(elem_count > 0);
228-
uint32_t blkcnt = ((elem_count - 1) / EITEMS_PER_BLOCK) + 1;
229-
if (!mblock_list_alloc(blkcnt, &result->head_blk, &result->last_blk)) {
230-
result->elem_cnt = 0;
231-
return false;
241+
uint32_t blkcnt;
242+
if (result->head_blk == NULL) { // empty block
243+
blkcnt = ((elem_count - 1) / EITEMS_PER_BLOCK) + 1;
244+
if (!mblock_list_alloc(blkcnt, &result->head_blk, &result->last_blk)) {
245+
result->elem_cnt = 0;
246+
return false;
247+
}
248+
result->tail_blk = NULL;
249+
} else {
250+
mem_block_t *head;
251+
mem_block_t *last;
252+
uint32_t curr_blkcnt = result->blck_cnt;
253+
int alloc_blkcnt;
254+
blkcnt = ((result->elem_cnt + elem_count - 1) / EITEMS_PER_BLOCK) + 1;
255+
alloc_blkcnt = blkcnt - curr_blkcnt;
256+
if (alloc_blkcnt > 0) { // need append block
257+
if (!mblock_list_alloc((alloc_blkcnt), &head, &last))
258+
return false;
259+
result->last_blk->next = head;
260+
result->last_blk = last;
261+
}
232262
}
233-
result->tail_blk = NULL;
234263
result->blck_cnt = blkcnt;
235264
return true;
236265
}
266+
237267
void eblk_truncate(eblock_result_t *result) {
238268
assert(result->last_blk->next == NULL);
239269
/* returns empty blocklist */
@@ -244,27 +274,33 @@ void eblk_truncate(eblock_result_t *result) {
244274
uint32_t used_nblks = ((result->elem_cnt - 1) / EITEMS_PER_BLOCK) + 1;
245275
uint32_t free_nblks = result->blck_cnt - used_nblks;
246276

247-
mblock_list_free(free_nblks, free_head, free_tail);
277+
mblock_list_free(free_nblks, &free_head, &free_tail);
248278
result->tail_blk->next = NULL;
249279
result->last_blk = result->tail_blk;
250280
result->blck_cnt -= free_nblks;
251281
}
252282
} else { /* ENGINE_ELEM_ENOENT case */
253-
mblock_list_free(result->blck_cnt, result->head_blk, result->last_blk);
283+
mblock_list_free(result->blck_cnt, &result->head_blk, &result->last_blk);
254284
result->head_blk = result->tail_blk = result->last_blk = NULL;
255285
result->elem_cnt = result->blck_cnt = 0;
256286
}
257287
}
258288

259289
void eblk_add_elem(eblock_result_t *result, eitem *elem) {
260-
if (result->tail_blk == NULL) {
261-
result->tail_blk = result->head_blk;
262-
result->elem_cnt = 0;
263-
} else {
264-
assert(result->elem_cnt > 0);
265-
if (result->elem_cnt % EITEMS_PER_BLOCK == 0)
266-
result->tail_blk = result->tail_blk->next;
290+
prepare_eblk_add_elem(result);
291+
result->tail_blk->items[result->elem_cnt++ % EITEMS_PER_BLOCK] = (eitem *)elem;
292+
}
293+
294+
void eblk_add_elem_with_posi(eblock_result_t *result, eitem *elem, int posi) {
295+
mem_block_t *curr_blk = result->head_blk;
296+
int move_block_count = (posi / EITEMS_PER_BLOCK);
297+
298+
while (move_block_count > 0) {
299+
curr_blk = curr_blk->next;
300+
move_block_count--;
267301
}
268302

269-
result->tail_blk->items[result->elem_cnt++ % EITEMS_PER_BLOCK] = (eitem *)elem;
303+
prepare_eblk_add_elem(result);
304+
curr_blk->items[posi % EITEMS_PER_BLOCK] = (eitem *)elem;
305+
result->elem_cnt++;
270306
}

engines/COMMON/mblock_allocator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ void mblock_allocator_destroy(void);
2929
void mblock_allocator_stats(mblock_stats *blk_stat);
3030

3131
bool mblock_list_alloc(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **tail_blk);
32-
void mblock_list_free(uint32_t blck_cnt, mem_block_t *head_blk, mem_block_t *tail_blk);
32+
void mblock_list_free(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **tail_blk);
3333

3434
bool eblk_prepare(eblock_result_t *result, uint32_t elem_count);
3535
void eblk_truncate(eblock_result_t *result);
3636
void eblk_add_elem(eblock_result_t *result, eitem *elem);
37-
37+
void eblk_add_elem_with_posi(eblock_result_t *result, eitem *elem, int posi);
3838
#endif

engines/default/default_engine.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,13 +777,23 @@ default_btree_elem_alloc(ENGINE_HANDLE* handle, const void* cookie,
777777
return ret;
778778
}
779779

780+
#ifdef USE_EBLOCK_RESULT
781+
static void
782+
default_btree_elem_release(ENGINE_HANDLE* handle, const void *cookie,
783+
eitem *eitem, EITEM_TYPE type)
784+
{
785+
struct default_engine *engine = get_handle(handle);
786+
btree_elem_release(engine, eitem, type);
787+
}
788+
#else
780789
static void
781790
default_btree_elem_release(ENGINE_HANDLE* handle, const void *cookie,
782791
eitem **eitem_array, const int eitem_count)
783792
{
784793
struct default_engine *engine = get_handle(handle);
785794
btree_elem_release(engine, (btree_elem_item**)eitem_array, eitem_count);
786795
}
796+
#endif
787797

788798
static ENGINE_ERROR_CODE
789799
default_btree_elem_insert(ENGINE_HANDLE* handle, const void* cookie,
@@ -879,7 +889,11 @@ default_btree_elem_get(ENGINE_HANDLE* handle, const void* cookie,
879889
const bkey_range *bkrange, const eflag_filter *efilter,
880890
const uint32_t offset, const uint32_t req_count,
881891
const bool delete, const bool drop_if_empty,
892+
#ifdef USE_EBLOCK_RESULT
893+
eblock_result_t *eblk_ret,
894+
#else
882895
eitem** eitem_array, uint32_t* eitem_count,
896+
#endif
883897
uint32_t *access_count, uint32_t* flags,
884898
bool* dropped_trimmed, uint16_t vbucket)
885899
{
@@ -890,7 +904,11 @@ default_btree_elem_get(ENGINE_HANDLE* handle, const void* cookie,
890904
if (delete) ACTION_BEFORE_WRITE(cookie, key, nkey);
891905
ret = btree_elem_get(engine, key, nkey, bkrange, efilter,
892906
offset, req_count, delete, drop_if_empty,
907+
#ifdef USE_EBLOCK_RESULT
908+
eblk_ret,
909+
#else
893910
(btree_elem_item**)eitem_array, eitem_count,
911+
#endif
894912
access_count, flags, dropped_trimmed);
895913
if (delete) ACTION_AFTER_WRITE(cookie, ret);
896914
return ret;
@@ -932,17 +950,27 @@ default_btree_posi_find_with_get(ENGINE_HANDLE* handle, const void* cookie,
932950
const char *key, const size_t nkey,
933951
const bkey_range *bkrange,
934952
ENGINE_BTREE_ORDER order, const uint32_t count,
953+
#ifdef USE_EBLOCK_RESULT
954+
int *position, eblock_result_t *eblk_ret,
955+
uint32_t *eitem_index,
956+
#else
935957
int *position, eitem **eitem_array,
936958
uint32_t *eitem_count, uint32_t *eitem_index,
959+
#endif
937960
uint32_t *flags, uint16_t vbucket)
938961
{
939962
struct default_engine *engine = get_handle(handle);
940963
ENGINE_ERROR_CODE ret;
941964
VBUCKET_GUARD(engine, vbucket);
942965

943966
ret = btree_posi_find_with_get(engine, key, nkey, bkrange, order, count,
967+
#ifdef USE_EBLOCK_RESULT
968+
position, eblk_ret,
969+
eitem_index, flags);
970+
#else
944971
position, (btree_elem_item**)eitem_array,
945972
eitem_count, eitem_index, flags);
973+
#endif
946974
return ret;
947975
}
948976

@@ -951,15 +979,23 @@ default_btree_elem_get_by_posi(ENGINE_HANDLE* handle, const void* cookie,
951979
const char *key, const size_t nkey,
952980
ENGINE_BTREE_ORDER order,
953981
uint32_t from_posi, uint32_t to_posi,
982+
#ifdef USE_EBLOCK_RESULT
983+
eblock_result_t *eblk_ret,
984+
#else
954985
eitem **eitem_array, uint32_t *eitem_count,
986+
#endif
955987
uint32_t *flags, uint16_t vbucket)
956988
{
957989
struct default_engine *engine = get_handle(handle);
958990
ENGINE_ERROR_CODE ret;
959991
VBUCKET_GUARD(engine, vbucket);
960992

961993
ret = btree_elem_get_by_posi(engine, key, nkey, order, from_posi, to_posi,
994+
#ifdef USE_EBLOCK_RESULT
995+
eblk_ret,
996+
#else
962997
(btree_elem_item**)eitem_array, eitem_count,
998+
#endif
963999
flags);
9641000
return ret;
9651001
}
@@ -973,10 +1009,16 @@ default_btree_elem_smget_old(ENGINE_HANDLE* handle, const void* cookie,
9731009
const bkey_range *bkrange,
9741010
const eflag_filter *efilter,
9751011
const uint32_t offset, const uint32_t count,
1012+
#ifdef USE_EBLOCK_RESULT
1013+
eblock_result_t *eblk_ret,
1014+
uint32_t* kfnd_array,
1015+
uint32_t* flag_array,
1016+
#else
9761017
eitem** eitem_array,
9771018
uint32_t* kfnd_array,
9781019
uint32_t* flag_array,
9791020
uint32_t* eitem_count,
1021+
#endif
9801022
uint32_t* missed_key_array,
9811023
uint32_t* missed_key_count,
9821024
bool *trimmed, bool *duplicated,
@@ -987,8 +1029,13 @@ default_btree_elem_smget_old(ENGINE_HANDLE* handle, const void* cookie,
9871029
VBUCKET_GUARD(engine, vbucket);
9881030

9891031
ret = btree_elem_smget_old(engine, karray, kcount, bkrange, efilter,
1032+
#ifdef USE_EBLOCK_RESULT
1033+
offset, count, eblk_ret,
1034+
kfnd_array, flag_array,
1035+
#else
9901036
offset, count, (btree_elem_item**)eitem_array,
9911037
kfnd_array, flag_array, eitem_count,
1038+
#endif
9921039
missed_key_array, missed_key_count,
9931040
trimmed, duplicated);
9941041
return ret;

0 commit comments

Comments
 (0)