Skip to content

Commit 81076b9

Browse files
committed
INTERNAL: Unify elem lifecycle state management with status field
Add status field to list/set/map elem items and replace the ADDR_MEANS_UNLINKED sentinel pointer pattern with ELEM_STATUS_USED/ UNLINK/FREE, consistent with btree. The shared defines are placed in item_base.h since all four collections use identical lifecycle states.
1 parent 58ae7c3 commit 81076b9

5 files changed

Lines changed: 64 additions & 51 deletions

File tree

engines/default/coll_btree.c

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,6 @@ static inline void UNLOCK_CACHE(void)
6262
#define BKEY_RANGE_TYPE_ASC 2 /* ascending bkey range */
6363
#define BKEY_RANGE_TYPE_DSC 3 /* descending bkey range */
6464

65-
/* btree item status */
66-
#define BTREE_ITEM_STATUS_USED 2
67-
#define BTREE_ITEM_STATUS_UNLINK 1
68-
#define BTREE_ITEM_STATUS_FREE 0
69-
7065
/* overflow type */
7166
#define OVFL_TYPE_NONE 0
7267
#define OVFL_TYPE_COUNT 1
@@ -289,7 +284,7 @@ static btree_elem_item *do_btree_elem_alloc(const uint32_t nbkey, const uint32_t
289284
assert(elem->slabs_clsid > 0);
290285

291286
elem->refcount = 0;
292-
elem->status = BTREE_ITEM_STATUS_UNLINK; /* unlinked state */
287+
elem->status = ELEM_STATUS_UNLINK; /* unlinked state */
293288
elem->nbkey = (uint8_t)nbkey;
294289
elem->neflag = (uint8_t)neflag;
295290
elem->nbytes = (uint16_t)nbytes;
@@ -307,12 +302,12 @@ static void do_btree_elem_free(btree_elem_item *elem)
307302

308303
static void do_btree_elem_release(btree_elem_item *elem)
309304
{
310-
/* assert(elem->status != BTREE_ITEM_STATUS_FREE); */
305+
/* assert(elem->status != ELEM_STATUS_FREE); */
311306
if (elem->refcount != 0) {
312307
elem->refcount--;
313308
}
314-
if (elem->refcount == 0 && elem->status == BTREE_ITEM_STATUS_UNLINK) {
315-
elem->status = BTREE_ITEM_STATUS_FREE;
309+
if (elem->refcount == 0 && elem->status == ELEM_STATUS_UNLINK) {
310+
elem->status = ELEM_STATUS_FREE;
316311
do_btree_elem_free(elem);
317312
}
318313
}
@@ -1667,9 +1662,9 @@ static void do_btree_elem_unlink(btree_meta_info *info, btree_elem_posi *path,
16671662
CLOG_BTREE_ELEM_DELETE(info, elem, cause);
16681663

16691664
if (elem->refcount > 0) {
1670-
elem->status = BTREE_ITEM_STATUS_UNLINK;
1665+
elem->status = ELEM_STATUS_UNLINK;
16711666
} else {
1672-
elem->status = BTREE_ITEM_STATUS_FREE;
1667+
elem->status = ELEM_STATUS_FREE;
16731668
do_btree_elem_free(elem);
16741669
}
16751670

@@ -1704,13 +1699,13 @@ static void do_btree_elem_replace(btree_meta_info *info,
17041699
CLOG_BTREE_ELEM_INSERT(info, old_elem, new_elem);
17051700

17061701
if (old_elem->refcount > 0) {
1707-
old_elem->status = BTREE_ITEM_STATUS_UNLINK;
1702+
old_elem->status = ELEM_STATUS_UNLINK;
17081703
} else {
1709-
old_elem->status = BTREE_ITEM_STATUS_FREE;
1704+
old_elem->status = ELEM_STATUS_FREE;
17101705
do_btree_elem_free(old_elem);
17111706
}
17121707

1713-
new_elem->status = BTREE_ITEM_STATUS_USED;
1708+
new_elem->status = ELEM_STATUS_USED;
17141709
posi->node->item[posi->indx] = new_elem;
17151710

17161711
if (new_stotal != old_stotal) { /* apply memory space */
@@ -1851,9 +1846,9 @@ static int do_btree_elem_delete_fast(btree_meta_info *info,
18511846
for (i = 0; i < node->used_count; i++) {
18521847
elem = (btree_elem_item *)node->item[i];
18531848
if (elem->refcount > 0) {
1854-
elem->status = BTREE_ITEM_STATUS_UNLINK;
1849+
elem->status = ELEM_STATUS_UNLINK;
18551850
} else {
1856-
elem->status = BTREE_ITEM_STATUS_FREE;
1851+
elem->status = ELEM_STATUS_FREE;
18571852
do_btree_elem_free(elem);
18581853
}
18591854
}
@@ -1946,9 +1941,9 @@ static uint32_t do_btree_elem_delete(btree_meta_info *info,
19461941

19471942
CLOG_BTREE_ELEM_DELETE(info, elem, cause);
19481943
if (elem->refcount > 0) {
1949-
elem->status = BTREE_ITEM_STATUS_UNLINK;
1944+
elem->status = ELEM_STATUS_UNLINK;
19501945
} else {
1951-
elem->status = BTREE_ITEM_STATUS_FREE;
1946+
elem->status = ELEM_STATUS_FREE;
19521947
do_btree_elem_free(elem);
19531948
}
19541949
c_posi.node->item[c_posi.indx] = NULL;
@@ -2245,7 +2240,7 @@ static ENGINE_ERROR_CODE do_btree_elem_link(btree_meta_info *info, btree_elem_it
22452240
CLOG_BTREE_ELEM_INSERT(info, NULL, elem);
22462241

22472242
/* insert the element into the leaf page */
2248-
elem->status = BTREE_ITEM_STATUS_USED;
2243+
elem->status = ELEM_STATUS_USED;
22492244
if (path[0].indx < path[0].node->used_count) {
22502245
for (int i = (path[0].node->used_count-1); i >= path[0].indx; i--) {
22512246
path[0].node->item[i+1] = path[0].node->item[i];
@@ -2395,7 +2390,7 @@ static uint32_t do_btree_elem_get(btree_meta_info *info,
23952390
elem_array[tot_found+cur_found] = elem;
23962391
if (delete) {
23972392
tot_space += slabs_space_size(do_btree_elem_ntotal(elem));
2398-
elem->status = BTREE_ITEM_STATUS_UNLINK;
2393+
elem->status = ELEM_STATUS_UNLINK;
23992394
c_posi.node->item[c_posi.indx] = NULL;
24002395
CLOG_BTREE_ELEM_DELETE(info, elem, ELEM_DELETE_NORMAL);
24012396
}
@@ -3692,8 +3687,8 @@ btree_elem_item *btree_elem_alloc(const uint32_t nbkey, const uint32_t neflag, c
36923687
void btree_elem_free(btree_elem_item *elem)
36933688
{
36943689
LOCK_CACHE();
3695-
assert(elem->status == BTREE_ITEM_STATUS_UNLINK);
3696-
elem->status = BTREE_ITEM_STATUS_FREE;
3690+
assert(elem->status == ELEM_STATUS_UNLINK);
3691+
elem->status = ELEM_STATUS_FREE;
36973692
do_btree_elem_free(elem);
36983693
UNLOCK_CACHE();
36993694
}

engines/default/coll_list.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static list_elem_item *do_list_elem_alloc(const uint32_t nbytes, const void *coo
132132

133133
elem->refcount = 0;
134134
elem->nbytes = nbytes;
135-
elem->prev = elem->next = (list_elem_item *)ADDR_MEANS_UNLINKED; /* Unliked state */
135+
elem->status = ELEM_STATUS_UNLINK; /* unlinked state */
136136
}
137137
return elem;
138138
}
@@ -150,7 +150,8 @@ static void do_list_elem_release(list_elem_item *elem)
150150
if (elem->refcount != 0) {
151151
elem->refcount--;
152152
}
153-
if (elem->refcount == 0 && elem->next == (list_elem_item *)ADDR_MEANS_UNLINKED) {
153+
if (elem->refcount == 0 && elem->status == ELEM_STATUS_UNLINK) {
154+
elem->status = ELEM_STATUS_FREE;
154155
do_list_elem_free(elem);
155156
}
156157
}
@@ -198,6 +199,7 @@ static ENGINE_ERROR_CODE do_list_elem_link(list_meta_info *info, const int index
198199
else prev->next = elem;
199200
if (next == NULL) info->tail = elem;
200201
else next->prev = elem;
202+
elem->status = ELEM_STATUS_USED;
201203
info->ccnt++;
202204

203205
if (1) { /* apply memory space */
@@ -210,23 +212,21 @@ static ENGINE_ERROR_CODE do_list_elem_link(list_meta_info *info, const int index
210212
static void do_list_elem_unlink(list_meta_info *info, list_elem_item *elem,
211213
enum elem_delete_cause cause)
212214
{
213-
/* if (elem->next != (list_elem_item *)ADDR_MEANS_UNLINKED) */
214-
{
215-
if (elem->prev == NULL) info->head = elem->next;
216-
else elem->prev->next = elem->next;
217-
if (elem->next == NULL) info->tail = elem->prev;
218-
else elem->next->prev = elem->prev;
219-
elem->prev = elem->next = (list_elem_item *)ADDR_MEANS_UNLINKED;
220-
info->ccnt--;
221-
222-
if (info->stotal > 0) { /* apply memory space */
223-
size_t stotal = slabs_space_size(do_list_elem_ntotal(elem));
224-
do_coll_space_decr((coll_meta_info *)info, ITEM_TYPE_LIST, stotal);
225-
}
215+
if (elem->prev == NULL) info->head = elem->next;
216+
else elem->prev->next = elem->next;
217+
if (elem->next == NULL) info->tail = elem->prev;
218+
else elem->next->prev = elem->prev;
219+
elem->status = ELEM_STATUS_UNLINK;
220+
info->ccnt--;
226221

227-
if (elem->refcount == 0) {
228-
do_list_elem_free(elem);
229-
}
222+
if (info->stotal > 0) { /* apply memory space */
223+
size_t stotal = slabs_space_size(do_list_elem_ntotal(elem));
224+
do_coll_space_decr((coll_meta_info *)info, ITEM_TYPE_LIST, stotal);
225+
}
226+
227+
if (elem->refcount == 0) {
228+
elem->status = ELEM_STATUS_FREE;
229+
do_list_elem_free(elem);
230230
}
231231
}
232232

@@ -390,7 +390,8 @@ list_elem_item *list_elem_alloc(const uint32_t nbytes, const void *cookie)
390390
void list_elem_free(list_elem_item *elem)
391391
{
392392
LOCK_CACHE();
393-
assert(elem->next == (list_elem_item *)ADDR_MEANS_UNLINKED);
393+
assert(elem->status == ELEM_STATUS_UNLINK);
394+
elem->status = ELEM_STATUS_FREE;
394395
do_list_elem_free(elem);
395396
UNLOCK_CACHE();
396397
}

engines/default/coll_map.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ static map_elem_item *do_map_elem_alloc(const int nfield,
177177
elem->refcount = 0;
178178
elem->nfield = (uint8_t)nfield;
179179
elem->nbytes = (uint16_t)nbytes;
180-
elem->next = (map_elem_item *)ADDR_MEANS_UNLINKED; /* Unliked state */
180+
elem->status = ELEM_STATUS_UNLINK; /* unlinked state */
181181
}
182182
return elem;
183183
}
@@ -195,7 +195,8 @@ static void do_map_elem_release(map_elem_item *elem)
195195
if (elem->refcount != 0) {
196196
elem->refcount--;
197197
}
198-
if (elem->refcount == 0 && elem->next == (map_elem_item *)ADDR_MEANS_UNLINKED) {
198+
if (elem->refcount == 0 && elem->status == ELEM_STATUS_UNLINK) {
199+
elem->status = ELEM_STATUS_FREE;
199200
do_map_elem_free(elem);
200201
}
201202
}
@@ -313,9 +314,11 @@ static void do_map_elem_replace(map_meta_info *info,
313314
} else {
314315
pinfo->node->htab[pinfo->hidx] = new_elem;
315316
}
317+
new_elem->status = ELEM_STATUS_USED;
316318

317-
old_elem->next = (map_elem_item *)ADDR_MEANS_UNLINKED;
319+
old_elem->status = ELEM_STATUS_UNLINK;
318320
if (old_elem->refcount == 0) {
321+
old_elem->status = ELEM_STATUS_FREE;
319322
do_map_elem_free(old_elem);
320323
}
321324

@@ -413,6 +416,7 @@ static ENGINE_ERROR_CODE do_map_elem_link(map_meta_info *info, map_elem_item *el
413416
node->htab[hidx] = elem;
414417
node->hcnt[hidx] += 1;
415418
node->cur_elem_cnt += 1;
419+
elem->status = ELEM_STATUS_USED;
416420

417421
info->ccnt++;
418422

@@ -431,7 +435,7 @@ static void do_map_elem_unlink(map_meta_info *info,
431435
{
432436
if (prev != NULL) prev->next = elem->next;
433437
else node->htab[hidx] = elem->next;
434-
elem->next = (map_elem_item *)ADDR_MEANS_UNLINKED;
438+
elem->status = ELEM_STATUS_UNLINK;
435439
node->hcnt[hidx] -= 1;
436440
node->cur_elem_cnt -= 1;
437441
info->ccnt--;
@@ -444,6 +448,7 @@ static void do_map_elem_unlink(map_meta_info *info,
444448
}
445449

446450
if (elem->refcount == 0) {
451+
elem->status = ELEM_STATUS_FREE;
447452
do_map_elem_free(elem);
448453
}
449454
}
@@ -748,7 +753,8 @@ map_elem_item *map_elem_alloc(const int nfield, const uint32_t nbytes, const voi
748753
void map_elem_free(map_elem_item *elem)
749754
{
750755
LOCK_CACHE();
751-
assert(elem->next == (map_elem_item *)ADDR_MEANS_UNLINKED);
756+
assert(elem->status == ELEM_STATUS_UNLINK);
757+
elem->status = ELEM_STATUS_FREE;
752758
do_map_elem_free(elem);
753759
UNLOCK_CACHE();
754760
}

engines/default/coll_set.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ static set_elem_item *do_set_elem_alloc(const uint32_t nbytes, const void *cooki
223223

224224
elem->refcount = 0;
225225
elem->nbytes = nbytes;
226-
elem->next = (set_elem_item *)ADDR_MEANS_UNLINKED; /* Unliked state */
226+
elem->status = ELEM_STATUS_UNLINK; /* unlinked state */
227227
}
228228
return elem;
229229
}
@@ -241,7 +241,8 @@ static void do_set_elem_release(set_elem_item *elem)
241241
if (elem->refcount != 0) {
242242
elem->refcount--;
243243
}
244-
if (elem->refcount == 0 && elem->next == (set_elem_item *)ADDR_MEANS_UNLINKED) {
244+
if (elem->refcount == 0 && elem->status == ELEM_STATUS_UNLINK) {
245+
elem->status = ELEM_STATUS_FREE;
245246
do_set_elem_free(elem);
246247
}
247248
}
@@ -367,6 +368,7 @@ static ENGINE_ERROR_CODE do_set_elem_link(set_meta_info *info, set_elem_item *el
367368
node->htab[hidx] = elem;
368369
node->hcnt[hidx] += 1;
369370
node->tot_elem_cnt += 1;
371+
elem->status = ELEM_STATUS_USED;
370372

371373
set_hash_node *par_node = info->root;
372374
while (par_node != node) {
@@ -392,7 +394,7 @@ static void do_set_elem_unlink(set_meta_info *info,
392394
{
393395
if (prev != NULL) prev->next = elem->next;
394396
else node->htab[hidx] = elem->next;
395-
elem->next = (set_elem_item *)ADDR_MEANS_UNLINKED;
397+
elem->status = ELEM_STATUS_UNLINK;
396398
node->hcnt[hidx] -= 1;
397399
node->tot_elem_cnt -= 1;
398400
info->ccnt--;
@@ -405,6 +407,7 @@ static void do_set_elem_unlink(set_meta_info *info,
405407
}
406408

407409
if (elem->refcount == 0) {
410+
elem->status = ELEM_STATUS_FREE;
408411
do_set_elem_free(elem);
409412
}
410413
}
@@ -772,7 +775,8 @@ set_elem_item *set_elem_alloc(const uint32_t nbytes, const void *cookie)
772775
void set_elem_free(set_elem_item *elem)
773776
{
774777
LOCK_CACHE();
775-
assert(elem->next == (set_elem_item *)ADDR_MEANS_UNLINKED);
778+
assert(elem->status == ELEM_STATUS_UNLINK);
779+
elem->status = ELEM_STATUS_FREE;
776780
do_set_elem_free(elem);
777781
UNLOCK_CACHE();
778782
}

engines/default/item_base.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ enum elem_delete_cause {
144144
/* special address for representing unlinked status */
145145
#define ADDR_MEANS_UNLINKED 1
146146

147+
/* collection element lifecycle status */
148+
#define ELEM_STATUS_USED 2
149+
#define ELEM_STATUS_UNLINK 1
150+
#define ELEM_STATUS_FREE 0
151+
147152
/* hash item strtucture */
148153
typedef struct _hash_item {
149154
uint16_t refcount; /* reference count */
@@ -167,7 +172,7 @@ typedef struct _hash_item {
167172
typedef struct _list_elem_item {
168173
uint16_t refcount;
169174
uint8_t slabs_clsid; /* which slab class we're in */
170-
uint32_t dummy;
175+
uint8_t status; /* element lifecycle state: used(in-list), unlinked(removed but referenced), or free */
171176
struct _list_elem_item *next; /* next chain in double linked list */
172177
struct _list_elem_item *prev; /* prev chain in double linked list */
173178
uint32_t nbytes; /**< The total size of the data (in bytes) */
@@ -178,6 +183,7 @@ typedef struct _list_elem_item {
178183
typedef struct _set_elem_item {
179184
uint16_t refcount;
180185
uint8_t slabs_clsid; /* which slab class we're in */
186+
uint8_t status; /* element lifecycle state: used(in-set), unlinked(removed but referenced), or free */
181187
uint32_t hval; /* hash value */
182188
struct _set_elem_item *next; /* hash chain next */
183189
uint32_t nbytes; /**< The total size of the data (in bytes) */
@@ -188,6 +194,7 @@ typedef struct _set_elem_item {
188194
typedef struct _map_elem_item {
189195
uint16_t refcount;
190196
uint8_t slabs_clsid; /* which slab class we're in */
197+
uint8_t status; /* element lifecycle state: used(in-map), unlinked(removed but referenced), or free */
191198
uint32_t hval; /* hash value */
192199
struct _map_elem_item *next; /* hash chain next */
193200
uint8_t nfield; /**< The total size of the field (in bytes) */

0 commit comments

Comments
 (0)