2 ** $Id: ltable.c,v 1.22 1999/05/21 19:41:49 roberto Exp $
4 ** See Copyright Notice in lua.h
17 #define gcsize(n) (1+(n/16))
19 #define nuse(t) ((t)->nuse)
20 #define nodevector(t) ((t)->node)
23 #define TagDefault LUA_T_ARRAY;
27 static long int hashindex (TObject
*ref
) {
31 h
= (long int)nvalue(ref
);
33 case LUA_T_STRING
: case LUA_T_USERDATA
:
34 h
= (IntPoint
)tsvalue(ref
);
37 h
= (IntPoint
)avalue(ref
);
40 h
= (IntPoint
)tfvalue(ref
);
43 h
= (IntPoint
)fvalue(ref
);
46 h
= (IntPoint
)clvalue(ref
);
49 lua_error("unexpected type to index table");
50 h
= 0; /* to avoid warnings */
52 return (h
>= 0 ? h
: -(h
+1));
56 Node
*luaH_present (Hash
*t
, TObject
*key
) {
58 long int h
= hashindex(key
);
60 Node
*n
= node(t
, h1
);
61 /* keep looking until an entry with "ref" equal to key or nil */
62 while ((ttype(ref(n
)) == ttype(key
)) ? !luaO_equalval(key
, ref(n
))
63 : ttype(ref(n
)) != LUA_T_NIL
) {
64 h1
+= (h
&(tsize
-2)) + 1; /* double hashing */
65 if (h1
>= tsize
) h1
-= tsize
;
72 void luaH_free (Hash
*frees
) {
74 Hash
*next
= (Hash
*)frees
->head
.next
;
75 L
->nblocks
-= gcsize(frees
->nhash
);
76 luaM_free(nodevector(frees
));
83 static Node
*hashnodecreate (int nhash
) {
84 Node
*v
= luaM_newvector(nhash
, Node
);
86 for (i
=0; i
<nhash
; i
++)
87 ttype(ref(&v
[i
])) = ttype(val(&v
[i
])) = LUA_T_NIL
;
92 Hash
*luaH_new (int nhash
) {
93 Hash
*t
= luaM_new(Hash
);
94 nhash
= luaO_redimension(nhash
*3/2);
95 nodevector(t
) = hashnodecreate(nhash
);
99 luaO_insertlist(&(L
->roottable
), (GCnode
*)t
);
100 L
->nblocks
+= gcsize(nhash
);
105 static int newsize (Hash
*t
) {
110 for (i
=0; i
<size
; i
++) {
111 if (ttype(val(v
+i
)) != LUA_T_NIL
)
114 return luaO_redimension((realuse
+1)*2); /* +1 is the new element */
118 static void rehash (Hash
*t
) {
120 Node
*vold
= nodevector(t
);
121 int nnew
= newsize(t
);
123 nodevector(t
) = hashnodecreate(nnew
);
126 for (i
=0; i
<nold
; i
++) {
128 if (ttype(val(n
)) != LUA_T_NIL
) {
129 *luaH_present(t
, ref(n
)) = *n
; /* copy old node to new hash */
133 L
->nblocks
+= gcsize(nnew
)-gcsize(nold
);
138 void luaH_set (Hash
*t
, TObject
*ref
, TObject
*val
) {
139 Node
*n
= luaH_present(t
, ref
);
140 if (ttype(ref(n
)) != LUA_T_NIL
)
144 buff
= *val
; /* rehash may invalidate this address */
145 if ((long)nuse(t
)*3L > (long)nhash(t
)*2L) {
147 n
= luaH_present(t
, ref
);
156 int luaH_pos (Hash
*t
, TObject
*r
) {
157 Node
*n
= luaH_present(t
, r
);
158 luaL_arg_check(ttype(val(n
)) != LUA_T_NIL
, 2, "key not found");
163 void luaH_setint (Hash
*t
, int ref
, TObject
*val
) {
165 ttype(&index
) = LUA_T_NUMBER
;
166 nvalue(&index
) = ref
;
167 luaH_set(t
, &index
, val
);
171 TObject
*luaH_getint (Hash
*t
, int ref
) {
173 ttype(&index
) = LUA_T_NUMBER
;
174 nvalue(&index
) = ref
;
175 return luaH_get(t
, &index
);