hashtables: allow re-using deleted tombstones. Fixes #381.
parent
433b8e6b6b
commit
e29c4589c4
|
@ -44,28 +44,40 @@ TUPLE: hashtable
|
||||||
: reset-hash ( n hash -- )
|
: reset-hash ( n hash -- )
|
||||||
swap <hash-array> >>array init-hash ; inline
|
swap <hash-array> >>array init-hash ; inline
|
||||||
|
|
||||||
: (new-key@) ( key array i probe# -- array i empty? )
|
|
||||||
[ 3dup swap array-nth ] dip over ((empty)) eq?
|
|
||||||
[ 3drop rot drop t ] [
|
|
||||||
[ = ] dip swap
|
|
||||||
[ drop rot drop f ]
|
|
||||||
[ probe (new-key@) ]
|
|
||||||
if
|
|
||||||
] if ; inline recursive
|
|
||||||
|
|
||||||
: new-key@ ( key hash -- array n empty? )
|
|
||||||
array>> 2dup hash@ 0 (new-key@) ; inline
|
|
||||||
|
|
||||||
: set-nth-pair ( value key seq n -- )
|
|
||||||
2 fixnum+fast [ set-slot ] 2keep
|
|
||||||
1 fixnum+fast set-slot ; inline
|
|
||||||
|
|
||||||
: hash-count+ ( hash -- )
|
: hash-count+ ( hash -- )
|
||||||
[ 1 + ] change-count drop ; inline
|
[ 1 + ] change-count drop ; inline
|
||||||
|
|
||||||
: hash-deleted+ ( hash -- )
|
: hash-deleted+ ( hash -- )
|
||||||
[ 1 + ] change-deleted drop ; inline
|
[ 1 + ] change-deleted drop ; inline
|
||||||
|
|
||||||
|
: hash-deleted- ( hash -- )
|
||||||
|
[ 1 - ] change-deleted drop ; inline
|
||||||
|
|
||||||
|
! i = first-empty-or-found
|
||||||
|
! j = first-deleted
|
||||||
|
: (new-key@) ( key array i probe# j -- array i j empty? )
|
||||||
|
[ 2dup swap array-nth ] 2dip pick tombstone?
|
||||||
|
[
|
||||||
|
rot ((empty)) eq?
|
||||||
|
[ nip [ drop ] 3dip t ]
|
||||||
|
[ pick or [ probe ] dip (new-key@) ]
|
||||||
|
if
|
||||||
|
] [
|
||||||
|
[ [ pick ] dip = ] 2dip rot
|
||||||
|
[ nip [ drop ] 3dip f ]
|
||||||
|
[ [ probe ] dip (new-key@) ]
|
||||||
|
if
|
||||||
|
] if ; inline recursive
|
||||||
|
|
||||||
|
: new-key@ ( key hash -- array n )
|
||||||
|
[ array>> 2dup hash@ 0 f (new-key@) ] keep
|
||||||
|
over [ pick [ hash-deleted- ] [ hash-count+ ] if ] [ drop ] if
|
||||||
|
[ swap or ] [ drop ] if ; inline
|
||||||
|
|
||||||
|
: set-nth-pair ( value key seq n -- )
|
||||||
|
2 fixnum+fast [ set-slot ] 2keep
|
||||||
|
1 fixnum+fast set-slot ; inline
|
||||||
|
|
||||||
: (rehash) ( hash alist -- )
|
: (rehash) ( hash alist -- )
|
||||||
swap [ swapd set-at ] curry assoc-each ; inline
|
swap [ swapd set-at ] curry assoc-each ; inline
|
||||||
|
|
||||||
|
@ -73,24 +85,13 @@ TUPLE: hashtable
|
||||||
[ count>> 3 fixnum*fast 1 fixnum+fast ]
|
[ count>> 3 fixnum*fast 1 fixnum+fast ]
|
||||||
[ array>> length>> ] bi fixnum> ; inline
|
[ array>> length>> ] bi fixnum> ; inline
|
||||||
|
|
||||||
: hash-stale? ( hash -- ? )
|
|
||||||
[ deleted>> 10 fixnum*fast ] [ count>> ] bi fixnum> ; inline
|
|
||||||
|
|
||||||
: grow-hash ( hash -- )
|
: grow-hash ( hash -- )
|
||||||
[ [ >alist ] [ assoc-size 1 + ] bi ] keep
|
[ [ >alist ] [ assoc-size 1 + ] bi ] keep
|
||||||
[ reset-hash ] keep
|
[ reset-hash ] keep
|
||||||
swap (rehash) ;
|
swap (rehash) ;
|
||||||
|
|
||||||
: ?grow-hash ( hash -- )
|
: ?grow-hash ( hash -- )
|
||||||
dup hash-large? [
|
dup hash-large? [ grow-hash ] [ drop ] if ; inline
|
||||||
grow-hash
|
|
||||||
] [
|
|
||||||
dup hash-stale? [
|
|
||||||
grow-hash
|
|
||||||
] [
|
|
||||||
drop
|
|
||||||
] if
|
|
||||||
] if ; inline
|
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
@ -118,10 +119,7 @@ M: hashtable assoc-size ( hash -- n )
|
||||||
dup >alist [ dup clear-assoc ] dip (rehash) ;
|
dup >alist [ dup clear-assoc ] dip (rehash) ;
|
||||||
|
|
||||||
M: hashtable set-at ( value key hash -- )
|
M: hashtable set-at ( value key hash -- )
|
||||||
dup ?grow-hash
|
dup ?grow-hash dupd new-key@ set-nth-pair ;
|
||||||
2dup new-key@
|
|
||||||
[ rot hash-count+ set-nth-pair ]
|
|
||||||
[ rot drop set-nth-pair ] if ;
|
|
||||||
|
|
||||||
: associate ( value key -- hash )
|
: associate ( value key -- hash )
|
||||||
2 <hashtable> [ set-at ] keep ;
|
2 <hashtable> [ set-at ] keep ;
|
||||||
|
|
Loading…
Reference in New Issue