Guest User

Untitled

a guest
Dec 11th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.23 KB | None | 0 0
  1.  
  2.  
  3. (define-class <pvector> ()
  4. ((size :init-keyword :size)
  5. (shift :init-keyword :shift)
  6. (root :init-keyword :root)))
  7.  
  8. (define pv:null (make <pvector> :size 0 :shift 0 :root #()))
  9.  
  10. (define (update-vector vec i val)
  11. (let ((tr (vector-copy vec)))
  12. (vector-set! tr i val)
  13. tr))
  14.  
  15. (define (expand-vector vec val)
  16. (let* ((length (vector-length vec))
  17. (tr (vector-copy vec 0 (+ 1 length) #f)))
  18. (vector-set! tr length val)
  19. tr))
  20.  
  21.  
  22. (define (pvector . args)
  23. (fold pv:cons pv:null args))
  24.  
  25.  
  26. (define (pv:assoc pvec i val)
  27. (let ((shift (slot-ref pvec 'shift)))
  28. (make <pvector>
  29. :size (slot-ref pvec 'size)
  30. :shift shift
  31. :root (pv:assoc* shift
  32. (slot-ref pvec 'root)
  33. i
  34. val))))
  35.  
  36.  
  37. (define (pv:assoc* shift vec i val)
  38. (if (zero? shift)
  39. (update-vector vec (logand i #x01f) val)
  40. (let* ((subidx (logand (ash i (- shift)) #x01f))
  41. (child (pv:assoc* (- shift 5) (vector-ref vec subidx) i val)))
  42. (update-vector vec subidx child))))
  43.  
  44.  
  45. (define (pv:nth pvec i)
  46. (let loop ((shift (slot-ref pvec 'shift))
  47. (arr (slot-ref pvec 'root)))
  48. (if (zero? shift)
  49. (vector-ref arr (logand i #x01f))
  50. (loop (- shift 5) (vector-ref arr (logand (ash i (- shift)) #x01f))))))
  51.  
  52.  
  53. (define (pv:cons obj pvec)
  54. (let* ((shift (slot-ref pvec 'shift))
  55. (size (slot-ref pvec 'size))
  56. (root (slot-ref pvec 'root))
  57. (new-root (pv:cons* shift root obj)))
  58. (if new-root
  59. (make <pvector>
  60. :size (+ size 1)
  61. :shift shift
  62. :root new-root)
  63. (make <pvector>
  64. :size (+ size 1)
  65. :shift (+ shift 5)
  66. :root (vector root (make-vector-chain (+ shift 5) obj))))))
  67.  
  68. (define (pv:cons* shift vec val)
  69. (if (zero? shift)
  70. (pv:cons-leaf vec val)
  71. (pv:cons-node shift vec val)))
  72.  
  73.  
  74. (define (node-full? vec)
  75. (= (vector-length vec) 32))
  76.  
  77. (define (pv:cons-leaf vec val)
  78. (if (node-full? vec)
  79. #f
  80. (expand-vector vec val)))
  81.  
  82. (define (pv:cons-node shift vec val)
  83. (let ((child (pv:cons* (- shift 5)
  84. (vector-ref vec (- (vector-length vec) 1))
  85. val)))
  86. (if child
  87. (update-vector vec (- (vector-length vec) 1) child)
  88. (if (node-full? vec)
  89. #f
  90. (expand-vector vec (make-vector-chain shift val))))))
  91.  
  92. (define (make-vector-chain shift val)
  93. (if (= shift 5)
  94. (vector val)
  95. (vector (make-vector-chain (- shift 5) val))))
Add Comment
Please, Sign In to add comment