Fix 'hashtable new'

db4
Slava Pestov 2008-07-13 23:26:20 -05:00
parent 817035099c
commit d34d3a6f31
3 changed files with 28 additions and 19 deletions

View File

@ -93,11 +93,6 @@ HELP: hash-deleted+
{ $description "Called to increment the deleted entry counter when an entry is removed with " { $link delete-at } }
{ $side-effects "hash" } ;
HELP: (set-hash)
{ $values { "value" "a value" } { "key" "a key to add" } { "hash" hashtable } { "new?" "a boolean" } }
{ $description "Stores the key/value pair into the hashtable. This word does not grow the hashtable if it exceeds capacity, therefore a hang can result. User code should use " { $link set-at } " instead, which grows the hashtable if necessary." }
{ $side-effects "hash" } ;
HELP: grow-hash
{ $values { "hash" hashtable } }
{ $description "Enlarges the capacity of a hashtable. User code does not need to call this word directly." }

View File

@ -164,3 +164,16 @@ H{ } "x" set
[ { "one" "two" 3 } ] [
{ 1 2 3 } H{ { 1 "one" } { 2 "two" } } substitute
] unit-test
! We want this to work
[ ] [ hashtable new "h" set ] unit-test
[ 0 ] [ "h" get assoc-size ] unit-test
[ f f ] [ "goo" "h" get at* ] unit-test
[ ] [ 1 2 "h" get set-at ] unit-test
[ 1 ] [ "h" get assoc-size ] unit-test
[ 1 ] [ 2 "h" get at ] unit-test

View File

@ -20,15 +20,18 @@ TUPLE: hashtable
: probe ( array i -- array i )
2 fixnum+fast over wrap ; inline
: (key@) ( key keys i -- array n ? )
: no-key ( key array -- array n ? ) nip f f ; inline
: (key@) ( key array i -- array n ? )
3dup swap array-nth
dup ((empty)) eq?
[ 3drop nip f f ] [
[ 3drop no-key ] [
= [ rot drop t ] [ probe (key@) ] if
] if ; inline
: key@ ( key hash -- array n ? )
array>> 2dup hash@ (key@) ; inline
array>> dup array-capacity 0 eq?
[ no-key ] [ 2dup hash@ (key@) ] if ; inline
: <hash-array> ( n -- array )
1+ next-power-of-2 4 * ((empty)) <array> ; inline
@ -63,25 +66,20 @@ TUPLE: hashtable
: hash-deleted+ ( hash -- )
[ 1+ ] change-deleted drop ; inline
: (set-hash) ( value key hash -- new? )
2dup new-key@
[ rot hash-count+ set-nth-pair t ]
[ rot drop set-nth-pair f ] if ; inline
: (rehash) ( hash alist -- )
swap [ swapd (set-hash) drop ] curry assoc-each ;
swap [ swapd set-at ] curry assoc-each ; inline
: hash-large? ( hash -- ? )
[ count>> 3 fixnum*fast ]
[ array>> array-capacity ] bi > ;
[ count>> 3 fixnum*fast 1 fixnum+fast ]
[ array>> array-capacity ] bi fixnum> ; inline
: hash-stale? ( hash -- ? )
[ deleted>> 10 fixnum*fast ] [ count>> ] bi fixnum> ;
[ deleted>> 10 fixnum*fast ] [ count>> ] bi fixnum> ; inline
: grow-hash ( hash -- )
[ dup >alist swap assoc-size 1+ ] keep
[ reset-hash ] keep
swap (rehash) ;
swap (rehash) ; inline
: ?grow-hash ( hash -- )
dup hash-large? [
@ -122,7 +120,10 @@ M: hashtable assoc-size ( hash -- n )
r> (rehash) ;
M: hashtable set-at ( value key hash -- )
dup >r (set-hash) [ r> ?grow-hash ] [ r> drop ] if ;
dup ?grow-hash
2dup new-key@
[ rot hash-count+ set-nth-pair ]
[ rot drop set-nth-pair ] if ;
: associate ( value key -- hash )
2 <hashtable> [ set-at ] keep ;