! Copyright (C) 2020 Michael Raitza ! See http://factorcode.org/license.txt for BSD license. ! ! * Crit-bit trees ! ** Rationale ! Critbit trees are described in [[https://cr.yp.to/critbit.html][djb's crit-bit tree]]. They are an evolution of ! PATRICIA trees showing that fast insertion, deletion, exact searching and suffix ! searching is possible with this data structure. ! The strength of this datastructure, according to its author, lies in its simple ! design and its optimisation to be machine parsable using machine word-sized ! operations where possible. Like PATRICIA trees, crit-bit trees are ! prefix-compressed, with internal nodes storing next decision point (the critical ! bit) in a length field (encoded as an integer and a mask) and two successor ! pointers. Arbitrary data objects make up its leaves. USING: accessors kernel math sequences serialize trees trees.private ; IN: trees.cb; TUPLE: cb < tree ; : ( -- tree ) cb new-tree ; inline ( byte# bits key value -- node ) cb-node new-node >>bits >>byte# ; inline ! 0 = left ! 1 = right : direction ( byte bits -- direction ) bitor 1 + -8 shift ; inline : key-side ( byte bits -- side ) direction 0 = -1 1 ? ; : get-byte-at ( byte# key -- byte/0 ) object>bytes ?nth [ 0 ] unless* ; ! ** Insertion ! Explain... ! Keep the byte sequence of the current key in =key-bytes= and provide a working ! environment for it with =with-key=. SYMBOL: key-bytes : with-key ( key quot -- ) [ key-bytes ] dip with-variable ; inline DEFER: cb-set ! TODO Rewrite with =with-key=. : cb-insert ( value key node -- node taller? created? ) 2dup [ byte#>> ] [ bits>> ] bi [ swap get-byte-at ] dip key-side [ node-link cb-set ] with-side ; ! Implement this and cb-insert using SYMBOL for current key bytes while ! traversing 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 t t ] if* ; PRIVATE>