tstrset.nim 1.8 KB

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