"transient" im::HashMap?

It is my understanding that im::HashMap, being an immutable structure, assumes that every intermediate state.

In Clojure, for performance reasons, there is a notion of 'transients' https://clojure.org/reference/transients

I am wondering if there is something similar for im::HashMap. So I want to take a im::HashMap, construct a "&mut transient" of it -- do some intermediate ops on this "transient" (with it being acceptable for ops on intermediate states to be destructive rather than persistent) -- and then, at the end, convert the transient back to a im::HashMap.

Is there any notion of this type of "transient" in Rust ?

I believe the &mut self methods on im::HashMap is the closest you get.

1 Like

The In-Place Mutation section in im's crate docs makes it sound like some of the types will be mutated in-place when there is only one pointer to the data. Which I think is what you're looking for.

All of these data structures support in-place copy-on-write mutation, which means that if you're the sole user of a data structure, you can update it in place without taking the performance hit of making a copy of the data structure before modifying it (this is about an order of magnitude faster than immutable operations, almost as fast as std::collections 's mutable data structures).

Looking at the source code for im::HashMap::insert(), I believe the PoolRef::make_mut() line is responsible for in-place copy-on-write in im::HashMap.


impl<K, V, S> HashMap<K, V, S>
where
    K: Hash + Eq + Clone,
    V: Clone,
    S: BuildHasher,
{
    ...

    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
        let hash = hash_key(&*self.hasher, &k);
        let root = PoolRef::make_mut(&self.pool.0, &mut self.root);
        let result = root.insert(&self.pool.0, hash, 0, (k, v));
        if result.is_none() {
            self.size += 1;
        }
        result.map(|(_, v)| v)
    }
}
2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.