1#![cfg_attr(feature = "nightly", feature(core_intrinsics))]
2#![deny(rust_2018_idioms, unsafe_op_in_unsafe_fn)]
3#![warn(missing_docs)]
4#![doc = include_str!("../README.md")]
5
6pub mod algorithm;
7mod core;
8mod read;
9mod util;
10mod view;
11mod write;
12
13pub use read::*;
14pub(crate) use util::loom;
15pub use util::{deterministic::*, Alias};
16pub use view::View;
17pub use write::*;
18
19use self::core::Core;
20use std::{
21 collections::hash_map::RandomState,
22 fmt::{self, Debug, Formatter},
23 hash::{BuildHasher, Hash},
24};
25
26pub(crate) type Map<K, V, S = RandomState> = hashbrown::HashMap<Alias<K>, Alias<V>, S>;
27
28pub fn new<K, V>() -> (WriteHandle<K, V>, ReadHandle<K, V>)
33where
34 K: TrustedHashEq,
35{
36 Builder::new().build()
37}
38
39pub fn with_capacity<K, V>(capacity: usize) -> (WriteHandle<K, V>, ReadHandle<K, V>)
44where
45 K: TrustedHashEq,
46{
47 Builder::new().with_capacity(capacity).build()
48}
49
50pub unsafe fn with_hasher<K, V, S>(hasher: S) -> (WriteHandle<K, V, S>, ReadHandle<K, V, S>)
59where
60 K: TrustedHashEq,
61 S: Clone + BuildHasher,
62{
63 unsafe { Builder::new().with_hasher(hasher).build() }
64}
65
66#[derive(Clone, Copy)]
71pub struct Builder<S = RandomState> {
72 capacity: usize,
73 hasher: HasherGen<S>,
74}
75
76impl<S> Debug for Builder<S> {
77 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
78 f.debug_struct("Builder")
79 .field("capacity", &self.capacity)
80 .field("hasher", &std::any::type_name::<S>())
81 .finish()
82 }
83}
84
85impl Builder<RandomState> {
86 pub fn new() -> Self {
89 Self {
90 capacity: 0,
91 hasher: HasherGen::MakeBoth(|| {
92 let hasher = RandomState::default();
93 (hasher.clone(), hasher)
94 }),
95 }
96 }
97}
98
99impl Default for Builder<RandomState> {
100 fn default() -> Self {
101 Self::new()
102 }
103}
104
105impl<S> Builder<S> {
106 pub fn with_capacity(self, capacity: usize) -> Self {
108 Self {
109 capacity,
110 hasher: self.hasher,
111 }
112 }
113
114 pub unsafe fn with_hasher<H>(self, hasher: H) -> Builder<H>
121 where
122 H: Clone + BuildHasher,
123 {
124 Builder {
125 capacity: self.capacity,
126 hasher: HasherGen::Clone(hasher, H::clone),
127 }
128 }
129
130 pub unsafe fn with_hasher_generator<H>(self, gen: fn() -> H) -> Builder<H>
139 where
140 H: BuildHasher,
141 {
142 Builder {
143 capacity: self.capacity,
144 hasher: HasherGen::Generate(gen),
145 }
146 }
147
148 pub fn build<K, V>(self) -> (WriteHandle<K, V, S>, ReadHandle<K, V, S>)
163 where
164 K: TrustedHashEq,
165 S: BuildHasher,
166 {
167 unsafe { self.build_assert_trusted() }
168 }
169
170 pub unsafe fn build_assert_trusted<K, V>(self) -> (WriteHandle<K, V, S>, ReadHandle<K, V, S>)
177 where
178 K: Hash + Eq,
179 S: BuildHasher,
180 {
181 unsafe { Core::build_map(self.into_args()) }
182 }
183
184 pub(crate) fn into_args(self) -> BuilderArgs<S> {
185 let (h1, h2) = self.hasher.generate();
186 BuilderArgs {
187 capacity: self.capacity,
188 h1,
189 h2,
190 }
191 }
192}
193
194#[derive(Clone, Copy)]
195enum HasherGen<S> {
196 Generate(fn() -> S),
197 MakeBoth(fn() -> (S, S)),
198 Clone(S, fn(&S) -> S),
199}
200
201impl<S> HasherGen<S> {
202 fn generate(self) -> (S, S) {
203 match self {
204 Self::Generate(gen) => (gen(), gen()),
205 Self::MakeBoth(make_both) => make_both(),
206 Self::Clone(hasher, clone) => (clone(&hasher), hasher),
207 }
208 }
209}
210
211pub(crate) struct BuilderArgs<S> {
212 pub capacity: usize,
213 pub h1: S,
214 pub h2: S,
215}
216
217#[allow(dead_code)]
229struct NotSendTypes;
230
231#[allow(dead_code)]
243struct NotSyncTypes;
244
245#[cfg(test)]
246mod tests {
247 use super::*;
248 use std::{collections::hash_map::DefaultHasher, marker::PhantomData};
249
250 fn assert_send<T: Send>() {}
251 fn assert_sync<T: Sync>() {}
252
253 #[derive(PartialEq, Eq, Hash)]
254 struct SendOnly(PhantomData<*const u8>);
255
256 unsafe impl Send for SendOnly {}
257
258 #[derive(PartialEq, Eq, Hash)]
259 struct SyncOnly(PhantomData<*const u8>);
260
261 unsafe impl Sync for SyncOnly {}
262
263 #[derive(PartialEq, Eq, Hash)]
264 struct SendSync;
265
266 impl BuildHasher for SendSync {
267 type Hasher = DefaultHasher;
268
269 fn build_hasher(&self) -> Self::Hasher {
270 unimplemented!()
271 }
272 }
273
274 #[test]
275 fn send_types() {
276 assert_send::<ReadHandle<SendSync, SendSync, SendSync>>();
277 assert_send::<WriteHandle<SendSync, SendSync, SendSync>>();
278 assert_send::<View<ReadGuard<'_, SendSync, SendSync, SendSync>>>();
279 assert_send::<Leaked<SendOnly>>();
280 }
281
282 #[test]
283 fn sync_types() {
284 assert_sync::<ReadHandle<SendSync, SendSync, SendSync>>();
285 assert_sync::<View<ReadGuard<'_, SendSync, SendSync, SendSync>>>();
286 assert_sync::<Leaked<SyncOnly>>();
287 }
288}