/* ------------------------------------------------------------------------- * * dllist.h * simple doubly linked list primitives * the elements of the list are void* so the lists can contain anything * Dlelem can only be in one list at a time * * * Here's a small example of how to use Dllists: * * Dllist *lst; * Dlelem *elt; * void *in_stuff; -- stuff to stick in the list * void *out_stuff * * lst = DLNewList(); -- make a new dllist * DLAddHead(lst, DLNewElem(in_stuff)); -- add a new element to the list * with in_stuff as the value * ... * elt = DLGetHead(lst); -- retrieve the head element * out_stuff = (void*)DLE_VAL(elt); -- get the stuff out * DLRemove(elt); -- removes the element from its list * DLFreeElem(elt); -- free the element since we don't * use it anymore * * * It is also possible to use Dllist objects that are embedded in larger * structures instead of being separately malloc'd. To do this, use * DLInitElem() to initialize a Dllist field within a larger object. * Don't forget to DLRemove() each field from its list (if any) before * freeing the larger object! * * * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/lib/dllist.h * * ------------------------------------------------------------------------- */ #ifndef DLLIST_H #define DLLIST_H struct Dllist; struct Dlelem; typedef struct Dlelem { struct Dlelem* dle_next; /* next element */ struct Dlelem* dle_prev; /* previous element */ void* dle_val; /* value of the element */ struct Dllist* dle_list; /* what list this element is in */ } Dlelem; typedef struct Dllist { Dlelem *dll_head; Dlelem *dll_tail; uint64 dll_len; } Dllist; class DllistWithLock : public BaseObject { public: DllistWithLock(); ~DllistWithLock(); void Remove(Dlelem* e) { (void)RemoveConfirm(e); } bool RemoveConfirm(Dlelem* e); void AddHead(Dlelem* e); void AddTail(Dlelem* e); Dlelem* RemoveHead(); Dlelem* RemoveHeadNoLock(); Dlelem* RemoveTail(); bool IsEmpty(); Dlelem* GetHead(); void GetLock(); void ReleaseLock(); inline uint64 GetLength() { return m_list.dll_len; } private: slock_t m_lock; Dllist m_list; }; extern Dllist* DLNewList(void); /* allocate and initialize a list header */ extern void DLInitList(Dllist* list); /* init a header alloced by caller */ extern void DLFreeList(Dllist* list); /* free up a list and all the nodes in * it */ extern void DLListConcat(Dllist* a, Dllist* b); extern Dlelem* DLNewElem(void* val); extern void DLInitElem(Dlelem* e, void* val); extern void DLFreeElem(Dlelem* e); extern void DLRemove(Dlelem* e); /* removes node from list */ extern void DLAddHead(Dllist* list, Dlelem* node); extern void DLAddTail(Dllist* list, Dlelem* node); extern Dlelem* DLRemHead(Dllist* list); /* remove and return the head */ extern Dlelem* DLRemTail(Dllist* list); extern void DLMoveToFront(Dlelem* e); /* move node to front of its list */ extern uint64 DLListLength(Dllist* list); /* These are macros for speed */ #define DLGetHead(list) ((list)->dll_head) #define DLGetTail(list) ((list)->dll_tail) #define DLIsNIL(list) ((list)->dll_head == NULL) #define DLGetSucc(elem) ((elem)->dle_next) #define DLGetPred(elem) ((elem)->dle_prev) #define DLGetListHdr(elem) ((elem)->dle_list) #define DLE_VAL(elem) ((elem)->dle_val) #endif /* DLLIST_H */