Skip to content

Commit 51384cc

Browse files
committed
Add detached node functions to ilist
These allow to test whether an element is in a list by checking whether prev/next are NULL. Needed to replace SHMQueueIsDetached() when converting from SHM_QUEUE to ilist.h style lists. Reviewed-by: Thomas Munro <thomas.munro@gmail.com> Discussion: https://postgr.es/m/20221120055930.t6kl3tyivzhlrzu2@awork3.anarazel.de Discussion: https://postgr.es/m/20200211042229.msv23badgqljrdg2@alap3.anarazel.de
1 parent 2b16208 commit 51384cc

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

src/include/lib/ilist.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,17 @@ dlist_init(dlist_head *head)
316316
head->head.next = head->head.prev = &head->head;
317317
}
318318

319+
/*
320+
* Initialize a doubly linked list element.
321+
*
322+
* This is only needed when dlist_node_is_detached() may be needed.
323+
*/
324+
static inline void
325+
dlist_node_init(dlist_node *node)
326+
{
327+
node->next = node->prev = NULL;
328+
}
329+
319330
/*
320331
* Is the list empty?
321332
*
@@ -397,6 +408,19 @@ dlist_delete(dlist_node *node)
397408
node->next->prev = node->prev;
398409
}
399410

411+
/*
412+
* Like dlist_delete(), but also sets next/prev to NULL to signal not being in
413+
* a list.
414+
*/
415+
static inline void
416+
dlist_delete_thoroughly(dlist_node *node)
417+
{
418+
node->prev->next = node->next;
419+
node->next->prev = node->prev;
420+
node->next = NULL;
421+
node->prev = NULL;
422+
}
423+
400424
/*
401425
* Same as dlist_delete, but performs checks in ILIST_DEBUG builds to ensure
402426
* that 'node' belongs to 'head'.
@@ -408,6 +432,17 @@ dlist_delete_from(dlist_head *head, dlist_node *node)
408432
dlist_delete(node);
409433
}
410434

435+
/*
436+
* Like dlist_delete_from, but also sets next/prev to NULL to signal not
437+
* being in a list.
438+
*/
439+
static inline void
440+
dlist_delete_from_thoroughly(dlist_head *head, dlist_node *node)
441+
{
442+
dlist_member_check(head, node);
443+
dlist_delete_thoroughly(node);
444+
}
445+
411446
/*
412447
* Remove and return the first node from a list (there must be one).
413448
*/
@@ -480,6 +515,21 @@ dlist_has_prev(const dlist_head *head, const dlist_node *node)
480515
return node->prev != &head->head;
481516
}
482517

518+
/*
519+
* Check if node is detached. A node is only detached if it either has been
520+
* initialized with dlist_init_node(), or deleted with
521+
* dlist_delete_thoroughly() / dlist_delete_from_thoroughly() /
522+
* dclist_delete_from_thoroughly().
523+
*/
524+
static inline bool
525+
dlist_node_is_detached(const dlist_node *node)
526+
{
527+
Assert((node->next == NULL && node->prev == NULL) ||
528+
(node->next != NULL && node->prev != NULL));
529+
530+
return node->next == NULL;
531+
}
532+
483533
/*
484534
* Return the next node in the list (there must be one).
485535
*/
@@ -718,6 +768,19 @@ dclist_delete_from(dclist_head *head, dlist_node *node)
718768
head->count--;
719769
}
720770

771+
/*
772+
* Like dclist_delete_from(), but also sets next/prev to NULL to signal not
773+
* being in a list.
774+
*/
775+
static inline void
776+
dclist_delete_from_thoroughly(dclist_head *head, dlist_node *node)
777+
{
778+
Assert(head->count > 0);
779+
780+
dlist_delete_from_thoroughly(&head->dlist, node);
781+
head->count--;
782+
}
783+
721784
/*
722785
* dclist_pop_head_node
723786
* Remove and return the first node from a list (there must be one).

0 commit comments

Comments
 (0)