6 char *rcs_tree
="$Id: tree.c,v 1.28 1997/06/11 14:24:40 roberto Exp $";
24 int nuse
; /* number of elements (including EMPTYs) */
28 static int initialized
= 0;
30 static stringtable string_root
[NUM_HASHS
];
32 static TaggedString EMPTY
= {LUA_T_STRING
, NULL
, {{NOT_USED
, NOT_USED
}},
36 static unsigned long hash (char *s
, int tag
)
39 if (tag
!= LUA_T_STRING
)
44 h
= ((h
<<5)-h
)^(unsigned char)*(s
++);
50 static void luaI_inittree (void)
53 for (i
=0; i
<NUM_HASHS
; i
++) {
54 string_root
[i
].size
= 0;
55 string_root
[i
].nuse
= 0;
56 string_root
[i
].hash
= NULL
;
61 static void initialize (void)
72 static void grow (stringtable
*tb
)
74 int newsize
= luaI_redimension(tb
->size
);
75 TaggedString
**newhash
= newvector(newsize
, TaggedString
*);
77 for (i
=0; i
<newsize
; i
++)
81 for (i
=0; i
<tb
->size
; i
++)
82 if (tb
->hash
[i
] != NULL
&& tb
->hash
[i
] != &EMPTY
) {
83 int h
= tb
->hash
[i
]->hash
%newsize
;
86 newhash
[h
] = tb
->hash
[i
];
95 static TaggedString
*newone(char *buff
, int tag
, unsigned long h
)
98 if (tag
== LUA_T_STRING
) {
99 ts
= (TaggedString
*)luaI_malloc(sizeof(TaggedString
)+strlen(buff
));
100 strcpy(ts
->str
, buff
);
101 ts
->u
.s
.varindex
= ts
->u
.s
.constindex
= NOT_USED
;
102 ts
->tag
= LUA_T_STRING
;
105 ts
= (TaggedString
*)luaI_malloc(sizeof(TaggedString
));
107 ts
->tag
= tag
== LUA_ANYTAG
? 0 : tag
;
114 static TaggedString
*insert (char *buff
, int tag
, stringtable
*tb
)
117 unsigned long h
= hash(buff
, tag
);
120 if ((Long
)tb
->nuse
*3 >= (Long
)tb
->size
*2)
127 while ((ts
= tb
->hash
[i
]) != NULL
)
131 else if ((ts
->tag
== LUA_T_STRING
) ?
132 (tag
== LUA_T_STRING
&& (strcmp(buff
, ts
->str
) == 0)) :
133 ((tag
== ts
->tag
|| tag
== LUA_ANYTAG
) && buff
== ts
->u
.v
))
139 if (j
!= -1) /* is there an EMPTY space? */
143 ts
= tb
->hash
[i
] = newone(buff
, tag
, h
);
147 TaggedString
*luaI_createudata (void *udata
, int tag
)
149 return insert(udata
, tag
, &string_root
[(unsigned)udata
%NUM_HASHS
]);
152 TaggedString
*lua_createstring (char *str
)
154 return insert(str
, LUA_T_STRING
, &string_root
[(unsigned)str
[0]%NUM_HASHS
]);
158 void luaI_strcallIM (TaggedString
*l
)
161 ttype(&o
) = LUA_T_USERDATA
;
162 for (; l
; l
=l
->next
) {
169 void luaI_strfree (TaggedString
*l
)
172 TaggedString
*next
= l
->next
;
180 ** Garbage collection function.
182 TaggedString
*luaI_strcollector (long *acum
)
185 TaggedString
*frees
= NULL
;
187 for (i
=0; i
<NUM_HASHS
; i
++)
189 stringtable
*tb
= &string_root
[i
];
191 for (j
=0; j
<tb
->size
; j
++)
193 TaggedString
*t
= tb
->hash
[j
];
194 if (t
!= NULL
&& t
->marked
<= 1)
202 tb
->hash
[j
] = &EMPTY
;