From d6a1699e37257c0b3d4651a481ce0bf597bc4e45 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 16 Nov 1994 16:09:11 -0200 Subject: [PATCH] uses a single list to keep allocated strings. --- tree.c | 130 +++++++++++++++++++-------------------------------------- 1 file changed, 42 insertions(+), 88 deletions(-) diff --git a/tree.c b/tree.c index 6e1c0b2a..e58a7dca 100644 --- a/tree.c +++ b/tree.c @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_tree="$Id: tree.c,v 1.5 1994/11/16 16:03:48 roberto Exp roberto $"; +char *rcs_tree="$Id: tree.c,v 1.6 1994/11/16 17:38:08 roberto Exp roberto $"; #include @@ -17,13 +17,21 @@ char *rcs_tree="$Id: tree.c,v 1.5 1994/11/16 16:03:48 roberto Exp roberto $"; #define lua_strcmp(a,b) (a[0]b[0]?(1):strcmp(a,b))) -static TreeNode *string_root = NULL; +typedef struct StringNode { + struct StringNode *next; + Word mark; + char str[1]; +} StringNode; + +static StringNode *string_root = NULL; + + static TreeNode *constant_root = NULL; /* -** Insert a new string/constant/variable at the tree. +** Insert a new constant/variable at the tree. */ -static TreeNode *tree_create (TreeNode **node, char *str, int *created) +static TreeNode *tree_create (TreeNode **node, char *str) { if (*node == NULL) { @@ -31,16 +39,15 @@ static TreeNode *tree_create (TreeNode **node, char *str, int *created) (*node)->left = (*node)->right = NULL; strcpy((*node)->str, str); (*node)->varindex = (*node)->constindex = UNMARKED_STRING; - *created = 1; return *node; } else { int c = lua_strcmp(str, (*node)->str); if (c < 0) - return tree_create(&(*node)->left, str, created); + return tree_create(&(*node)->left, str); else if (c > 0) - return tree_create(&(*node)->right, str, created); + return tree_create(&(*node)->right, str); else return *node; } @@ -48,101 +55,48 @@ static TreeNode *tree_create (TreeNode **node, char *str, int *created) char *lua_strcreate (char *str) { - int created=0; - TreeNode *t = tree_create(&string_root, str, &created); - if (created) - { + StringNode *newString = (StringNode *)luaI_malloc(sizeof(StringNode)+ + strlen(str)); + newString->mark = UNMARKED_STRING; + strcpy(newString->str, str); + newString->next = string_root; + string_root = newString; if (lua_nentity == lua_block) lua_pack (); lua_nentity++; - } - return t->str; + return newString->str; } + TreeNode *lua_constcreate (char *str) { - int created; - return tree_create(&constant_root, str, &created); -} - - -/* -** Free a node of the tree -*/ -static TreeNode *lua_strfree (TreeNode *parent) -{ - if (parent->left == NULL && parent->right == NULL) /* no child */ - { - luaI_free(parent); - return NULL; - } - else if (parent->left == NULL) /* only right child */ - { - TreeNode *p = parent->right; - luaI_free(parent); - return p; - } - else if (parent->right == NULL) /* only left child */ - { - TreeNode *p = parent->left; - luaI_free(parent); - return p; - } - else /* two children */ - { - TreeNode *p = parent, *r = parent->right; - while (r->left != NULL) - { - p = r; - r = r->left; - } - if (p == parent) - { - r->left = parent->left; - parent->left = NULL; - parent->right = r->right; - r->right = lua_strfree(parent); - } - else - { - TreeNode *t = r->right; - r->left = parent->left; - r->right = parent->right; - parent->left = NULL; - parent->right = t; - p->left = lua_strfree(parent); - } - return r; - } -} - -/* -** Traverse tree for garbage collection -*/ -static TreeNode *lua_travcollector (TreeNode *r) -{ - if (r == NULL) return NULL; - r->right = lua_travcollector(r->right); - r->left = lua_travcollector(r->left); - if (r->constindex == UNMARKED_STRING) - { - ++lua_recovered; - return lua_strfree(r); - } - else - { - r->constindex = UNMARKED_STRING; - return r; - } + return tree_create(&constant_root, str); } /* ** Garbage collection function. -** This function traverse the tree freening unindexed strings +** This function traverse the string list freeing unindexed strings */ void lua_strcollector (void) { - string_root = lua_travcollector(string_root); + StringNode *curr = string_root, *prev = NULL; + while (curr) + { + StringNode *next = curr->next; + if (curr->mark == UNMARKED_STRING) + { + if (prev == NULL) string_root = next; + else prev->next = next; + luaI_free(curr); + ++lua_recovered; + } + else + { + curr->mark = UNMARKED_STRING; + prev = curr; + } + curr = next; + } } /*