data structures
hash array mapped trie
HAMT
functional programming
computer science

`Hash` Array Mapped Trie HAMT

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

A Hash Array Mapped Trie (HAMT) is a data structure that efficiently stores associative arrays (or key-value pairs) and sets. It combines the principles of tries (prefix trees) and hash tables to achieve both space efficiency and fast access time. HAMTs are chiefly used in functional programming languages where immutability is a key constraint because they allow relatively efficient updates without destructively modifying the data structure.

Structure of HAMT

A HAMT structure is essentially a trie where each node has an array that acts as a bitmap index. It uses hash codes of keys to determine the path from the root to the leaf nodes. This path consists of several hash segments, each used as an index in the nodes' arrays.

Anatomy of a Node

Each node in a HAMT contains:

  1. Bitmap: A sequence of bits that indicates which slots in the node's array contain valid child pointers or values.
  2. Array: Contains either values (in case of leaf nodes) or pointers to other nodes.
  3. Key-Value Pairs: For nodes terminating with actual data, the arrays store pairs.

Algorithm Mechanics

  • Insertion: The algorithm calculates the hash of the key and traverses the trie according to segments of the hash. If an array lacks space, the structure applies a glass-box technique to lazily expand.
  • Search: Queries compute the hash of the key. Navigating the trie involves computing indices from hash segments to access nodes.
  • Deletion: This involves retracing and cleaning up nodes that become unnecessary due to a removed key.

Examples

Let's consider a simple case where we want to insert a key "key1" with value "value1" .

  • Compute the hash of "key1" .
  • Break the hash into segments, using each segment to determine the index at each level of the trie.
  • Follow the calculated path and insert the key-value pair.

Example Code (in Python-like Pseudocode)

  • Space Efficiency: HAMTs sacrifice space for speed by lazily expanding nodes and reusing paths via bitmap indices.
  • Persistent Data Structures: Every mutation generates a new version of the HAMT, supporting functional programming requirements for immutability.
  • Concurrency Friendly: Immutable nature negates synchronization issues in parallel computations.
  • Lazy Expansion: Nodes only expand when necessary, conserving memory.
  • Scalable: Designed to efficiently handle large datasets with uniform access times.
  • Space-Intensive: While nodes are lazily expanded, the abstraction level can result in higher memory footprints.
  • Complex Implementation: HARMs can be non-trivial to implement and understand due to the interplay of bitmaps and hash calculations.
  • Functional Programming Languages: Languages like Clojure and Scala employ HAMTs in their native data structures for maps and sets.
  • Concurrency Systems: Where immutable data types are advantageous.
  • Compilers and Interpreters: To manage symbol tables and environments efficiently.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.