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 | /* |