tstrset.nim 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. discard """
  2. matrix: "--mm:refc; --mm:orc"
  3. """
  4. # test a simple yet highly efficient set of strings
  5. type
  6. TRadixNodeKind = enum rnLinear, rnFull, rnLeaf
  7. PRadixNode = ref TRadixNode
  8. TRadixNode {.inheritable.} = object
  9. kind: TRadixNodeKind
  10. TRadixNodeLinear = object of TRadixNode
  11. len: uint8
  12. keys: array[0..31, char]
  13. vals: array[0..31, PRadixNode]
  14. TRadixNodeFull = object of TRadixNode
  15. b: array[char, PRadixNode]
  16. TRadixNodeLeaf = object of TRadixNode
  17. s: string
  18. PRadixNodeLinear = ref TRadixNodeLinear
  19. PRadixNodeFull = ref TRadixNodeFull
  20. PRadixNodeLeaf = ref TRadixNodeLeaf
  21. proc search(r: PRadixNode, s: string): PRadixNode =
  22. result = default(PRadixNode)
  23. var r = r
  24. var i = 0
  25. while r != nil:
  26. case r.kind
  27. of rnLinear:
  28. var x = PRadixNodeLinear(r)
  29. for j in 0..int(x.len)-1:
  30. if x.keys[j] == s[i]:
  31. if s[i] == '\0': return r
  32. r = x.vals[j]
  33. inc(i)
  34. break
  35. break # character not found
  36. of rnFull:
  37. var x = PRadixNodeFull(r)
  38. var y = x.b[s[i]]
  39. if s[i] == '\0':
  40. return if y != nil: r else: nil
  41. r = y
  42. inc(i)
  43. of rnLeaf:
  44. var x = PRadixNodeLeaf(r)
  45. var j = 0
  46. while true:
  47. if x.s[j] != s[i]: return nil
  48. if s[i] == '\0': return r
  49. inc(j)
  50. inc(i)
  51. proc contains*(r: PRadixNode, s: string): bool =
  52. return search(r, s) != nil
  53. proc testOrIncl*(r: var PRadixNode, s: string): bool =
  54. result = false
  55. proc incl*(r: var PRadixNode, s: string) = discard testOrIncl(r, s)
  56. proc excl*(r: var PRadixNode, s: string) =
  57. var x = search(r, s)
  58. if x == nil: return
  59. case x.kind
  60. of rnLeaf: PRadixNodeLeaf(x).s = ""
  61. of rnFull: PRadixNodeFull(x).b['\0'] = nil
  62. of rnLinear:
  63. var x = PRadixNodeLinear(x)
  64. for i in 0..int(x.len)-1:
  65. if x.keys[i] == '\0':
  66. swap(x.keys[i], x.keys[int(x.len)-1])
  67. dec(x.len)
  68. break
  69. var
  70. root: PRadixNode