deepmesa.com

LinkedHashMap

A Rust HashMap with a predictable Iteration order and constant time inserts and lookups

The LinkedHashMap combines a HashMap and a LinkedList for O(1) inserts, lookups and deletes along with a predictable iteration order.

All the basic functions - get(), get_mut(), get_key_value(), put(), insert(), remove(), remove_entry() - provide constant time performance which is expected to be lower than that of the Hashmap given the added expense of of maintaining and updating the underlying linked list.

Getting Started

use deepmesa::collections::LinkedHashMap;
use deepmesa::collections::map::Order;

let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
lhm.put(1, "a");
lhm.put(2, "b");

assert_eq!(lhm.get(&1), Some(&"a"));
assert_eq!(lhm.get(&2), Some(&"b"));

if let Some(val) = lhm.get_mut(&1) {
    *val = "d";
}

assert_eq!(lhm.get(&1), Some(&"d"));

Iteration Order

This map holds a LinkedList of all the elements that defines the iteration order. The order is either InsertionOrder or AccessOrder. InsertionOrder is the order in which the keys were inserted into the map from least recently inserted (oldest) to most recently inserted (newest). ReInserting a key (via the insert or put methods) will change the insertion order to make the re-inserted key the most recently inserted (newest) in the order.

AccessOrder is the order in which the keys in the map were last accessed (via the get(), get_key_value(), get_mut() methods) from least-recently accessed (oldest) to most recently accessed (newest). Iterating over the map using one of the iterators - iter(), iter_mut(), keys(), values(), values_mut() - does not affect the order.

Iteration over the map requires time proportional to the length of the map (O(len)) regardless of the capacity because it iterates over the elements of the underlying linked list. The iteration order of the map is always from oldest entry (accessed or inserted) to the newest entry (accessed or inserted).

The map offers iterators over the elements, keys and values with mutable iterators for elements and values. The iterators can also be reversed.

// Construct a map in InsertionOrder
use deepmesa::collections::LinkedHashMap;
use deepmesa::collections::map::Order;

let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::InsertionOrder, None);
lhm.put(1, "a");
lhm.put(2, "b");

lhm.get(&1);

let mut iter = lhm.iter();
assert_eq!(iter.next(), Some((&1, &"a")));
assert_eq!(iter.next(), Some((&2, &"b")));
assert_eq!(iter.next(), None);
iter = iter.reverse();
assert_eq!(iter.next(), Some((&2, &"b")));
assert_eq!(iter.next(), Some((&1, &"a")));
assert_eq!(iter.next(), None);


// Construct a map in AccessOrder
let mut lhm = LinkedHashMap::<u16, &str>::new(10, Order::AccessOrder, None);
lhm.put(1, "a");
lhm.put(2, "b");

lhm.get(&1);

let mut iter = lhm.iter();
assert_eq!(iter.next(), Some((&2, &"b")));
assert_eq!(iter.next(), Some((&1, &"a")));
assert_eq!(iter.next(), None);
iter = iter.reverse();
assert_eq!(iter.next(), Some((&1, &"a")));
assert_eq!(iter.next(), Some((&2, &"b")));
assert_eq!(iter.next(), None);

Evicting Elements

The Map also supports construction with an evict_eldest function that can be provided to implement a policy for removing entries when new elements are added to the map. A LinkedHashMap with AccessOrder and an eviction function is well suited to building an LRU Cache.

use deepmesa::collections::map::Entry;
pub fn evict<K,V>(len: usize, capacity: usize, e: &Entry<K, V>) -> bool {
    if len > capacity {
        return true;
    }
    return false;
}

use deepmesa::collections::LinkedHashMap;
use deepmesa::collections::map::Order;

let mut lhm = LinkedHashMap::<u16, &str>::new(3, Order::AccessOrder, Some(evict));
lhm.put(1, "a");
lhm.put(2, "b");
lhm.put(3, "c");

assert_eq!(lhm.get(&2), Some(&"b"));
lhm.put(4, "d");
assert_eq!(lhm.get(&1), None);
About the author

Open Source Software in Rust & Go

Distributed Systems, Search and Artificial Intelligence

Download more icon variants from https://tabler-icons.io/i/brand-github Github
deepmesa.com

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to deepmesa.com.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.