diff options
Diffstat (limited to 'lstring.c')
| -rw-r--r-- | lstring.c | 72 |
1 files changed, 23 insertions, 49 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 1.61 2001/02/23 17:17:25 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.62 2001/03/26 14:31:49 roberto Exp roberto $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -17,22 +17,15 @@ | |||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | void luaS_init (lua_State *L) { | ||
| 21 | luaS_resize(L, &G(L)->strt, MINPOWER2); | ||
| 22 | luaS_resize(L, &G(L)->udt, MINPOWER2); | ||
| 23 | } | ||
| 24 | |||
| 25 | |||
| 26 | void luaS_freeall (lua_State *L) { | 20 | void luaS_freeall (lua_State *L) { |
| 27 | lua_assert(G(L)->strt.nuse==0); | 21 | lua_assert(G(L)->strt.nuse==0); |
| 28 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); | 22 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); |
| 29 | lua_assert(G(L)->udt.nuse==0); | ||
| 30 | luaM_freearray(L, G(L)->udt.hash, G(L)->udt.size, TString *); | ||
| 31 | } | 23 | } |
| 32 | 24 | ||
| 33 | 25 | ||
| 34 | void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | 26 | void luaS_resize (lua_State *L, int newsize) { |
| 35 | TString **newhash = luaM_newvector(L, newsize, TString *); | 27 | TString **newhash = luaM_newvector(L, newsize, TString *); |
| 28 | stringtable *tb = &G(L)->strt; | ||
| 36 | int i; | 29 | int i; |
| 37 | for (i=0; i<newsize; i++) newhash[i] = NULL; | 30 | for (i=0; i<newsize; i++) newhash[i] = NULL; |
| 38 | /* rehash */ | 31 | /* rehash */ |
| @@ -40,7 +33,7 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
| 40 | TString *p = tb->hash[i]; | 33 | TString *p = tb->hash[i]; |
| 41 | while (p) { /* for each node in the list */ | 34 | while (p) { /* for each node in the list */ |
| 42 | TString *next = p->nexthash; /* save next */ | 35 | TString *next = p->nexthash; /* save next */ |
| 43 | lu_hash h = (tb == &G(L)->strt) ? p->u.s.hash : IntPoint(p->u.d.value); | 36 | lu_hash h = p->hash; |
| 44 | int h1 = lmod(h, newsize); /* new position */ | 37 | int h1 = lmod(h, newsize); /* new position */ |
| 45 | lua_assert((int)(h%newsize) == lmod(h, newsize)); | 38 | lua_assert((int)(h%newsize) == lmod(h, newsize)); |
| 46 | p->nexthash = newhash[h1]; /* chain it in new position */ | 39 | p->nexthash = newhash[h1]; /* chain it in new position */ |
| @@ -54,16 +47,6 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
| 54 | } | 47 | } |
| 55 | 48 | ||
| 56 | 49 | ||
| 57 | static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) { | ||
| 58 | ts->nexthash = tb->hash[h]; /* chain new entry */ | ||
| 59 | tb->hash[h] = ts; | ||
| 60 | tb->nuse++; | ||
| 61 | if (tb->nuse > (ls_nstr)tb->size && tb->size <= MAX_INT/2) /* too crowded? */ | ||
| 62 | luaS_resize(L, tb, tb->size*2); | ||
| 63 | } | ||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l) { | 50 | TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l) { |
| 68 | TString *ts; | 51 | TString *ts; |
| 69 | lu_hash h = l; /* seed */ | 52 | lu_hash h = l; /* seed */ |
| @@ -80,39 +63,30 @@ TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l) { | |||
| 80 | ts->marked = 0; | 63 | ts->marked = 0; |
| 81 | ts->nexthash = NULL; | 64 | ts->nexthash = NULL; |
| 82 | ts->len = l; | 65 | ts->len = l; |
| 83 | ts->u.s.hash = h; | 66 | ts->hash = h; |
| 84 | ts->u.s.constindex = 0; | 67 | ts->constindex = 0; |
| 85 | memcpy(getstr(ts), str, l*sizeof(l_char)); | 68 | memcpy(getstr(ts), str, l*sizeof(l_char)); |
| 86 | getstr(ts)[l] = 0; /* ending 0 */ | 69 | getstr(ts)[l] = 0; /* ending 0 */ |
| 87 | newentry(L, &G(L)->strt, ts, lmod(h, G(L)->strt.size)); /* insert it */ | 70 | h = lmod(h, G(L)->strt.size); |
| 71 | ts->nexthash = G(L)->strt.hash[h]; /* chain new entry */ | ||
| 72 | G(L)->strt.hash[h] = ts; | ||
| 73 | G(L)->strt.nuse++; | ||
| 74 | if (G(L)->strt.nuse > (ls_nstr)G(L)->strt.size && | ||
| 75 | G(L)->strt.size <= MAX_INT/2) | ||
| 76 | luaS_resize(L, G(L)->strt.size*2); /* too crowded */ | ||
| 88 | return ts; | 77 | return ts; |
| 89 | } | 78 | } |
| 90 | 79 | ||
| 91 | 80 | ||
| 92 | TString *luaS_newudata (lua_State *L, size_t s, void *udata) { | 81 | Udata *luaS_newudata (lua_State *L, size_t s) { |
| 93 | TString *ts = (TString *)luaM_malloc(L, sizeudata(s)); | 82 | Udata *u = (Udata *)luaM_malloc(L, sizeudata(s)); |
| 94 | ts->marked = 0; | 83 | u->marked = 0; |
| 95 | ts->nexthash = NULL; | 84 | u->len = s; |
| 96 | ts->len = s; | 85 | u->tag = 0; |
| 97 | ts->u.d.tag = 0; | 86 | u->value = ((union L_UUdata *)(u) + 1); |
| 98 | ts->u.d.value = (s > 0) ? getstr(ts) : udata; | 87 | /* chain it on udata list */ |
| 99 | /* insert it on table */ | 88 | u->next = G(L)->rootudata; |
| 100 | newentry(L, &G(L)->udt, ts, lmod(IntPoint(ts->u.d.value), G(L)->udt.size)); | 89 | G(L)->rootudata = u; |
| 101 | return ts; | 90 | return u; |
| 102 | } | ||
| 103 | |||
| 104 | |||
| 105 | int luaS_createudata (lua_State *L, void *udata, TObject *o) { | ||
| 106 | int h1 = lmod(IntPoint(udata), G(L)->udt.size); | ||
| 107 | TString *ts; | ||
| 108 | for (ts = G(L)->udt.hash[h1]; ts; ts = ts->nexthash) { | ||
| 109 | if (udata == ts->u.d.value) { | ||
| 110 | setuvalue(o, ts); | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | /* not found */ | ||
| 115 | setuvalue(o, luaS_newudata(L, 0, udata)); | ||
| 116 | return 1; | ||
| 117 | } | 91 | } |
| 118 | 92 | ||
