useCell: (s) -> if s >= @alphabet.length+2 @base[-@check[s]] = @base[s] @check[-@base[s]] = @check[s]
allocate: (chars) -> test = (b) => for c in chars returnfalseif @check[b+c] > 0or @base[b+c] > 0 true
loop b = -@check[0] while b != 0 if b+@alphabet.length < @n and test b return b b = -@check[b] nn = Math.ceil @n*1.3 base2 = Array(nn) check2 = Array(nn) for i in [0...@n] base2[i] = @base[i] check2[i] = @check[i] @base = base2 @check = check2 for i in [nn-1..@n] by-1 @freeCell i @n = nn
relocate: (s, b) -> for c in @chars s @useCell b+c @check[b+c] = s @base[b+c] = @base[@base[s]+c] for cc in @chars(@base[s]+c) @check[@base[@base[s]+c]+cc] = b+c @freeCell @base[s]+c @base[s] = b
ord: (ch) -> @mapping[ch.charCodeAt(0)]
insertBranch: (s, c) -> if @base[s] > 0 if @check[@base[s]+c] == s return if @check[@base[s]+c] > 0 @relocate s, @allocate([c].concat @chars s) else t = @allocate [c] # @base may vary @base[s] = t @useCell @base[s]+c @check[@base[s]+c] = s
insert: (str) -> s = 1 for _, i in str o = @ord str[i] @insertBranch s, o s = @base[s]+o @insertBranch s, 0
retrieve: (str) -> s = 1 for c in str ss = @base[s]+@ord(c) returnfalseif @check[ss] != s s = ss true