image-table.scm 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. ; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
  2. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  3. ; A hash table for writing images. Objects to be written out are saved in
  4. ; the table.
  5. ; This needs to be here because the Pre-Scheme compiler does not currently
  6. ; support polymorphic data types (so the table cannot be polymorphic, so
  7. ; we need to have this before we can define tables).
  8. (define-record-type image-location :image-location
  9. (really-make-image-location new-descriptor next)
  10. (new-descriptor integer image-location-new-descriptor set-image-location-new-descriptor!)
  11. (next integer image-location-next set-image-location-next!))
  12. (define (make-image-location new-descriptor)
  13. (really-make-image-location new-descriptor 0))
  14. ;----------------------------------------------------------------
  15. (define-record-type table :table
  16. (really-make-table keys values count size)
  17. (keys (^ integer) table-keys set-table-keys!)
  18. (values (^ image-location) table-values set-table-values!)
  19. (count integer table-count set-table-count!)
  20. (size integer table-size set-table-size!))
  21. (define initial-table-size (shift-left 1 12))
  22. ; MAKE-VECTOR uses the initial value only to determine the type of the vector.
  23. ; It doesn't do the fill (which is really dumb).
  24. (define (make-table)
  25. (let ((keys (make-vector (+ initial-table-size 1) 0)))
  26. (vector+length-fill! keys (+ initial-table-size 1) 0)
  27. (really-make-table keys
  28. (make-vector initial-table-size (null-pointer))
  29. 0
  30. initial-table-size)))
  31. (define (deallocate-table table)
  32. (let ((keys (table-keys table))
  33. (values (table-values table)))
  34. (do ((i 0 (+ i 1)))
  35. ((= i (table-size table)))
  36. (if (not (= (vector-ref keys i) 0))
  37. (deallocate (vector-ref values i))))
  38. (deallocate keys)
  39. (deallocate values)
  40. (deallocate table)))
  41. ; The if we run out of memory we mark the table as unusable. The image-writing
  42. ; code does the same.
  43. (define (table-okay? table)
  44. (< 0 (table-size table)))
  45. (define (break-table! table)
  46. (set-table-size! table 0))
  47. ; Assumes SIZE is a power of two.
  48. ; I have no idea how effective this hash function is.
  49. (define (hash key size)
  50. (bitwise-and (bitwise-xor key
  51. (bitwise-xor (shift-left key 1)
  52. (arithmetic-shift-right key 10)))
  53. (- size 1)))
  54. ; Double the size of the table.
  55. (define (table-grow table)
  56. (let ((new-size (* (table-size table) 2))
  57. (old-size (table-size table))
  58. (old-keys (table-keys table))
  59. (old-values (table-values table)))
  60. (let ((new-keys (make-vector (+ new-size 1) 0))
  61. (new-values (make-vector new-size (null-pointer))))
  62. (cond ((or (null-pointer? new-keys)
  63. (null-pointer? new-values))
  64. (if (not (null-pointer? new-keys))
  65. (deallocate new-keys))
  66. (if (not (null-pointer? new-values))
  67. (deallocate new-values))
  68. (break-table! table))
  69. (else
  70. (set-table-keys! table new-keys)
  71. (set-table-values! table new-values)
  72. (set-table-size! table new-size)
  73. (set-table-count! table 0)
  74. (vector+length-fill! new-keys ; MAKE-VECTOR doesn't fill
  75. (+ new-size 1)
  76. 0)
  77. (do ((i 0 (+ i 1)))
  78. ((= i old-size))
  79. (let ((key (vector-ref old-keys i)))
  80. (if (not (= key 0))
  81. (table-insert! new-size
  82. new-keys
  83. new-values
  84. key
  85. (vector-ref old-values i)))))
  86. (deallocate old-keys)
  87. (deallocate old-values))))))
  88. (define (table-insert! size keys values key value)
  89. (let loop ((i (hash key size)))
  90. (cond ((not (= (vector-ref keys i) 0))
  91. (loop (+ i 1)))
  92. ((= i size)
  93. (loop 0))
  94. (else
  95. (vector-set! keys i key)
  96. (vector-set! values i value)))))
  97. (define (table-find table key found not-found)
  98. (let ((start (hash key (table-size table)))
  99. (keys (table-keys table)))
  100. (let loop ((i start))
  101. (let ((next (vector-ref keys i)))
  102. (cond ((= key next)
  103. (found i))
  104. ((not (= next 0))
  105. (loop (+ i 1)))
  106. ((= i (table-size table))
  107. (loop 0))
  108. (else
  109. (not-found i)))))))
  110. (define (table-set! table key value)
  111. (if (table-okay? table)
  112. (table-find table
  113. key
  114. (lambda (i)
  115. ; A. this should not happen
  116. ; B. if it were to, who would delete the old value?
  117. (vector-set! (table-values table) i value))
  118. (lambda (i)
  119. (vector-set! (table-keys table) i key)
  120. (vector-set! (table-values table) i value)
  121. (set-table-count! table (+ (table-count table) 1))
  122. (if (= (table-count table)
  123. (quotient (table-size table) 3))
  124. (table-grow table))
  125. (unspecific)))
  126. (unspecific)))
  127. (define (table-ref table key)
  128. (if (table-okay? table)
  129. (table-find table
  130. key
  131. (lambda (i)
  132. (vector-ref (table-values table) i))
  133. (lambda (i)
  134. (null-pointer)))
  135. (null-pointer)))