From b064b7e6af8ffb8c32b5c920a8a6c387e393f4a7 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 1 Oct 2021 16:20:34 -0700 Subject: [PATCH] Get rid of cache doubly linked list --- match.c | 42 ++++++++++++++++++------------------------ match.h | 12 ++++-------- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/match.c b/match.c index 71660ca..aa00592 100644 --- a/match.c +++ b/match.c @@ -54,31 +54,25 @@ __attribute__((returns_nonnull)) static match_t *new_match(pat_t *pat, const char *start, const char *end, match_t *children[]); // Prepend to a doubly linked list -static inline void list_prepend(match_t **head, match_t *m, match_dll_t *node) +static inline void gc_list_prepend(match_t **head, match_t *m) { - if (node->home) + if (m->gc.home) errx(1, "Node already has a home"); - node->home = head; - node->next = *head; - if (*head) { - match_dll_t *head_node = (match_dll_t*)((char*)(*head) + ((char*)node - (char*)m)); - head_node->home = &node->next; - } + m->gc.home = head; + m->gc.next = *head; + if (*head) (*head)->gc.home = &m->gc.next; *head = m; } // Remove from a doubly linked list -static inline void list_remove(match_t *m, match_dll_t *node) +static inline void gc_list_remove(match_t *m) { - if (!node->home) + if (!m->gc.home) errx(1, "Attempt to remove something that isn't in a list"); - *node->home = node->next; - if (node->next) { - match_dll_t *next_node = (match_dll_t*)((char*)(node->next) + ((char*)node - (char*)m)); - next_node->home = node->home; - } - node->home = NULL; - node->next = NULL; + *m->gc.home = m->gc.next; + if (m->gc.next) m->gc.next->gc.home = m->gc.home; + m->gc.home = NULL; + m->gc.next = NULL; } // @@ -669,13 +663,13 @@ match_t *new_match(pat_t *pat, const char *start, const char *end, match_t *chil match_t *m; if (unused_matches) { m = unused_matches; - list_remove(m, &m->gc); + gc_list_remove(m); memset(m, 0, sizeof(match_t)); } else { m = new(match_t); } // Keep track of the object: - list_prepend(&in_use_matches, m, &m->gc); + gc_list_prepend(&in_use_matches, m); m->pat = pat; m->start = start; @@ -703,9 +697,9 @@ void recycle_match(match_t **at_m) delete(&m->children); } - list_remove(m, &m->gc); + gc_list_remove(m); (void)memset(m, 0, sizeof(match_t)); - list_prepend(&unused_matches, m, &m->gc); + gc_list_prepend(&unused_matches, m); *at_m = NULL; } @@ -716,10 +710,10 @@ size_t recycle_all_matches(void) { size_t count = 0; for (match_t *m; (m = in_use_matches); ++count) { - list_remove(m, &m->gc); + gc_list_remove(m); if (m->children && m->children != m->_children) delete(&m->children); - list_prepend(&unused_matches, m, &m->gc); + gc_list_prepend(&unused_matches, m); } return count; } @@ -732,7 +726,7 @@ size_t free_all_matches(void) size_t count = 0; recycle_all_matches(); for (match_t *m; (m = unused_matches); ++count) { - list_remove(m, &m->gc); + gc_list_remove(m); delete(&m); } return count; diff --git a/match.h b/match.h index a31d923..93f2ade 100644 --- a/match.h +++ b/match.h @@ -9,12 +9,6 @@ #include "pattern.h" -struct match_s; // forward declared to resolve circular struct defs - -typedef struct { - struct match_s **home, *next; -} match_dll_t; - // // Pattern matching result object // @@ -22,8 +16,10 @@ typedef struct match_s { // Where the match starts and ends (end is after the last character) const char *start, *end; pat_t *pat; - // Intrusive linked list nodes for garbage collection and cache buckets: - match_dll_t gc, cache; + // Intrusive linked list node for garbage collection: + struct { + struct match_s **home, *next; + } gc; struct match_s **children; struct match_s *_children[3]; } match_t;