macro_inline void prefix ## _del_hint(struct prefix##_head *h, type *item, \
_Atomic atomptr_t *hint) \
{ atomlist_del_hint(&h->ah, &item->field.ai, hint); } \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
-{ atomlist_del_hint(&h->ah, &item->field.ai, NULL); } \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
+{ atomlist_del_hint(&h->ah, &item->field.ai, NULL); \
+ /* TODO: Return NULL if not found */ \
+ return item; } \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ char *p = (char *)atomlist_pop(&h->ah); \
return p ? (type *)(p - offsetof(type, field)) : NULL; } \
{ \
atomsort_del_hint(&h->ah, &item->field.ai, hint); \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
atomsort_del_hint(&h->ah, &item->field.ai, NULL); \
+ /* TODO: Return NULL if not found */ \
+ return item; \
} \
macro_inline size_t prefix ## _count(struct prefix##_head *h) \
{ \
int (*cmpfn)(
const struct typed_rb_entry *a,
const struct typed_rb_entry *b));
-void typed_rb_remove(struct typed_rb_root *, struct typed_rb_entry *rbe);
+struct typed_rb_entry *typed_rb_remove(struct typed_rb_root *,
+ struct typed_rb_entry *rbe);
struct typed_rb_entry *typed_rb_find(struct typed_rb_root *,
const struct typed_rb_entry *rbe,
int (*cmpfn)(
re = typed_rb_find_lt(&h->rr, &item->field.re, cmpfn_nuq); \
return container_of_null(re, type, field.re); \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
- typed_rb_remove(&h->rr, &item->field.re); \
+ struct typed_rb_entry *re; \
+ re = typed_rb_remove(&h->rr, &item->field.re); \
+ return container_of_null(re, type, field.re); \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
return best;
}
-void typesafe_skiplist_del(struct sskip_head *head, struct sskip_item *item,
- int (*cmpfn)(const struct sskip_item *a,
- const struct sskip_item *b))
+struct sskip_item *typesafe_skiplist_del(
+ struct sskip_head *head, struct sskip_item *item,
+ int (*cmpfn)(const struct sskip_item *a, const struct sskip_item *b))
{
size_t level = SKIPLIST_MAXDEPTH;
struct sskip_item *prev = &head->hitem, *next;
int cmpval;
+ bool found = false;
while (level) {
next = sl_level_get(prev, level - 1);
sl_level_set(prev, level - 1,
sl_level_get(item, level - 1));
level--;
+ found = true;
continue;
}
cmpval = cmpfn(next, item);
level--;
}
+ if (!found)
+ return NULL;
+
/* TBD: assert when trying to remove non-existing item? */
head->count--;
XFREE(MTYPE_SKIPLIST_OFLOW, oflow);
}
memset(item, 0, sizeof(*item));
+
+ return item;
}
struct sskip_item *typesafe_skiplist_pop(struct sskip_head *head)
typesafe_list_add(&h->sh, nextp, &item->field.si); \
} \
/* TODO: del_hint */ \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
struct slist_item **iter = &h->sh.first; \
while (*iter && *iter != &item->field.si) \
iter = &(*iter)->next; \
if (!*iter) \
- return; \
+ return NULL; \
h->sh.count--; \
*iter = item->field.si.next; \
if (!item->field.si.next) \
h->sh.last_next = iter; \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
prev = after ? &after->field.di : &h->dh.hitem; \
typesafe_dlist_add(&h->dh, prev, &item->field.di); \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
struct dlist_item *ditem = &item->field.di; \
ditem->prev->next = ditem->next; \
ditem->next->prev = ditem->prev; \
h->dh.count--; \
ditem->prev = ditem->next = NULL; \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
h->hh.count++; \
return NULL; \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
struct heap_item *other; \
uint32_t index = item->field.hi.index; \
typesafe_heap_pushdown(&h->hh, index, other, prefix ## __cmp); \
if (HEAP_RESIZE_TRESH_DN(h)) \
typesafe_heap_resize(&h->hh, false); \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
return container_of_null(prev, type, field.si); \
} \
/* TODO: del_hint */ \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
struct ssort_item **iter = &h->sh.first; \
while (*iter && *iter != &item->field.si) \
iter = &(*iter)->next; \
if (!*iter) \
- return; \
+ return NULL; \
h->sh.count--; \
*iter = item->field.si.next; \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
} \
return NULL; \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
if (!h->hh.tabshift) \
- return; \
+ return NULL; \
uint32_t hval = item->field.hi.hashval, hbits = HASH_KEY(h->hh, hval); \
struct thash_item **np = &h->hh.entries[hbits]; \
while (*np && (*np)->hashval < hval) \
while (*np && *np != &item->field.hi && (*np)->hashval == hval) \
np = &(*np)->next; \
if (*np != &item->field.hi) \
- return; \
+ return NULL; \
*np = item->field.hi.next; \
item->field.hi.next = NULL; \
h->hh.count--; \
if (HASH_SHRINK_THRESHOLD(h->hh)) \
typesafe_hash_shrink(&h->hh); \
+ return item; \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
&item->field.si, cmpfn_nuq); \
return container_of_null(sitem, type, field.si); \
} \
-macro_inline void prefix ## _del(struct prefix##_head *h, type *item) \
+macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \
{ \
- typesafe_skiplist_del(&h->sh, &item->field.si, cmpfn_uq); \
+ struct sskip_item *sitem = typesafe_skiplist_del(&h->sh, \
+ &item->field.si, cmpfn_uq); \
+ return container_of_null(sitem, type, field.si); \
} \
macro_inline type *prefix ## _pop(struct prefix##_head *h) \
{ \
const struct sskip_item *item, int (*cmpfn)(
const struct sskip_item *a,
const struct sskip_item *b));
-extern void typesafe_skiplist_del(struct sskip_head *head,
- struct sskip_item *item, int (*cmpfn)(
+extern struct sskip_item *typesafe_skiplist_del(
+ struct sskip_head *head, struct sskip_item *item, int (*cmpfn)(
const struct sskip_item *a,
const struct sskip_item *b));
extern struct sskip_item *typesafe_skiplist_pop(struct sskip_head *head);