cedar.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. package cedar
  2. const (
  3. // ValueLimit limit value
  4. ValueLimit = int(^uint(0) >> 1)
  5. )
  6. type node struct {
  7. Value int
  8. Check int
  9. }
  10. func (n *node) base() int {
  11. return -(n.Value + 1)
  12. }
  13. type ninfo struct {
  14. Sibling, Child byte
  15. }
  16. type block struct {
  17. Prev, Next, Num, Reject, Trial, Ehead int
  18. }
  19. func (b *block) init() {
  20. b.Num = 256
  21. b.Reject = 257
  22. }
  23. // Cedar cedar struct
  24. type Cedar struct {
  25. *cedar
  26. }
  27. type cedar struct {
  28. Array []node
  29. Ninfos []ninfo
  30. Blocks []block
  31. Reject [257]int
  32. BheadF int
  33. BheadC int
  34. BheadO int
  35. Capacity int
  36. Size int
  37. Ordered bool
  38. MaxTrial int
  39. }
  40. // New new cedar
  41. func New() *Cedar {
  42. da := cedar{
  43. Array: make([]node, 256),
  44. Ninfos: make([]ninfo, 256),
  45. Blocks: make([]block, 1),
  46. Capacity: 256,
  47. Size: 256,
  48. Ordered: true,
  49. MaxTrial: 1,
  50. }
  51. da.Array[0] = node{-2, 0}
  52. for i := 1; i < 256; i++ {
  53. da.Array[i] = node{-(i - 1), -(i + 1)}
  54. }
  55. da.Array[1].Value = -255
  56. da.Array[255].Check = -1
  57. da.Blocks[0].Ehead = 1
  58. da.Blocks[0].init()
  59. for i := 0; i <= 256; i++ {
  60. da.Reject[i] = i + 1
  61. }
  62. return &Cedar{&da}
  63. }
  64. // Get value by key, insert the key if not exist
  65. func (da *cedar) get(key []byte, from, pos int) *int {
  66. for ; pos < len(key); pos++ {
  67. if value := da.Array[from].Value; value >= 0 && value != ValueLimit {
  68. to := da.follow(from, 0)
  69. da.Array[to].Value = value
  70. }
  71. from = da.follow(from, key[pos])
  72. }
  73. to := from
  74. if da.Array[from].Value < 0 {
  75. to = da.follow(from, 0)
  76. }
  77. return &da.Array[to].Value
  78. }
  79. func (da *cedar) follow(from int, label byte) int {
  80. base := da.Array[from].base()
  81. to := base ^ int(label)
  82. if base < 0 || da.Array[to].Check < 0 {
  83. hasChild := false
  84. if base >= 0 {
  85. hasChild = (da.Array[base^int(da.Ninfos[from].Child)].Check == from)
  86. }
  87. to = da.popEnode(base, label, from)
  88. da.pushSibling(from, to^int(label), label, hasChild)
  89. return to
  90. }
  91. if da.Array[to].Check != from {
  92. to = da.resolve(from, base, label)
  93. return to
  94. }
  95. if da.Array[to].Check == from {
  96. return to
  97. }
  98. panic("cedar: internal error, should not be here")
  99. // return to
  100. }
  101. func (da *cedar) popBlock(bi int, headIn *int, last bool) {
  102. if last {
  103. *headIn = 0
  104. return
  105. }
  106. b := &da.Blocks[bi]
  107. da.Blocks[b.Prev].Next = b.Next
  108. da.Blocks[b.Next].Prev = b.Prev
  109. if bi == *headIn {
  110. *headIn = b.Next
  111. }
  112. }
  113. func (da *cedar) pushBlock(bi int, headOut *int, empty bool) {
  114. b := &da.Blocks[bi]
  115. if empty {
  116. *headOut, b.Prev, b.Next = bi, bi, bi
  117. } else {
  118. tailOut := &da.Blocks[*headOut].Prev
  119. b.Prev = *tailOut
  120. b.Next = *headOut
  121. *headOut, *tailOut, da.Blocks[*tailOut].Next = bi, bi, bi
  122. }
  123. }
  124. func (da *cedar) addBlock() int {
  125. if da.Size == da.Capacity {
  126. da.Capacity *= 2
  127. oldArray := da.Array
  128. da.Array = make([]node, da.Capacity)
  129. copy(da.Array, oldArray)
  130. oldNinfo := da.Ninfos
  131. da.Ninfos = make([]ninfo, da.Capacity)
  132. copy(da.Ninfos, oldNinfo)
  133. oldBlock := da.Blocks
  134. da.Blocks = make([]block, da.Capacity>>8)
  135. copy(da.Blocks, oldBlock)
  136. }
  137. da.Blocks[da.Size>>8].init()
  138. da.Blocks[da.Size>>8].Ehead = da.Size
  139. da.Array[da.Size] = node{-(da.Size + 255), -(da.Size + 1)}
  140. for i := da.Size + 1; i < da.Size+255; i++ {
  141. da.Array[i] = node{-(i - 1), -(i + 1)}
  142. }
  143. da.Array[da.Size+255] = node{-(da.Size + 254), -da.Size}
  144. da.pushBlock(da.Size>>8, &da.BheadO, da.BheadO == 0)
  145. da.Size += 256
  146. return da.Size>>8 - 1
  147. }
  148. func (da *cedar) transferBlock(bi int, headIn, headOut *int) {
  149. da.popBlock(bi, headIn, bi == da.Blocks[bi].Next)
  150. da.pushBlock(bi, headOut, *headOut == 0 && da.Blocks[bi].Num != 0)
  151. }
  152. func (da *cedar) popEnode(base int, label byte, from int) int {
  153. e := base ^ int(label)
  154. if base < 0 {
  155. e = da.findPlace()
  156. }
  157. bi := e >> 8
  158. n := &da.Array[e]
  159. b := &da.Blocks[bi]
  160. b.Num--
  161. if b.Num == 0 {
  162. if bi != 0 {
  163. da.transferBlock(bi, &da.BheadC, &da.BheadF)
  164. }
  165. } else {
  166. da.Array[-n.Value].Check = n.Check
  167. da.Array[-n.Check].Value = n.Value
  168. if e == b.Ehead {
  169. b.Ehead = -n.Check
  170. }
  171. if bi != 0 && b.Num == 1 && b.Trial != da.MaxTrial {
  172. da.transferBlock(bi, &da.BheadO, &da.BheadC)
  173. }
  174. }
  175. n.Value = ValueLimit
  176. n.Check = from
  177. if base < 0 {
  178. da.Array[from].Value = -(e ^ int(label)) - 1
  179. }
  180. return e
  181. }
  182. func (da *cedar) pushEnode(e int) {
  183. bi := e >> 8
  184. b := &da.Blocks[bi]
  185. b.Num++
  186. if b.Num == 1 {
  187. b.Ehead = e
  188. da.Array[e] = node{-e, -e}
  189. if bi != 0 {
  190. da.transferBlock(bi, &da.BheadF, &da.BheadC)
  191. }
  192. } else {
  193. prev := b.Ehead
  194. next := -da.Array[prev].Check
  195. da.Array[e] = node{-prev, -next}
  196. da.Array[prev].Check = -e
  197. da.Array[next].Value = -e
  198. if b.Num == 2 || b.Trial == da.MaxTrial {
  199. if bi != 0 {
  200. da.transferBlock(bi, &da.BheadC, &da.BheadO)
  201. }
  202. }
  203. b.Trial = 0
  204. }
  205. if b.Reject < da.Reject[b.Num] {
  206. b.Reject = da.Reject[b.Num]
  207. }
  208. da.Ninfos[e] = ninfo{}
  209. }
  210. // hasChild: wherether the `from` node has children
  211. func (da *cedar) pushSibling(from, base int, label byte, hasChild bool) {
  212. c := &da.Ninfos[from].Child
  213. keepOrder := *c == 0
  214. if da.Ordered {
  215. keepOrder = label > *c
  216. }
  217. if hasChild && keepOrder {
  218. c = &da.Ninfos[base^int(*c)].Sibling
  219. for da.Ordered && *c != 0 && *c < label {
  220. c = &da.Ninfos[base^int(*c)].Sibling
  221. }
  222. }
  223. da.Ninfos[base^int(label)].Sibling = *c
  224. *c = label
  225. }
  226. func (da *cedar) popSibling(from, base int, label byte) {
  227. c := &da.Ninfos[from].Child
  228. for *c != label {
  229. c = &da.Ninfos[base^int(*c)].Sibling
  230. }
  231. *c = da.Ninfos[base^int(*c)].Sibling
  232. }
  233. func (da *cedar) consult(baseN, baseP int, cN, cP byte) bool {
  234. cN = da.Ninfos[baseN^int(cN)].Sibling
  235. cP = da.Ninfos[baseP^int(cP)].Sibling
  236. for cN != 0 && cP != 0 {
  237. cN = da.Ninfos[baseN^int(cN)].Sibling
  238. cP = da.Ninfos[baseP^int(cP)].Sibling
  239. }
  240. return cP != 0
  241. }
  242. func (da *cedar) setChild(base int, c byte, label byte, flag bool) []byte {
  243. child := make([]byte, 0, 257)
  244. if c == 0 {
  245. child = append(child, c)
  246. c = da.Ninfos[base^int(c)].Sibling
  247. }
  248. if da.Ordered {
  249. for c != 0 && c <= label {
  250. child = append(child, c)
  251. c = da.Ninfos[base^int(c)].Sibling
  252. }
  253. }
  254. if flag {
  255. child = append(child, label)
  256. }
  257. for c != 0 {
  258. child = append(child, c)
  259. c = da.Ninfos[base^int(c)].Sibling
  260. }
  261. return child
  262. }
  263. func (da *cedar) findPlace() int {
  264. if da.BheadC != 0 {
  265. return da.Blocks[da.BheadC].Ehead
  266. }
  267. if da.BheadO != 0 {
  268. return da.Blocks[da.BheadO].Ehead
  269. }
  270. return da.addBlock() << 8
  271. }
  272. func (da *cedar) findPlaces(child []byte) int {
  273. bi := da.BheadO
  274. if bi != 0 {
  275. e := da.listBi(bi, child)
  276. if e > 0 {
  277. return e
  278. }
  279. }
  280. return da.addBlock() << 8
  281. }
  282. func (da *cedar) listBi(bi int, child []byte) int {
  283. nc := len(child)
  284. bz := da.Blocks[da.BheadO].Prev
  285. for {
  286. b := &da.Blocks[bi]
  287. if b.Num >= nc && nc < b.Reject {
  288. e := da.listEhead(b, child)
  289. if e > 0 {
  290. return e
  291. }
  292. }
  293. b.Reject = nc
  294. if b.Reject < da.Reject[b.Num] {
  295. da.Reject[b.Num] = b.Reject
  296. }
  297. biN := b.Next
  298. b.Trial++
  299. if b.Trial == da.MaxTrial {
  300. da.transferBlock(bi, &da.BheadO, &da.BheadC)
  301. }
  302. if bi == bz {
  303. break
  304. }
  305. bi = biN
  306. }
  307. return 0
  308. }
  309. func (da *cedar) listEhead(b *block, child []byte) int {
  310. for e := b.Ehead; ; {
  311. base := e ^ int(child[0])
  312. for i := 0; da.Array[base^int(child[i])].Check < 0; i++ {
  313. if i == len(child)-1 {
  314. b.Ehead = e
  315. // if e == 0 {
  316. // }
  317. return e
  318. }
  319. }
  320. e = -da.Array[e].Check
  321. if e == b.Ehead {
  322. break
  323. }
  324. }
  325. return 0
  326. }
  327. func (da *cedar) resolve(fromN, baseN int, labelN byte) int {
  328. toPn := baseN ^ int(labelN)
  329. fromP := da.Array[toPn].Check
  330. baseP := da.Array[fromP].base()
  331. flag := da.consult(baseN, baseP, da.Ninfos[fromN].Child, da.Ninfos[fromP].Child)
  332. var children []byte
  333. if flag {
  334. children = da.setChild(baseN, da.Ninfos[fromN].Child, labelN, true)
  335. } else {
  336. children = da.setChild(baseP, da.Ninfos[fromP].Child, 255, false)
  337. }
  338. var base int
  339. if len(children) == 1 {
  340. base = da.findPlace()
  341. } else {
  342. base = da.findPlaces(children)
  343. }
  344. base ^= int(children[0])
  345. var (
  346. from int
  347. nbase int
  348. )
  349. if flag {
  350. from = fromN
  351. nbase = baseN
  352. } else {
  353. from = fromP
  354. nbase = baseP
  355. }
  356. if flag && children[0] == labelN {
  357. da.Ninfos[from].Child = labelN
  358. }
  359. da.Array[from].Value = -base - 1
  360. base, labelN, toPn = da.list(base, from, nbase, fromN, toPn,
  361. labelN, children, flag)
  362. if flag {
  363. return base ^ int(labelN)
  364. }
  365. return toPn
  366. }
  367. func (da *cedar) list(base, from, nbase, fromN, toPn int,
  368. labelN byte, children []byte, flag bool) (int, byte, int) {
  369. for i := 0; i < len(children); i++ {
  370. to := da.popEnode(base, children[i], from)
  371. newTo := nbase ^ int(children[i])
  372. if i == len(children)-1 {
  373. da.Ninfos[to].Sibling = 0
  374. } else {
  375. da.Ninfos[to].Sibling = children[i+1]
  376. }
  377. if flag && newTo == toPn { // new node has no child
  378. continue
  379. }
  380. n := &da.Array[to]
  381. ns := &da.Array[newTo]
  382. n.Value = ns.Value
  383. if n.Value < 0 && children[i] != 0 {
  384. // this node has children, fix their check
  385. c := da.Ninfos[newTo].Child
  386. da.Ninfos[to].Child = c
  387. da.Array[n.base()^int(c)].Check = to
  388. c = da.Ninfos[n.base()^int(c)].Sibling
  389. for c != 0 {
  390. da.Array[n.base()^int(c)].Check = to
  391. c = da.Ninfos[n.base()^int(c)].Sibling
  392. }
  393. }
  394. if !flag && newTo == fromN { // parent node moved
  395. fromN = to
  396. }
  397. if !flag && newTo == toPn {
  398. da.pushSibling(fromN, toPn^int(labelN), labelN, true)
  399. da.Ninfos[newTo].Child = 0
  400. ns.Value = ValueLimit
  401. ns.Check = fromN
  402. } else {
  403. da.pushEnode(newTo)
  404. }
  405. }
  406. return base, labelN, toPn
  407. }