Created
May 11, 2021 10:18
-
-
Save louisswarren/94eb78713a9eeda312b9f5adc6149a4a to your computer and use it in GitHub Desktop.
Linked list pool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#define POOL_NODE_HEADERS struct pool_node *prev, *next | |
struct pool_node { | |
POOL_NODE_HEADERS; | |
}; | |
struct pool { | |
size_t node_size; | |
size_t capacity; | |
size_t len; | |
void *head; | |
void *insert_p; | |
char nodes[]; | |
}; | |
struct int_node { | |
POOL_NODE_HEADERS; | |
int value; | |
}; | |
size_t | |
pool_size(size_t node_size, size_t capacity) | |
{ | |
if (node_size > (SIZE_MAX - sizeof(struct pool)) / capacity) | |
return 0; | |
return sizeof(struct pool) + node_size * capacity; | |
} | |
void | |
pool_init(struct pool *p, size_t node_size, size_t capacity) | |
{ | |
p->node_size = node_size; | |
p->capacity = capacity; | |
p->len = 0; | |
p->head = NULL; | |
p->insert_p = p->nodes; | |
} | |
struct pool_node * | |
pool_add(struct pool *p, void *node) | |
{ | |
struct pool_node *new; | |
if ((void *) p->nodes + p->node_size * p->capacity <= p->insert_p) { | |
if (p->len < p->capacity) { | |
fprintf(stderr, "Reflow not implemented\n"); | |
return NULL; | |
} else { | |
fprintf(stderr, "No room left\n"); | |
return NULL; | |
} | |
} | |
memcpy(p->insert_p, node, p->node_size); | |
new = (struct pool_node *) p->insert_p; | |
new->prev = NULL; | |
new->next = (struct pool_node *)p->head; | |
p->head = p->insert_p; | |
p->len++; | |
p->insert_p += p->node_size; | |
return new; | |
} | |
void | |
pool_remove(struct pool *p, void *node) | |
{ | |
struct pool_node *n = node; | |
if (p->head == node) | |
p->head = n->next; | |
if (n->prev != NULL) | |
n->prev->next = n->next; | |
if (n->next != NULL) | |
n->next->prev = n->prev; | |
} | |
int | |
main(void) | |
{ | |
struct int_node n; | |
struct pool *p = malloc(pool_size(sizeof(struct int_node), 5)); | |
pool_init(p, sizeof(struct int_node), 5); | |
n.value = 1; pool_add(p, &n); | |
n.value = 2; pool_add(p, &n); | |
n.value = 3; pool_add(p, &n); | |
n.value = 4; pool_add(p, &n); | |
n.value = 5; pool_add(p, &n); | |
for (struct int_node *n = p->head; n != NULL; n = n->next) { | |
printf("%d\n", n->value); | |
} | |
printf("\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment