Repository navigation
Expand file tree
/
Copy pathlstringc.go
More file actions
144 lines (134 loc) · 3.78 KB
/
Copy pathlstringc.go
File metadata and controls
144 lines (134 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package main
import (
"math"
"unsafe"
"github.com/golang/glog"
)
const MEMERRMSG = "not enough memory"
const LUAI_HASHLIMIT = 5
func luaS_hash(str []byte, l size_t, seed uint) uint {
var h uint = seed ^ uint(l)
var step size_t = l>>LUAI_HASHLIMIT + 1
for ; l >= step; l -= step {
h ^= ((h << 5) + (h >> 2) + uint(str[l-1]))
}
return h
}
/*
** resizes the string table
*/
func luaS_resize(L *lua_State, newsize int) {
var tb *stringtable = &L.l_G.strt
if newsize > tb.size {
//luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
var tmp = &TString{}
luaM_reallocvector(L, &tb.hash, uint(tb.size), uint(newsize), &tmp)
}
for i := 0; i < tb.size; i++ { /* rehash */
var p *TString = tb.hash[i]
tb.hash[i] = nil
for p != nil { /* for each node in the list */
var hnext *TString = p.u.hnext /* save next */
var h uint = uint(lmod(p.hash, newsize)) /* new position */
p.u.hnext = tb.hash[h] /* chain it */
tb.hash[h] = p
p = hnext
}
}
if newsize < tb.size {
assert(tb.hash[newsize] == nil && tb.hash[tb.size-1] == nil)
//luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
var tmp = &TString{}
luaM_reallocvector(L, &tb.hash, uint(tb.size), uint(newsize), &tmp)
}
tb.size = newsize
}
func luaS_init(L *lua_State) {
var g *global_State = L.l_G
luaS_resize(L, MINSTRTABSIZE) /* initial size of string table */
/* pre-create memory-error message */
g.memerrmsg = luaS_newliteral(L, MEMERRMSG)
luaC_fix(L, obj2gco(g.memerrmsg)) /* it should never be collected */
for i := 0; i < STRCACHE_N; i++ { /* fill cache with valid strings */
for j := 0; j < STRCACHE_M; j++ {
g.strcache[i][j] = g.memerrmsg
}
}
}
func createstrobj(L *lua_State, l size_t, tag int, h uint) *TString {
var ts *TString
var o GCObject
//var totalsize size_t = sizelstring(l) /* total size of TString object */
o = luaC_newobj(L, tag /*, totalsize*/)
ts = gco2ts(o)
ts.hash = h
ts.extra = 0
//getstr(ts)[l] = '\0'; /* ending 0 */
return ts
}
func luaS_createlngstrobj(L *lua_State, l size_t) *TString {
var ts = createstrobj(L, l, LUA_TLNGSTR, L.l_G.seed)
ts.u.lnglen = l
return ts
}
/*
** checks whether short string exists and reuses it or creates a new one
*/
func internshrstr(L *lua_State, str []byte, l size_t) *TString {
var ts *TString
var g *global_State = L.l_G
var h uint = luaS_hash(str, l, g.seed)
var list **TString = &g.strt.hash[lmod(h, g.strt.size)]
glog.Info(string(str), " ", l, lmod(h, g.strt.size))
assert(str != nil)
for ts = *list; ts != nil; ts = ts.u.hnext {
if l == size_t(ts.shrlen) && string(str) == getstr(ts) {
/* 找到! */
if isdead(g, ts) {
changewhite(ts)
}
return ts
}
}
if g.strt.nuse >= g.strt.size && g.strt.size <= math.MaxInt32/2 {
luaS_resize(L, g.strt.size*2)
list = &g.strt.hash[lmod(h, g.strt.size)] /* recompute with new size */
}
ts = createstrobj(L, l, LUA_TSHRSTR, h)
ts.data = string(str[:l])
ts.shrlen = byte(l)
ts.u.hnext = *list
*list = ts
g.strt.nuse++
return ts
}
func luaS_newlstr(L *lua_State, str []byte, l size_t) *TString {
if l <= LUAI_MAXSHORTLEN {
return internshrstr(L, str[:l], l)
} else {
var ts *TString
if l >= MAX_SIZE-size_t(unsafe.Sizeof(*ts)) { //sizeof(TString)
luaM_toobig(L)
}
ts = luaS_createlngstrobj(L, l)
ts.data = string(str[:l])
return ts
}
}
func luaS_new(L *lua_State, str string) *TString {
var i uint = point2uint(str) % STRCACHE_N /* hash */
var j int
var p *([2]*TString) = &L.l_G.strcache[i]
for j = 0; j < STRCACHE_M; j++ {
if str == getstr(p[j]) { /* hit? */
return p[j] /* that is it */
}
}
/* normal route */
for j = STRCACHE_M - 1; j > 0; j-- {
p[j] = p[j-1] /* move out last element */
}
/* new element is first in the list */
p[0] = luaS_newlstr(L, []byte(str), size_t(len(str)))
return p[0]
}