From 97bf8d2c510036e4e9731dbb9dd1152870e9f01a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Mar 2001 05:29:46 +0000 Subject: [PATCH] garbage collector implemented but untested. Also unsused because the issue is WHEN to call it. I don't imagine it will be cheap :/ --- include/progs.h | 2 +- libs/gamecode/pr_strings.c | 58 +++++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/include/progs.h b/include/progs.h index cfd24c057..78228d8bc 100644 --- a/include/progs.h +++ b/include/progs.h @@ -196,7 +196,7 @@ struct progs_s { // garbage collected strings strref_t *static_strings; - strref_t dynamic_strings[2]; // 0 = head, 1 = tail + strref_t dynamic_strings; // head of linked list; struct hashtab_s *strref_hash; int num_strings; diff --git a/libs/gamecode/pr_strings.c b/libs/gamecode/pr_strings.c index 2477627f7..b21c89734 100644 --- a/libs/gamecode/pr_strings.c +++ b/libs/gamecode/pr_strings.c @@ -59,7 +59,8 @@ strref_free (void *_sr, void *_pr) if (sr < pr->static_strings || sr >= pr->static_strings + pr->num_strings) { free (sr->string); - sr->next->prev = sr->prev; + if (sr->next) + sr->next->prev = sr->prev; sr->prev->next = sr->next; free (sr); @@ -83,10 +84,8 @@ PR_LoadStrings (progs_t *pr) pr->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free, pr); } - pr->dynamic_strings[0].next = &pr->dynamic_strings[1]; - pr->dynamic_strings[0].prev = 0; - pr->dynamic_strings[1].next = 0; - pr->dynamic_strings[1].prev = &pr->dynamic_strings[1]; + pr->dynamic_strings.next = 0; + pr->dynamic_strings.prev = 0; if (pr->static_strings) free (pr->static_strings); @@ -102,6 +101,42 @@ PR_LoadStrings (progs_t *pr) pr->num_strings = count; } +void +PR_GarbageCollect (progs_t *pr) +{ + strref_t *sr; + ddef_t *def; + int i, j; + + for (sr = pr->dynamic_strings.next; sr; sr = sr->next) + sr->count = 0; + for (i = 0; i < pr->progs->numglobaldefs; i++) { + def = &pr->pr_globaldefs[i]; + if ((def->type & ~DEF_SAVEGLOBAL) == ev_string) { + sr = Hash_Find (pr->strref_hash, G_STRING (pr, def->ofs)); + if (sr) + sr->count++; + } + } + for (i = 0; i < pr->progs->numfielddefs; i++) { + def = &pr->pr_fielddefs[i]; + if ((def->type & ~DEF_SAVEGLOBAL) == ev_string) { + for (j = 0; j < *pr->num_edicts; j++) { + sr = Hash_Find (pr->strref_hash, + E_STRING (pr, EDICT_NUM (pr, j), def->ofs)); + if (sr) + sr->count++; + } + } + } + for (sr = pr->dynamic_strings.next; sr; sr = sr->next) { + if (sr->count) { + Hash_Del (pr->strref_hash, sr->string); + strref_free (sr, pr); + } + } +} + char * PR_GetString (progs_t *pr, int num) { @@ -120,11 +155,14 @@ PR_SetString (progs_t *pr, char *s) sr->string = strdup(s); sr->count = 0; - sr->next = pr->dynamic_strings[0].next; - sr->prev = pr->dynamic_strings[0].next->prev; - - pr->dynamic_strings[0].next->prev = sr; - pr->dynamic_strings[0].next = sr; + sr->next = pr->dynamic_strings.next; + if (pr->dynamic_strings.next) { + sr->prev = pr->dynamic_strings.next->prev; + pr->dynamic_strings.next->prev = sr; + } else { + sr->prev = &pr->dynamic_strings; + } + pr->dynamic_strings.next = sr; Hash_Add (pr->strref_hash, sr);