frozen_hashbrown/
lib.rs

1//! Frozen version of Rust standard library's [hashbrown](https://github.com/rust-lang/hashbrown).
2//!
3//! # What is this about
4//!
5//! 1. Allow you to dump the memory of a `std::collections::HashMap` into a blob
6//! 2. Load the blob and re-construct the hashmap
7//! 3. Such that we can iterate through the data!
8//!
9//! # What is this for
10//!
11//! 1. It's used in FireDBG to allow us to capture and render `HashMap`
12//! 2. It could also probably allow us to extract `HashMap` from `coredump`
13//!
14//! # How it works
15//!
16//! Online
17//!
18//! 1. Construct `TableLayout` for `(K, V)`
19//! 2. Extract `ctrl` and `bucket_mask`
20//! 3. `calculate_layout_for(buckets)` and calculate the address `NonNull<u8>` and `Layout`
21//! 4. Dump the memory into a blob
22//!
23//! Offline
24//!
25//! 1. Load the blob into memory
26//! 2. Re-construct `hashbrown::map::HashMap` for `(K, V)`
27//! 3. Ready to serve
28//!
29//! # Why does it work
30//!
31//! 1. The `HashMap` in Rust's standard library is a flat hashmap. Meaning it's only backed by a single contiguous piece of memory.
32//! 2. It's dense for small maps and is very memory efficient
33//! 3. It's more like a glorified `Vec<(K, V)>` with an index to assist hash key lookup
34//!
35//! # How to use
36//!
37//! ```rust
38//! use frozen_hashbrown::FrozenHashMap;
39//! use std::collections::HashMap;
40//!
41//! let map: HashMap<char, i32> = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
42//!     .into_iter()
43//!     .collect();
44//! let snapshot = format!("{map:?}");
45//!
46//! let frozen = FrozenHashMap::construct(&map);
47//! std::mem::drop(map);
48//! let frozen: Vec<u8> = frozen.store();
49//!
50//! let mut unfrozen = FrozenHashMap::load(&frozen).expect("Failed to load");
51//! let unfrozen = unfrozen
52//!     .reconstruct::<char, i32>()
53//!     .expect("Failed to reconstruct");
54//! let unfrozen_snapshot = format!("{unfrozen:?}");
55//!
56//! // even the "random" iteration order holds
57//! assert_eq!(snapshot, unfrozen_snapshot);
58//! ```
59//!
60//! More examples under https://github.com/tyt2y3/frozen-hashbrown/blob/main/tests/unfreeze.rs
61//!
62//! #
63
64#[cfg(not(target_pointer_width = "64"))]
65compile_error!("Only support 64-bit platforms");
66
67mod frozen;
68mod iter;
69
70pub use frozen::*;
71pub use iter::*;
72
73pub struct Group {}
74
75cfg_if::cfg_if! {
76    if #[cfg(all(
77        target_feature = "sse2",
78        any(target_arch = "x86", target_arch = "x86_64"),
79        not(miri)
80    ))] {
81        impl Group {
82            pub const WIDTH: usize = 16;
83        }
84    } else if #[cfg(all(target_arch = "aarch64", target_feature = "neon"))] {
85        impl Group {
86            pub const WIDTH: usize = 8;
87        }
88    } else {
89        // generic
90        impl Group {
91            pub const WIDTH: usize = 8;
92        }
93    }
94}