fork download
  1. #lang racket
  2.  
  3. (require (only-in srfi/41 stream-drop-while stream-from))
  4.  
  5. ;; 素数列
  6. (define primes
  7. (stream-cons
  8. 2
  9. (stream-filter prime? (stream-from 3))))
  10.  
  11. (define (prime? n)
  12. (let loop ((ps primes))
  13. (let ((x (stream-first ps)))
  14. (or (> (expt (stream-first ps) 2) n)
  15. (and ((compose1 not zero?) (remainder n x))
  16. (loop (stream-rest ps)))))))
  17.  
  18. ;; メルセンヌ素数(の一部)のテーブル(12個のみ)
  19. (define *mersenne-primes*
  20. (vector 3 7 31 127 8191 131071 524287 2147483647 2305843009213693951
  21. 618970019642690137449562111 162259276829213363391578010288127
  22. 170141183460469231731687303715884105727))
  23.  
  24. ;; キーと値のペアを形作る構造体
  25. (struct entry (key value) #:transparent)
  26.  
  27. ;;; ハッシュテーブル生成関数
  28. (define make-ht
  29. (case-lambda
  30. ((n)
  31. (let ((bucket (make-vector n '())))
  32. ;;; 多項式ローリングハッシュ関数
  33. (define hashval
  34. (case-lambda
  35. ((s ht p)
  36. (let ((s (map char->integer (string->list s))))
  37. (modulo
  38. (apply +
  39. (map (lambda (i s)
  40. (* (expt p i) s))
  41. (range (length s))
  42. s))
  43. (vector-length ht))))
  44. ((s ht)
  45. (hashval s ht (vector-ref *mersenne-primes* 2)))
  46. ((s)
  47. (hashval s bucket))))
  48. ;;; ハッシュテーブル操作関数
  49. ;; 検索
  50. (define (lookup key)
  51. (let ((lst (vector-ref bucket (hashval key))))
  52. (and ((compose1 not null?) lst)
  53. (entry-value
  54. (car
  55. (member key lst
  56. (lambda (x y)
  57. (string=? x (entry-key y)))))))))
  58. ;; 削除
  59. (define (delete key)
  60. (let ((hv (hashval key)))
  61. (vector-set! bucket hv
  62. (remove key
  63. (vector-ref bucket hv)
  64. (lambda (x y)
  65. (string=? x (entry-key y)))))))
  66. ;; 挿入
  67. (define insert
  68. (case-lambda
  69. ((vec key val flag)
  70. (let ((hv (hashval key vec)))
  71. (when flag
  72. (delete key))
  73. (vector-set! vec hv
  74. (cons (entry key val) (vector-ref vec hv)))))
  75. ((vec key val)
  76. (insert vec key val #f))
  77. ((key val)
  78. (when (check-size?)
  79. (rehash))
  80. (insert bucket key val #t))))
  81. ;; キーのリストを返す
  82. (define (getkeys)
  83. (get-entries entry-key))
  84. ;; 値のリストを返す
  85. (define (getvalues)
  86. (get-entries entry-value))
  87. ;;; ユーティリティ
  88. ;; エントリを返す
  89. (define get-entries
  90. (case-lambda
  91. ((proc)
  92. (map proc (get-entries)))
  93. (()
  94. (flatten (vector->list bucket)))))
  95. ;; ハッシュテーブルを占めるデータの割合を計算する
  96. (define check-size?
  97. (case-lambda
  98. ((threshold)
  99. (> (/ (length (get-entries)) (vector-length bucket)) threshold))
  100. (()
  101. (check-size? 0.8))))
  102. ;; リハッシュ
  103. (define (rehash)
  104. (let* ((n (vector-length bucket))
  105. (v (make-vector
  106. (stream-first
  107. (stream-drop-while
  108. (lambda (x)
  109. (< x (* 2 n))) primes)) '())))
  110. (for-each (lambda (key val)
  111. (insert v key val)) (getkeys) (getvalues))
  112. (set! bucket v)))
  113. ;; デバッグ用
  114. (define (print)
  115. (display bucket)
  116. (newline))
  117. ;; *ディスパッチ関数*
  118. ;; ここでオブジェクト外に「公開する」メソッドと「隠蔽する」メソッド
  119. ;; に分かれる(登録すると「公開」される)
  120. ;; 通常のOOPで言う"public""private"だ。
  121. (define (dispatch message)
  122. (case message
  123. ((delete) delete)
  124. ((getkeys) getkeys)
  125. ((getvalues) getvalues)
  126. ((insert) insert)
  127. ((lookup) lookup)
  128. ;; デバッグ用
  129. ;; ((check-size?) check-size?)
  130. ;; ((get-entries) get-entries)
  131. ;; ((print) print)
  132. ;; ((rehash) rehash)
  133. (else (error "Unknown request --MAKE-HT" message))))
  134. dispatch
  135. ))
  136. (() (make-ht (stream-ref primes 25)))))
  137.  
  138. ;; メッセージ送信
  139. ; 「オブジェクト指向の理論的モデル」で書くと
  140. ; ((object message) arg0 arg1 ...)
  141. ; と面倒臭い形式で関数記述を行わないとならない。
  142. ; それを避け、「objectにmessageをsendする」と言う
  143. ; 明解な「形式」に語順を変える。
  144. (define (send object message . args)
  145. (apply (object message) args))
  146.  
  147. ; 以下の関数は send を利用して object の外部で「フツーの関数」として
  148. ; 定義されている。
  149. ;; 削除関数
  150. (define (delete object key)
  151. (send object 'delete key))
  152.  
  153. ;; キーのリストを得る
  154. (define (getkeys object)
  155. (send object 'getkeys))
  156.  
  157. ;; 値のリストを得る
  158. (define (getvalues object)
  159. (send object 'getvalues))
  160.  
  161. ;; 挿入関数
  162. (define (insert object key val)
  163. (send object 'insert key val))
  164.  
  165. ;; 検索関数
  166. (define (lookup object key)
  167. (send object 'lookup key))
Success #stdin #stdout 0.7s 116104KB
stdin
Standard input is empty
stdout
Standard output is empty