expand-vec.scm 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. ; Copyright (c) 1993-2008 by Richard Kelsey. See file COPYING.
  2. ; Vectors of infinite length. These work as do regular vectors except that
  3. ; they have no fixed size. XVECTOR-LENGTH is one more than the highest index
  4. ; that has been passed to XVECTOR-SET!.
  5. ;
  6. ; (MAKE-XVECTOR <fill>)
  7. ; (XVECTOR-LENGTH <xvec>)
  8. ; (XVECTOR-REF <xvec> <index>)
  9. ; (XVECTOR-SET! <xvec> <index> <value>)
  10. ; (XVECTOR->VECTOR <xvec>)
  11. ; The actual record fields are:
  12. ; default - the fill value
  13. ; length - total length of internal vector(s)
  14. ; contents - either:
  15. ; a: vector of entries, or
  16. ; b: vector of vectors of entries, vector has #f's after the last needed
  17. ; sub-vector, each sub-vector has length XVEC-MAX-CONTENTS-SIZE
  18. ; max - maximum index used in a XVECTOR-SET!
  19. (define-record-type expanding-vector :expanding-vector
  20. (make-expanding-vector default length contents max)
  21. expanding-vector?
  22. (default expanding-vector-default)
  23. (length expanding-vector-length set-expanding-vector-length!)
  24. (contents expanding-vector-contents set-expanding-vector-contents!)
  25. (max expanding-vector-max set-expanding-vector-max!))
  26. (define (make-xvector default)
  27. (make-expanding-vector default 0 '#() -1))
  28. ; Maximum size of any internal vector
  29. (define xvec-max-contents-size 1024)
  30. ; XVECTOR-LENGTH returns 1 + the maximum index passed to XVECTOR-SET!
  31. (define (xvector-length xvec)
  32. (+ 1 (expanding-vector-max xvec)))
  33. ; If INDEX points outside current storage, the default is returned, otherwise
  34. ; the value is extracted from the one-or-two-level contents vector.
  35. (define (xvector-ref xvec index)
  36. (let ((length (expanding-vector-length xvec)))
  37. (cond ((>= index length)
  38. (expanding-vector-default xvec))
  39. ((<= length xvec-max-contents-size)
  40. (vector-ref (expanding-vector-contents xvec) index))
  41. (else
  42. (vector-ref (vector-ref (expanding-vector-contents xvec)
  43. (quotient index xvec-max-contents-size))
  44. (remainder index xvec-max-contents-size))))))
  45. ; Same as the above, setting instead of extracting. INDEX is checked agains
  46. ; the maximum index, and the contents may have to be expanded.
  47. (define (xvector-set! xvec index value)
  48. (let ((length (expanding-vector-length xvec)))
  49. (if (> index (expanding-vector-max xvec))
  50. (set-expanding-vector-max! xvec index))
  51. (cond ((>= index length)
  52. (expand-expanding-vector xvec)
  53. (xvector-set! xvec index value))
  54. ((<= length xvec-max-contents-size)
  55. (vector-set! (expanding-vector-contents xvec) index value))
  56. (else
  57. (vector-set! (vector-ref (expanding-vector-contents xvec)
  58. (quotient index xvec-max-contents-size))
  59. (remainder index xvec-max-contents-size)
  60. value)))))
  61. ; Copy an expanding vector into a regular vector.
  62. (define (xvector->vector xvec)
  63. (let ((new (make-vector (xvector-length xvec))))
  64. (do ((i 0 (+ i 1)))
  65. ((>= i (xvector-length xvec)))
  66. (vector-set! new i (xvector-ref xvec i)))
  67. new))
  68. ; Expand an expanding vector. A new length and contents are produced and
  69. ; put in XVEC. If LENGTH is below the maximum for a contents vector it is
  70. ; doubled in size. If the two-level structure is being used, a new sub-
  71. ; vector is added to it.
  72. (define (expand-expanding-vector xvec)
  73. (let ((length (expanding-vector-length xvec))
  74. (contents (expanding-vector-contents xvec))
  75. (default (expanding-vector-default xvec))
  76. (finish (lambda (length contents)
  77. (set-expanding-vector-length! xvec length)
  78. (set-expanding-vector-contents! xvec contents))))
  79. (if (< length xvec-max-contents-size)
  80. (let ((new (expand-vector contents default)))
  81. (finish (vector-length new) new))
  82. (let ((contents (cond ((= length xvec-max-contents-size)
  83. (let ((new (make-vector 4 #f)))
  84. (vector-set! new 0 contents)
  85. new))
  86. ((vector-ref contents
  87. (- (vector-length contents) 1))
  88. (expand-vector contents #f))
  89. (else
  90. contents))))
  91. (vector-set! contents
  92. (quotient length xvec-max-contents-size)
  93. (make-vector xvec-max-contents-size default))
  94. (finish (+ length xvec-max-contents-size) contents)))))
  95. ; Make a new vector twice the length of OLD and copy the contents of OLD into
  96. ; it. DEFAULT is used to fill in the other slots.
  97. (define (expand-vector old default)
  98. (let* ((length (vector-length old))
  99. (new (make-vector (if (= 0 length) 4 (* 2 length)) default)))
  100. (do ((i 0 (+ i 1)))
  101. ((>= i length))
  102. (vector-set! new i (vector-ref old i)))
  103. new))