aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2021-10-01 16:20:34 -0700
committerBruce Hill <bruce@bruce-hill.com>2021-10-01 16:20:34 -0700
commitb064b7e6af8ffb8c32b5c920a8a6c387e393f4a7 (patch)
tree840814c8427f39502fdaf5955d30f148a7019d71
parent1bdf8f4f40548dc1c273b09ebdd2a7153adf94ec (diff)
Get rid of cache doubly linked list
-rw-r--r--match.c42
-rw-r--r--match.h12
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;