aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1994-11-16 16:09:11 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1994-11-16 16:09:11 -0200
commitd6a1699e37257c0b3d4651a481ce0bf597bc4e45 (patch)
tree11f8199151b5946e86eeac721674be888f07bd79
parenta5862498a19cc8a25ef22b29c1e7103c5c0466f8 (diff)
downloadlua-d6a1699e37257c0b3d4651a481ce0bf597bc4e45.tar.gz
lua-d6a1699e37257c0b3d4651a481ce0bf597bc4e45.tar.bz2
lua-d6a1699e37257c0b3d4651a481ce0bf597bc4e45.zip
uses a single list to keep allocated strings.
-rw-r--r--tree.c130
1 files 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 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_tree="$Id: tree.c,v 1.5 1994/11/16 16:03:48 roberto Exp roberto $"; 6char *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
20static TreeNode *string_root = NULL; 20typedef struct StringNode {
21 struct StringNode *next;
22 Word mark;
23 char str[1];
24} StringNode;
25
26static StringNode *string_root = NULL;
27
28
21static TreeNode *constant_root = NULL; 29static 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*/
26static TreeNode *tree_create (TreeNode **node, char *str, int *created) 34static 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
49char *lua_strcreate (char *str) 56char *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
61TreeNode *lua_constcreate (char *str)
62{
63 int created;
64 return tree_create(&constant_root, str, &created);
65}
66 69
67 70TreeNode *lua_constcreate (char *str)
68/*
69** Free a node of the tree
70*/
71static 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*/
121static 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*/
143void lua_strcollector (void) 80void 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/*