2008-08-06 02:06:14 -04:00
|
|
|
! Based on Clojure's PersistentHashMap by Rich Hickey.
|
|
|
|
|
2008-09-05 20:29:14 -04:00
|
|
|
USING: math math.bitwise arrays kernel accessors locals sequences
|
|
|
|
sequences.private
|
2008-08-06 02:06:14 -04:00
|
|
|
persistent.sequences
|
|
|
|
persistent.hashtables.config
|
|
|
|
persistent.hashtables.nodes ;
|
|
|
|
IN: persistent.hashtables.nodes.bitmap
|
|
|
|
|
|
|
|
: index ( bit bitmap -- n ) [ 1- ] dip bitand bit-count ; inline
|
|
|
|
|
|
|
|
M:: bitmap-node (entry-at) ( key hashcode bitmap-node -- entry )
|
|
|
|
[let* | shift [ bitmap-node shift>> ]
|
|
|
|
bit [ hashcode shift bitpos ]
|
|
|
|
bitmap [ bitmap-node bitmap>> ]
|
|
|
|
nodes [ bitmap-node nodes>> ] |
|
2008-08-06 05:46:44 -04:00
|
|
|
bitmap bit bitand 0 eq? [ f ] [
|
2008-08-06 02:06:14 -04:00
|
|
|
key hashcode
|
|
|
|
bit bitmap index nodes nth-unsafe
|
|
|
|
(entry-at)
|
|
|
|
] if
|
|
|
|
] ;
|
|
|
|
|
|
|
|
M:: bitmap-node (new-at) ( shift value key hashcode bitmap-node -- node' added-leaf )
|
|
|
|
[let* | shift [ bitmap-node shift>> ]
|
|
|
|
bit [ hashcode shift bitpos ]
|
|
|
|
bitmap [ bitmap-node bitmap>> ]
|
|
|
|
idx [ bit bitmap index ]
|
|
|
|
nodes [ bitmap-node nodes>> ] |
|
2008-08-06 05:46:44 -04:00
|
|
|
bitmap bit bitand 0 eq? [
|
2008-08-06 02:06:14 -04:00
|
|
|
[let | new-leaf [ value key hashcode <leaf-node> ] |
|
|
|
|
bitmap bit bitor
|
|
|
|
new-leaf idx nodes insert-nth
|
|
|
|
shift
|
|
|
|
<bitmap-node>
|
|
|
|
new-leaf
|
|
|
|
]
|
|
|
|
] [
|
|
|
|
[let | n [ idx nodes nth ] |
|
|
|
|
shift radix-bits + value key hashcode n (new-at)
|
|
|
|
[let | new-leaf [ ] n' [ ] |
|
|
|
|
n n' eq? [
|
|
|
|
bitmap-node
|
|
|
|
] [
|
|
|
|
bitmap
|
|
|
|
n' idx nodes new-nth
|
|
|
|
shift
|
|
|
|
<bitmap-node>
|
|
|
|
] if
|
|
|
|
new-leaf
|
|
|
|
]
|
|
|
|
]
|
|
|
|
] if
|
|
|
|
] ;
|
|
|
|
|
|
|
|
M:: bitmap-node (pluck-at) ( key hashcode bitmap-node -- node' )
|
|
|
|
[let | bit [ hashcode bitmap-node shift>> bitpos ]
|
|
|
|
bitmap [ bitmap-node bitmap>> ]
|
|
|
|
nodes [ bitmap-node nodes>> ]
|
|
|
|
shift [ bitmap-node shift>> ] |
|
2008-08-06 05:46:44 -04:00
|
|
|
bit bitmap bitand 0 eq? [ bitmap-node ] [
|
2008-08-06 02:06:14 -04:00
|
|
|
[let* | idx [ bit bitmap index ]
|
|
|
|
n [ idx nodes nth-unsafe ]
|
|
|
|
n' [ key hashcode n (pluck-at) ] |
|
|
|
|
n n' eq? [
|
|
|
|
bitmap-node
|
|
|
|
] [
|
|
|
|
n' [
|
|
|
|
bitmap
|
|
|
|
n' idx nodes new-nth
|
|
|
|
shift
|
|
|
|
<bitmap-node>
|
|
|
|
] [
|
2008-08-06 05:46:44 -04:00
|
|
|
bitmap bit eq? [ f ] [
|
2008-08-06 02:06:14 -04:00
|
|
|
bitmap bit bitnot bitand
|
|
|
|
idx nodes remove-nth
|
|
|
|
shift
|
|
|
|
<bitmap-node>
|
|
|
|
] if
|
|
|
|
] if
|
|
|
|
] if
|
|
|
|
]
|
|
|
|
] if
|
|
|
|
] ;
|
|
|
|
|
|
|
|
M: bitmap-node >alist% ( node -- ) nodes>> >alist-each% ;
|