mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
garbage collector implemented but untested. Also unsused because the issue is
WHEN to call it. I don't imagine it will be cheap :/
This commit is contained in:
parent
4489319298
commit
97bf8d2c51
2 changed files with 49 additions and 11 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue