aboutsummaryrefslogtreecommitdiff
path: root/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'tree.c')
-rw-r--r--tree.c152
1 files changed, 92 insertions, 60 deletions
diff --git a/tree.c b/tree.c
index f511436a..3b82dc9a 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.14 1995/10/17 11:53:53 roberto Exp roberto $"; 6char *rcs_tree="$Id: tree.c,v 1.15 1996/01/26 18:03:19 roberto Exp $";
7 7
8 8
9#include <string.h> 9#include <string.h>
@@ -11,68 +11,98 @@ char *rcs_tree="$Id: tree.c,v 1.14 1995/10/17 11:53:53 roberto Exp roberto $";
11#include "mem.h" 11#include "mem.h"
12#include "lua.h" 12#include "lua.h"
13#include "tree.h" 13#include "tree.h"
14#include "hash.h"
14#include "table.h" 15#include "table.h"
15 16
16 17
17#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) 18#define lua_streq(a,b) (a[0] == b[0] && strcmp(a,b) == 0)
18 19
20#define NUM_HASHS 64
19 21
20typedef struct StringNode { 22typedef struct {
21 struct StringNode *next; 23 int size;
22 TaggedString ts; 24 int nuse; /* number of elements (including EMPTYs) */
23} StringNode; 25 TaggedString **hash;
26} stringtable;
24 27
25static StringNode *string_root = NULL; 28static stringtable string_root[NUM_HASHS];
26 29
27static TreeNode *constant_root = NULL; 30static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 0, {0}};
28 31
29/* 32static unsigned long hash (char *str)
30** Insert a new constant/variable at the tree.
31*/
32static TreeNode *tree_create (TreeNode **node, char *str)
33{ 33{
34 if (*node == NULL) 34 unsigned long h = 0;
35 { 35 while (*str)
36 *node = (TreeNode *) luaI_malloc(sizeof(TreeNode)+strlen(str)); 36 h = ((h<<5)-h)^(unsigned char)*(str++);
37 (*node)->left = (*node)->right = NULL; 37 return h;
38 strcpy((*node)->ts.str, str);
39 (*node)->ts.marked = 0;
40 (*node)->ts.hash = 0;
41 (*node)->varindex = (*node)->constindex = NOT_USED;
42 return *node;
43 }
44 else
45 {
46 int c = lua_strcmp(str, (*node)->ts.str);
47 if (c < 0)
48 return tree_create(&(*node)->left, str);
49 else if (c > 0)
50 return tree_create(&(*node)->right, str);
51 else
52 return *node;
53 }
54} 38}
55 39
56TaggedString *lua_createstring (char *str) 40static void grow (stringtable *tb)
57{ 41{
58 StringNode *newString; 42 int newsize = luaI_redimension(tb->size);
59 if (str == NULL) return NULL; 43 TaggedString **newhash = newvector(newsize, TaggedString *);
60 lua_pack(); 44 int i;
61 newString = (StringNode *)luaI_malloc(sizeof(StringNode)+strlen(str)); 45 for (i=0; i<newsize; i++)
62 newString->ts.marked = 0; 46 newhash[i] = NULL;
63 newString->ts.hash = 0; 47 if (tb->size > 0)
64 strcpy(newString->ts.str, str); 48 { /* rehash */
65 newString->next = string_root; 49 tb->nuse = 0;
66 string_root = newString; 50 for (i=0; i<tb->size; i++)
67 return &(newString->ts); 51 if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
52 {
53 int h = tb->hash[i]->hash%newsize;
54 while (newhash[h])
55 h = (h+1)%newsize;
56 newhash[h] = tb->hash[i];
57 tb->nuse++;
58 }
59 luaI_free(tb->hash);
60 }
61 tb->size = newsize;
62 tb->hash = newhash;
68} 63}
69 64
65static TaggedString *insert (char *str, stringtable *tb)
66{
67 TaggedString *ts;
68 unsigned long h = hash(str);
69 int i;
70 int j = -1;
71 if ((Long)tb->nuse*3 >= (Long)tb->size*2)
72 grow(tb);
73 i = h%tb->size;
74 while (tb->hash[i])
75 {
76 if (tb->hash[i] == &EMPTY)
77 j = i;
78 else if (lua_streq(str, tb->hash[i]->str))
79 return tb->hash[i];
80 i = (i+1)%tb->size;
81 }
82 /* not found */
83 if (j != -1) /* is there an EMPTY space? */
84 i = j;
85 else
86 tb->nuse++;
87 ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str));
88 strcpy(ts->str, str);
89 ts->marked = 0;
90 ts->hash = h;
91 ts->varindex = ts->constindex = NOT_USED;
92 return ts;
93}
70 94
71TreeNode *lua_constcreate (char *str) 95TaggedString *lua_createstring (char *str)
72{ 96{
73 return tree_create(&constant_root, str); 97 return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]);
74} 98}
75 99
100TaggedString *luaI_createfixedstring (char *str)
101{
102 TaggedString *ts = lua_createstring(str);
103 ts->marked = 2; /* to avoid GC */
104 return ts;
105}
76 106
77/* 107/*
78** Garbage collection function. 108** Garbage collection function.
@@ -80,26 +110,28 @@ TreeNode *lua_constcreate (char *str)
80*/ 110*/
81Long lua_strcollector (void) 111Long lua_strcollector (void)
82{ 112{
83 StringNode *curr = string_root, *prev = NULL;
84 Long counter = 0; 113 Long counter = 0;
85 while (curr) 114 int i;
115 for (i=0; i<NUM_HASHS; i++)
86 { 116 {
87 StringNode *next = curr->next; 117 stringtable *tb = &string_root[i];
88 if (!curr->ts.marked) 118 int j;
89 { 119 for (j=0; j<tb->size; j++)
90 if (prev == NULL) string_root = next;
91 else prev->next = next;
92 luaI_free(curr);
93 ++counter;
94 }
95 else
96 { 120 {
97 curr->ts.marked = 0; 121 TaggedString *t = tb->hash[j];
98 prev = curr; 122 if (t != NULL && t != &EMPTY && t->marked != 2)
123 {
124 if (t->marked)
125 t->marked = 0;
126 else
127 {
128 luaI_free(t);
129 tb->hash[j] = &EMPTY;
130 counter++;
131 }
132 }
99 } 133 }
100 curr = next;
101 } 134 }
102 return counter; 135 return counter;
103} 136}
104 137
105