1
0
Fork 0

Implement set-at; cb-set for the empty tree

master
Michael Raitza 2020-02-09 15:54:27 +01:00
parent 5a7d699b3b
commit 3e2f2e7dac
1 changed files with 41 additions and 23 deletions

View File

@ -7,14 +7,15 @@
! PATRICIA trees showing that fast insertion, deletion, exact searching and suffix ! PATRICIA trees showing that fast insertion, deletion, exact searching and suffix
! searching is possible with this data structure. ! searching is possible with this data structure.
! The strength of this datastructure, according to its author, lies in its simple ! The strength of this data structure, according to its author, lies in its
! design and its optimisation to be machine parsable using machine word-sized ! simple design and its optimisation to be machine parsable using machine
! operations where possible. Like PATRICIA trees, crit-bit trees are ! word-sized operations where possible. Like PATRICIA trees, crit-bit trees are
! prefix-compressed, with internal nodes storing next decision point (the critical ! prefix-compressed, with internal nodes storing next decision point (the
! bit) in a length field (encoded as an integer and a mask) and two successor ! critical bit) in a length field (encoded as an integer and a mask) and two
! pointers. Arbitrary data objects make up its leaves. ! successor pointers. Arbitrary data objects make up its leaves.
USING: accessors kernel math sequences serialize trees trees.private ; USING: accessors arrays assocs kernel math namespaces sequences serialize trees
trees.private ;
IN: trees.cb; IN: trees.cb;
TUPLE: cb < tree ; TUPLE: cb < tree ;
@ -23,49 +24,66 @@ TUPLE: cb < tree ;
<PRIVATE <PRIVATE
TUPLE: cb-node < node byte# bits ; TUPLE: cb-node < node { byte# integer } { bits integer } ;
: <cb-node> ( byte# bits key value -- node ) : <cb-node> ( byte# bits key value -- node )
cb-node new-node cb-node new-node
>>bits swap >>bits
>>byte# ; inline swap >>byte# ; inline
! 0 = left ! 0 = left
! 1 = right ! 1 = right
: direction ( byte bits -- direction ) : direction ( n n -- direction )
bitor 1 + -8 shift ; inline bitor 1 + -8 shift ; inline
: key-side ( byte bits -- side ) : key-side ( bits byte -- side )
direction 0 = -1 1 ? ; direction 0 = -1 1 ? ;
: get-byte-at ( byte# key -- byte/0 ) : get-byte-at ( byte# key -- byte/0 )
object>bytes ?nth [ 0 ] unless* ; object>bytes ?nth [ 0 ] unless* ;
! ** Insertion
! Explain...
! Keep the byte sequence of the current key in =key-bytes= and provide a working ! Keep the byte sequence of the current key in =key-bytes= and provide a working
! environment for it with =with-key=. ! environment for it with =with-key=.
SYMBOL: key-bytes SYMBOL: key-bytes
SYMBOL: current-key
: with-key ( key quot -- ) : with-key ( key quot -- )
[ key-bytes ] dip with-variable ; inline [
{ current-key key-bytes }
[ dup object>bytes 2array ] dip zip
] dip with-variables ; inline
: byte-at ( byte# -- byte/0 )
key-bytes get ?nth [ 0 ] unless* ;
! ** Insertion
! Explain...
DEFER: cb-set DEFER: cb-set
! TODO Rewrite with =with-key=.
: cb-insert ( value key node -- node taller? created? ) : cb-insert ( value key node -- node taller? created? )
2dup [ byte#>> ] [ bits>> ] bi f
[ swap get-byte-at ] dip key-side [ swap [
node-link cb-set dup [ bits>> ] [ byte#>> ] bi
] with-side ; byte-at key-side [
node-link cb-set
] with-side
] with-key ;
! Implement this and cb-insert using SYMBOL for current key bytes while ! Implement this and cb-insert using SYMBOL for current key bytes while
! traversing the tree. ! traversing the tree.
: (cb-set) ( value key node -- node taller? created? ) : (cb-set) ( value key node -- node taller? created? )
; drop
dup key>> current-key get = [
current-key get >>key swap >>value f f
] [ current-key get swap cb-insert ] if ;
! Insert a node into the tree
: cb-set ( value key node -- node taller? created? ) : cb-set ( value key node -- node taller? created? )
[ (cb-set) ] [ swap [ [ 0 get-byte-at 0xfe ] keep ] dip <cb-node> t t ] if* ; [ (cb-set) ] [ [ 0 byte-at 0xfe ] 2dip swap <cb-node> t t ] if* ;
PRIVATE> PRIVATE>
M: cb set-at ( value key cb -- )
[ cb-set nip swap ] change-root
swap [ dup inc-count ] when drop ;