2025-08-10 01:34:16 +02:00

268 lines
6.0 KiB
C

#ifndef POINTERLIST_H_
#define POINTERLIST_H_
#include <common/Common.h>
struct PointerListElem;
typedef struct PointerListElem PointerListElem;
struct PointerList;
typedef struct PointerList PointerList;
static inline void PointerList_init(PointerList* this);
static inline void PointerList_uninit(PointerList* this);
static inline void PointerList_addHead(PointerList* this, void* valuePointer);
static inline void PointerList_addTail(PointerList* this, void* valuePointer);
static inline void PointerList_append(PointerList* this, void* valuePointer);
static inline void PointerList_removeHead(PointerList* this);
static inline void PointerList_removeTail(PointerList* this);
static inline void PointerList_removeElem(PointerList* this, PointerListElem* elem);
static inline void PointerList_moveToHead(PointerList* this, PointerListElem* elem);
static inline void PointerList_moveToTail(PointerList* this, PointerListElem* elem);
static inline size_t PointerList_length(const PointerList* this);
static inline void PointerList_clear(PointerList* this);
static inline PointerListElem* PointerList_getTail(PointerList* this);
static inline PointerListElem* PointerList_getHead(PointerList* this);
struct PointerListElem
{
void* valuePointer;
struct PointerListElem* prev;
struct PointerListElem* next;
};
struct PointerList
{
struct PointerListElem* head;
struct PointerListElem* tail;
size_t length;
};
void PointerList_init(PointerList* this)
{
this->head = NULL;
this->tail = NULL;
this->length = 0;
}
void PointerList_uninit(PointerList* this)
{
PointerList_clear(this);
}
static inline void __PointerList_addHead(PointerList* this, PointerListElem* elem)
{
if(this->length)
{ // elements exist => replace head
elem->next = this->head;
this->head->prev = elem;
this->head = elem;
}
else
{ // no elements exist yet
this->head = elem;
this->tail = elem;
elem->next = NULL;
}
elem->prev = NULL;
this->length++;
}
void PointerList_addHead(PointerList* this, void* valuePointer)
{
PointerListElem* elem = (PointerListElem*)os_kmalloc(
sizeof(PointerListElem) );
elem->valuePointer = valuePointer;
__PointerList_addHead(this, elem);
}
static inline void __PointerList_addTail(PointerList* this, PointerListElem* elem)
{
if(this->length)
{ // elements exist => replace tail
elem->prev = this->tail;
this->tail->next = elem;
this->tail = elem;
}
else
{ // no elements exist yet
this->head = elem;
this->tail = elem;
elem->prev = NULL;
}
elem->next = NULL;
this->length++;
}
void PointerList_addTail(PointerList* this, void* valuePointer)
{
PointerListElem* elem = (PointerListElem*)os_kmalloc(sizeof(PointerListElem) );
elem->valuePointer = valuePointer;
__PointerList_addTail(this, elem);
}
void PointerList_append(PointerList* this, void* valuePointer)
{
PointerList_addTail(this, valuePointer);
}
static inline void __PointerList_removeHead(PointerList* this, bool freeElem)
{
#ifdef BEEGFS_DEBUG
if(!this->length)
{
BEEGFS_BUG_ON(true, "Attempt to remove head from empty list");
return;
}
#endif
if(this->length == 1)
{ // removing the last element
if (freeElem)
kfree(this->head);
this->head = NULL;
this->tail = NULL;
this->length = 0;
}
else
{ // there are more elements in the list
PointerListElem* newHead = this->head->next;
if (freeElem)
kfree(this->head);
this->head = newHead;
this->head->prev = NULL;
this->length--;
}
}
void PointerList_removeHead(PointerList* this)
{
__PointerList_removeHead(this, true);
}
static inline void __PointerList_removeTail(PointerList* this, bool freeElem)
{
#ifdef BEEGFS_DEBUG
if(!this->length)
{
BEEGFS_BUG_ON(true, "Attempt to remove tail from empty list");
return;
}
#endif
if(this->length == 1)
{ // removing the last element
if (freeElem)
kfree(this->tail);
this->head = NULL;
this->tail = NULL;
this->length = 0;
}
else
{ // there are more elements in the list
PointerListElem* newTail = this->tail->prev;
if (freeElem)
kfree(this->tail);
this->tail = newTail;
this->tail->next = NULL;
this->length--;
}
}
void PointerList_removeTail(PointerList* this)
{
__PointerList_removeTail(this, true);
}
static inline void __PointerList_removeElem(PointerList* this, PointerListElem* elem, bool freeElem)
{
if(elem == this->head)
__PointerList_removeHead(this, freeElem);
else
if(elem == this->tail)
__PointerList_removeTail(this, freeElem);
else
{
// not head and not tail, so this elem is somewhere in the middle
PointerListElem* prev = elem->prev;
PointerListElem* next = elem->next;
prev->next = next;
next->prev = prev;
if (freeElem)
kfree(elem);
this->length--;
}
}
void PointerList_removeElem(PointerList* this, PointerListElem* elem)
{
__PointerList_removeElem(this, elem, true);
}
size_t PointerList_length(const PointerList* this)
{
return this->length;
}
void PointerList_clear(PointerList* this)
{
// free all elems
PointerListElem* elem = this->head;
while(elem)
{
PointerListElem* next = elem->next;
kfree(elem);
elem = next;
}
// reset attributes
this->head = NULL;
this->tail = NULL;
this->length = 0;
}
PointerListElem* PointerList_getTail(PointerList* this)
{
return this->tail;
}
PointerListElem* PointerList_getHead(PointerList* this)
{
return this->head;
}
void PointerList_moveToHead(PointerList* this, PointerListElem *elem)
{
__PointerList_removeElem(this, elem, false);
__PointerList_addHead(this, elem);
}
void PointerList_moveToTail(PointerList* this, PointerListElem *elem)
{
__PointerList_removeElem(this, elem, false);
__PointerList_addTail(this, elem);
}
#endif /*POINTERLIST_H_*/