* ikarus.hash-tables is ok now.
This commit is contained in:
parent
0c31cbc8df
commit
b425bc58cb
BIN
src/ikarus.boot
BIN
src/ikarus.boot
Binary file not shown.
|
@ -1,15 +1,25 @@
|
|||
|
||||
(library (ikarus hash-tables)
|
||||
(export)
|
||||
(import (scheme))
|
||||
(export hash-table? make-hash-table get-hash-table put-hash-table!)
|
||||
(import
|
||||
(only (scheme) $set-car! $set-cdr! $car $cdr $fxlogxor $fxsra
|
||||
$fxsll $fxlognot $fx+ $fx- $fx= $fx> $fxadd1
|
||||
$vector-length $vector-ref $vector-set!
|
||||
$make-tcbucket $set-tcbucket-val!
|
||||
$tcbucket-next $tcbucket-key $set-tcbucket-next!
|
||||
$tcbucket-val $set-tcbucket-tconc! $fxlogand)
|
||||
(except (ikarus) hash-table? make-hash-table get-hash-table
|
||||
put-hash-table!))
|
||||
|
||||
(let ([hash-rtd (make-record-type '"hash-table" '(hash-vec count tc))])
|
||||
;;; accessors
|
||||
(define get-vec (record-field-accessor hash-rtd 0))
|
||||
(define set-vec! (record-field-mutator hash-rtd 0))
|
||||
(define get-count (record-field-accessor hash-rtd 1))
|
||||
(define set-count! (record-field-mutator hash-rtd 1))
|
||||
(define get-tc (record-field-accessor hash-rtd 2))
|
||||
(define-record hasht (vec count tc))
|
||||
|
||||
;(let ([hash-rtd (make-record-type '"hash-table" '(hash-vec count tc))])
|
||||
; ;;; accessors
|
||||
; (define get-vec (record-field-accessor hash-rtd 0))
|
||||
; (define set-vec! (record-field-mutator hash-rtd 0))
|
||||
; (define get-count (record-field-accessor hash-rtd 1))
|
||||
; (define set-count! (record-field-mutator hash-rtd 1))
|
||||
; (define get-tc (record-field-accessor hash-rtd 2))
|
||||
;;; implementation
|
||||
|
||||
;;; directly from Dybvig's paper
|
||||
|
@ -85,7 +95,7 @@
|
|||
|
||||
(define re-add!
|
||||
(lambda (h b)
|
||||
(let ([vec (get-vec h)]
|
||||
(let ([vec (hasht-vec h)]
|
||||
[next ($tcbucket-next b)])
|
||||
;;; first remove it from its old place
|
||||
(let ([idx
|
||||
|
@ -99,7 +109,7 @@
|
|||
[else
|
||||
(replace! fst b next)])))
|
||||
;;; reset the tcbucket-tconc FIRST
|
||||
($set-tcbucket-tconc! b (get-tc h))
|
||||
($set-tcbucket-tconc! b (hasht-tc h))
|
||||
;;; then add it to the new place
|
||||
(let ([k ($tcbucket-key b)])
|
||||
(let ([ih (inthash (pointer-value k))])
|
||||
|
@ -134,12 +144,12 @@
|
|||
(define get-hash
|
||||
(lambda (h x v)
|
||||
(let ([pv (pointer-value x)]
|
||||
[vec (get-vec h)])
|
||||
[vec (hasht-vec h)])
|
||||
(let ([ih (inthash pv)])
|
||||
(let ([idx ($fxlogand ih ($fx- ($vector-length vec) 1))])
|
||||
(let ([b ($vector-ref vec idx)])
|
||||
(cond
|
||||
[(or (direct-lookup x b) (rehash-lookup h (get-tc h) x))
|
||||
[(or (direct-lookup x b) (rehash-lookup h (hasht-tc h) x))
|
||||
=>
|
||||
(lambda (b)
|
||||
($tcbucket-val b))]
|
||||
|
@ -149,19 +159,19 @@
|
|||
(define put-hash!
|
||||
(lambda (h x v)
|
||||
(let ([pv (pointer-value x)]
|
||||
[vec (get-vec h)])
|
||||
[vec (hasht-vec h)])
|
||||
(let ([ih (inthash pv)])
|
||||
(let ([idx ($fxlogand ih ($fx- ($vector-length vec) 1))])
|
||||
(let ([b ($vector-ref vec idx)])
|
||||
(cond
|
||||
[(or (direct-lookup x b) (rehash-lookup h (get-tc h) x))
|
||||
[(or (direct-lookup x b) (rehash-lookup h (hasht-tc h) x))
|
||||
=>
|
||||
(lambda (b)
|
||||
($set-tcbucket-val! b v)
|
||||
(void))]
|
||||
[else
|
||||
(let ([bucket
|
||||
($make-tcbucket (get-tc h) x v ($vector-ref vec idx))])
|
||||
($make-tcbucket (hasht-tc h) x v ($vector-ref vec idx))])
|
||||
(if ($fx= (pointer-value x) pv)
|
||||
($vector-set! vec idx bucket)
|
||||
(let* ([ih (inthash (pointer-value x))]
|
||||
|
@ -169,8 +179,8 @@
|
|||
($fxlogand ih ($fx- ($vector-length vec) 1))])
|
||||
($set-tcbucket-next! bucket ($vector-ref vec idx))
|
||||
($vector-set! vec idx bucket))))
|
||||
(let ([ct (get-count h)])
|
||||
(set-count! h ($fxadd1 ct))
|
||||
(let ([ct (hasht-count h)])
|
||||
(set-hasht-count! h ($fxadd1 ct))
|
||||
(when ($fx> ct ($vector-length vec))
|
||||
(enlarge-table h)))])))))))
|
||||
|
||||
|
@ -196,12 +206,12 @@
|
|||
|
||||
(define enlarge-table
|
||||
(lambda (h)
|
||||
(let* ([vec1 (get-vec h)]
|
||||
(let* ([vec1 (hasht-vec h)]
|
||||
[n1 ($vector-length vec1)]
|
||||
[n2 ($fxsll n1 1)]
|
||||
[vec2 (make-base-vec n2)])
|
||||
(move-all vec1 0 n1 vec2 ($fx- n2 1))
|
||||
(set-vec! h vec2))))
|
||||
(set-hasht-vec! h vec2))))
|
||||
|
||||
|
||||
|
||||
|
@ -218,22 +228,23 @@
|
|||
(init-vec (make-vector n) 0 n)))
|
||||
|
||||
;;; public interface
|
||||
(primitive-set! 'hash-table? (record-predicate hash-rtd))
|
||||
(primitive-set! 'make-hash-table
|
||||
(let ([make (record-constructor hash-rtd)])
|
||||
(lambda ()
|
||||
(let ([x (cons #f #f)])
|
||||
(let ([tc (cons x x)])
|
||||
(make (make-base-vec 32) 0 tc))))))
|
||||
(primitive-set! 'get-hash-table
|
||||
(define (hash-table? x) (hasht? x))
|
||||
|
||||
(define (make-hash-table)
|
||||
(let ([x (cons #f #f)])
|
||||
(let ([tc (cons x x)])
|
||||
(make-hasht (make-base-vec 32) 0 tc))))
|
||||
|
||||
(define get-hash-table
|
||||
(lambda (h x v)
|
||||
(if (hash-table? h)
|
||||
(if (hasht? h)
|
||||
(get-hash h x v)
|
||||
(error 'get-hash-table "~s is not a hash table" h))))
|
||||
(primitive-set! 'put-hash-table!
|
||||
|
||||
(define put-hash-table!
|
||||
(lambda (h x v)
|
||||
(if (hash-table? h)
|
||||
(if (hasht? h)
|
||||
(put-hash! h x v)
|
||||
(error 'put-hash-table! "~s is not a hash table" h)))))
|
||||
(error 'put-hash-table! "~s is not a hash table" h))))
|
||||
|
||||
)
|
|
@ -50,7 +50,8 @@
|
|||
"ikarus.io.output-files.ss"
|
||||
"ikarus.io.output-strings.ss"
|
||||
|
||||
"libhash.ss"
|
||||
"ikarus.hash-tables.ss"
|
||||
|
||||
"libwriter.ss"
|
||||
"libtokenizer.ss"
|
||||
"libassembler.ss"
|
||||
|
|
Loading…
Reference in New Issue