Different Tries

Tikhon Jelvis

Tries

  • key-value map
    • simple
    • persistent
    • fast

Retrieval

Also Called

  • digital trees
  • prefix trees
  • radix trees

Tries

  • basic trie
  • PATRICIA trie: Data.IntMap
  • variations
    • branching factor
    • (Persistent) Adaptive Radix Tree

Example

Sorry, your browser does not support SVG.

lookup “b”

Sorry, your browser does not support SVG.

  • b = 1

lookup “bab”

Sorry, your browser does not support SVG.

  • b

lookup “bab”

Sorry, your browser does not support SVG.

  • b → a

lookup “bab”

Sorry, your browser does not support SVG.

  • b → a → b = 7

data Trie a = 
  Node (Maybe a) [(Char, Trie a)]

lookup :: String → Trie a → Maybe a

insert :: String → a → Trie a → Trie a

Prefixes

  • every key starting with “ba”

Sorry, your browser does not support SVG. Sorry, your browser does not support SVG.

PATRICIA

Practical Algorithm to Retrieve Information Coded in Alphanumeric

  • developed in 1968

Okasaki and Gill, 1998

okasaki.png

Data.IntMap

  • Int keys
    • bit-by-bit
  • persistent
  • ByteString keys?

Structure

  • branch on each bit

Sorry, your browser does not support SVG.

Paths

Sorry, your browser does not support SVG.

two keys: 00011, 00001

Compressed Paths

Sorry, your browser does not support SVG.

Compressed Paths

Sorry, your browser does not support SVG.

Compressed Paths

Sorry, your browser does not support SVG.

Data.IntMap

type Prefix = Int
type Mask = Int

data IntMap a = 
    Branch !Prefix !Mask 
           !(IntMap a) !(IntMap a)
  | Leaf !Prefix a
  | Empty

Performance Considerations

  • unbox as much as possible
  • spine strict
  • highestBitSet ~ bitwise trick

highestBitSet

   -- Borrowed from Haskell's Data.IntMap
highestBitSet :: Int -> Int
highestBitSet n =
  case (n .|. shiftR n 1) of
    n -> case (n .|. shiftR n 2) of
      n -> case (n .|. shiftR n 4) of
        n -> case (n .|. shiftR n 8) of
          n -> case (n .|. shiftR n 16) of
            n -> case (n .|. shiftR n 32) of   -- for 64 bit platforms
              n -> (n `xor` (shiftR n 1))

Performance

  • much faster than Data.Map
    • fast lookup/insert
    • fast scans and merges
  • slower than mutable hash map

Branching Factor

Sorry, your browser does not support SVG. n bits of key = 2ⁿ children per node

branching-tradeoff.png

  • from ART paper
  • benchmark with mutable tries

Adaptive Radix Trees

art.png

Adaptive Radix Trees

  • branching factor: 256
  • byte at a time

art-nodes.png

Four Types of Nodes

art-nodes-details.png

Persistent Adaptive Radix Trees?

Functional Graph Library

graph.png

Summary

  • IntMap: binary radix tree
  • different branching factors
    • time/memory tradeoff
  • (persistent) adaptive radix trees
  • optimize for Haskell?

Created by Tikhon Jelvis.