diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-16 16:09:11 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-16 16:09:11 -0200 |
| commit | d6a1699e37257c0b3d4651a481ce0bf597bc4e45 (patch) | |
| tree | 11f8199151b5946e86eeac721674be888f07bd79 | |
| parent | a5862498a19cc8a25ef22b29c1e7103c5c0466f8 (diff) | |
| download | lua-d6a1699e37257c0b3d4651a481ce0bf597bc4e45.tar.gz lua-d6a1699e37257c0b3d4651a481ce0bf597bc4e45.tar.bz2 lua-d6a1699e37257c0b3d4651a481ce0bf597bc4e45.zip | |
uses a single list to keep allocated strings.
| -rw-r--r-- | tree.c | 130 |
1 files changed, 42 insertions, 88 deletions
| @@ -3,7 +3,7 @@ | |||
| 3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | char *rcs_tree="$Id: tree.c,v 1.5 1994/11/16 16:03:48 roberto Exp roberto $"; | 6 | char *rcs_tree="$Id: tree.c,v 1.6 1994/11/16 17:38:08 roberto Exp roberto $"; |
| 7 | 7 | ||
| 8 | 8 | ||
| 9 | #include <string.h> | 9 | #include <string.h> |
| @@ -17,13 +17,21 @@ char *rcs_tree="$Id: tree.c,v 1.5 1994/11/16 16:03:48 roberto Exp roberto $"; | |||
| 17 | #define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) | 17 | #define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) |
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | static TreeNode *string_root = NULL; | 20 | typedef struct StringNode { |
| 21 | struct StringNode *next; | ||
| 22 | Word mark; | ||
| 23 | char str[1]; | ||
| 24 | } StringNode; | ||
| 25 | |||
| 26 | static StringNode *string_root = NULL; | ||
| 27 | |||
| 28 | |||
| 21 | static TreeNode *constant_root = NULL; | 29 | static TreeNode *constant_root = NULL; |
| 22 | 30 | ||
| 23 | /* | 31 | /* |
| 24 | ** Insert a new string/constant/variable at the tree. | 32 | ** Insert a new constant/variable at the tree. |
| 25 | */ | 33 | */ |
| 26 | static TreeNode *tree_create (TreeNode **node, char *str, int *created) | 34 | static TreeNode *tree_create (TreeNode **node, char *str) |
| 27 | { | 35 | { |
| 28 | if (*node == NULL) | 36 | if (*node == NULL) |
| 29 | { | 37 | { |
| @@ -31,16 +39,15 @@ static TreeNode *tree_create (TreeNode **node, char *str, int *created) | |||
| 31 | (*node)->left = (*node)->right = NULL; | 39 | (*node)->left = (*node)->right = NULL; |
| 32 | strcpy((*node)->str, str); | 40 | strcpy((*node)->str, str); |
| 33 | (*node)->varindex = (*node)->constindex = UNMARKED_STRING; | 41 | (*node)->varindex = (*node)->constindex = UNMARKED_STRING; |
| 34 | *created = 1; | ||
| 35 | return *node; | 42 | return *node; |
| 36 | } | 43 | } |
| 37 | else | 44 | else |
| 38 | { | 45 | { |
| 39 | int c = lua_strcmp(str, (*node)->str); | 46 | int c = lua_strcmp(str, (*node)->str); |
| 40 | if (c < 0) | 47 | if (c < 0) |
| 41 | return tree_create(&(*node)->left, str, created); | 48 | return tree_create(&(*node)->left, str); |
| 42 | else if (c > 0) | 49 | else if (c > 0) |
| 43 | return tree_create(&(*node)->right, str, created); | 50 | return tree_create(&(*node)->right, str); |
| 44 | else | 51 | else |
| 45 | return *node; | 52 | return *node; |
| 46 | } | 53 | } |
| @@ -48,101 +55,48 @@ static TreeNode *tree_create (TreeNode **node, char *str, int *created) | |||
| 48 | 55 | ||
| 49 | char *lua_strcreate (char *str) | 56 | char *lua_strcreate (char *str) |
| 50 | { | 57 | { |
| 51 | int created=0; | 58 | StringNode *newString = (StringNode *)luaI_malloc(sizeof(StringNode)+ |
| 52 | TreeNode *t = tree_create(&string_root, str, &created); | 59 | strlen(str)); |
| 53 | if (created) | 60 | newString->mark = UNMARKED_STRING; |
| 54 | { | 61 | strcpy(newString->str, str); |
| 62 | newString->next = string_root; | ||
| 63 | string_root = newString; | ||
| 55 | if (lua_nentity == lua_block) lua_pack (); | 64 | if (lua_nentity == lua_block) lua_pack (); |
| 56 | lua_nentity++; | 65 | lua_nentity++; |
| 57 | } | 66 | return newString->str; |
| 58 | return t->str; | ||
| 59 | } | 67 | } |
| 60 | 68 | ||
| 61 | TreeNode *lua_constcreate (char *str) | ||
| 62 | { | ||
| 63 | int created; | ||
| 64 | return tree_create(&constant_root, str, &created); | ||
| 65 | } | ||
| 66 | 69 | ||
| 67 | 70 | TreeNode *lua_constcreate (char *str) | |
| 68 | /* | ||
| 69 | ** Free a node of the tree | ||
| 70 | */ | ||
| 71 | static TreeNode *lua_strfree (TreeNode *parent) | ||
| 72 | { | ||
| 73 | if (parent->left == NULL && parent->right == NULL) /* no child */ | ||
| 74 | { | ||
| 75 | luaI_free(parent); | ||
| 76 | return NULL; | ||
| 77 | } | ||
| 78 | else if (parent->left == NULL) /* only right child */ | ||
| 79 | { | ||
| 80 | TreeNode *p = parent->right; | ||
| 81 | luaI_free(parent); | ||
| 82 | return p; | ||
| 83 | } | ||
| 84 | else if (parent->right == NULL) /* only left child */ | ||
| 85 | { | ||
| 86 | TreeNode *p = parent->left; | ||
| 87 | luaI_free(parent); | ||
| 88 | return p; | ||
| 89 | } | ||
| 90 | else /* two children */ | ||
| 91 | { | ||
| 92 | TreeNode *p = parent, *r = parent->right; | ||
| 93 | while (r->left != NULL) | ||
| 94 | { | ||
| 95 | p = r; | ||
| 96 | r = r->left; | ||
| 97 | } | ||
| 98 | if (p == parent) | ||
| 99 | { | ||
| 100 | r->left = parent->left; | ||
| 101 | parent->left = NULL; | ||
| 102 | parent->right = r->right; | ||
| 103 | r->right = lua_strfree(parent); | ||
| 104 | } | ||
| 105 | else | ||
| 106 | { | ||
| 107 | TreeNode *t = r->right; | ||
| 108 | r->left = parent->left; | ||
| 109 | r->right = parent->right; | ||
| 110 | parent->left = NULL; | ||
| 111 | parent->right = t; | ||
| 112 | p->left = lua_strfree(parent); | ||
| 113 | } | ||
| 114 | return r; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | /* | ||
| 119 | ** Traverse tree for garbage collection | ||
| 120 | */ | ||
| 121 | static TreeNode *lua_travcollector (TreeNode *r) | ||
| 122 | { | 71 | { |
| 123 | if (r == NULL) return NULL; | 72 | return tree_create(&constant_root, str); |
| 124 | r->right = lua_travcollector(r->right); | ||
| 125 | r->left = lua_travcollector(r->left); | ||
| 126 | if (r->constindex == UNMARKED_STRING) | ||
| 127 | { | ||
| 128 | ++lua_recovered; | ||
| 129 | return lua_strfree(r); | ||
| 130 | } | ||
| 131 | else | ||
| 132 | { | ||
| 133 | r->constindex = UNMARKED_STRING; | ||
| 134 | return r; | ||
| 135 | } | ||
| 136 | } | 73 | } |
| 137 | 74 | ||
| 138 | 75 | ||
| 139 | /* | 76 | /* |
| 140 | ** Garbage collection function. | 77 | ** Garbage collection function. |
| 141 | ** This function traverse the tree freening unindexed strings | 78 | ** This function traverse the string list freeing unindexed strings |
| 142 | */ | 79 | */ |
| 143 | void lua_strcollector (void) | 80 | void lua_strcollector (void) |
| 144 | { | 81 | { |
| 145 | string_root = lua_travcollector(string_root); | 82 | StringNode *curr = string_root, *prev = NULL; |
| 83 | while (curr) | ||
| 84 | { | ||
| 85 | StringNode *next = curr->next; | ||
| 86 | if (curr->mark == UNMARKED_STRING) | ||
| 87 | { | ||
| 88 | if (prev == NULL) string_root = next; | ||
| 89 | else prev->next = next; | ||
| 90 | luaI_free(curr); | ||
| 91 | ++lua_recovered; | ||
| 92 | } | ||
| 93 | else | ||
| 94 | { | ||
| 95 | curr->mark = UNMARKED_STRING; | ||
| 96 | prev = curr; | ||
| 97 | } | ||
| 98 | curr = next; | ||
| 99 | } | ||
| 146 | } | 100 | } |
| 147 | 101 | ||
| 148 | /* | 102 | /* |
