| 1 | use crate::avl::{Iter, IterMut, Tree, WeakTree}; |
| 2 | pub use crate::chunk::DEFAULT_SIZE; |
| 3 | use core::{ |
| 4 | borrow::Borrow, |
| 5 | cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}, |
| 6 | default::Default, |
| 7 | fmt::{self, Debug, Formatter}, |
| 8 | hash::{Hash, Hasher}, |
| 9 | iter::FromIterator, |
| 10 | ops::{Index, IndexMut, RangeBounds, RangeFull}, |
| 11 | }; |
| 12 | |
| 13 | #[cfg (feature = "serde" )] |
| 14 | use serde::{ |
| 15 | de::{MapAccess, Visitor}, |
| 16 | ser::SerializeMap, |
| 17 | Deserialize, Deserializer, Serialize, Serializer, |
| 18 | }; |
| 19 | |
| 20 | #[cfg (feature = "serde" )] |
| 21 | use core::marker::PhantomData; |
| 22 | |
| 23 | #[cfg (feature = "rayon" )] |
| 24 | use rayon::{ |
| 25 | iter::{FromParallelIterator, IntoParallelIterator}, |
| 26 | prelude::*, |
| 27 | }; |
| 28 | |
| 29 | /// This Map uses a similar strategy to BTreeMap to ensure cache |
| 30 | /// efficient performance on modern hardware while still providing |
| 31 | /// log(N) get, insert, and remove operations. |
| 32 | /// |
| 33 | /// For good performance, it is very important to understand |
| 34 | /// that clone is a fundamental operation, it needs to be fast |
| 35 | /// for your key and data types, because it's going to be |
| 36 | /// called a lot whenever you change the map. |
| 37 | /// |
| 38 | /// # Why |
| 39 | /// |
| 40 | /// 1. Multiple threads can read this structure even while one thread |
| 41 | /// is updating it. Using a library like arc_swap you can avoid ever |
| 42 | /// blocking readers. |
| 43 | /// |
| 44 | /// 2. Snapshotting this structure is free. |
| 45 | /// |
| 46 | /// # Examples |
| 47 | /// ``` |
| 48 | /// # extern crate alloc; |
| 49 | /// use alloc::string::String; |
| 50 | /// use self::immutable_chunkmap::map::MapM; |
| 51 | /// |
| 52 | /// let m = |
| 53 | /// MapM::new() |
| 54 | /// .insert(String::from("1" ), 1).0 |
| 55 | /// .insert(String::from("2" ), 2).0 |
| 56 | /// .insert(String::from("3" ), 3).0; |
| 57 | /// |
| 58 | /// assert_eq!(m.get("1" ), Option::Some(&1)); |
| 59 | /// assert_eq!(m.get("2" ), Option::Some(&2)); |
| 60 | /// assert_eq!(m.get("3" ), Option::Some(&3)); |
| 61 | /// assert_eq!(m.get("4" ), Option::None); |
| 62 | /// |
| 63 | /// for (k, v) in &m { |
| 64 | /// println!("key {}, val: {}" , k, v) |
| 65 | /// } |
| 66 | /// ``` |
| 67 | #[derive (Clone)] |
| 68 | pub struct Map<K: Ord + Clone, V: Clone, const SIZE: usize>(Tree<K, V, SIZE>); |
| 69 | |
| 70 | /// Map using a smaller chunk size, faster to update, slower to search |
| 71 | pub type MapS<K, V> = Map<K, V, { DEFAULT_SIZE / 2 }>; |
| 72 | |
| 73 | /// Map using the default chunk size, a good balance of update and search |
| 74 | pub type MapM<K, V> = Map<K, V, DEFAULT_SIZE>; |
| 75 | |
| 76 | /// Map using a larger chunk size, faster to search, slower to update |
| 77 | pub type MapL<K, V> = Map<K, V, { DEFAULT_SIZE * 2 }>; |
| 78 | |
| 79 | /// A weak reference to a map. |
| 80 | #[derive (Clone)] |
| 81 | pub struct WeakMapRef<K: Ord + Clone, V: Clone, const SIZE: usize>(WeakTree<K, V, SIZE>); |
| 82 | |
| 83 | pub type WeakMapRefS<K, V> = WeakMapRef<K, V, { DEFAULT_SIZE / 2 }>; |
| 84 | pub type WeakMapRefM<K, V> = WeakMapRef<K, V, DEFAULT_SIZE>; |
| 85 | pub type WeakMapRefL<K, V> = WeakMapRef<K, V, { DEFAULT_SIZE * 2 }>; |
| 86 | |
| 87 | impl<K, V, const SIZE: usize> WeakMapRef<K, V, SIZE> |
| 88 | where |
| 89 | K: Ord + Clone, |
| 90 | V: Clone, |
| 91 | { |
| 92 | pub fn upgrade(&self) -> Option<Map<K, V, SIZE>> { |
| 93 | self.0.upgrade().map(Map) |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | impl<K, V, const SIZE: usize> Hash for Map<K, V, SIZE> |
| 98 | where |
| 99 | K: Hash + Ord + Clone, |
| 100 | V: Hash + Clone, |
| 101 | { |
| 102 | fn hash<H: Hasher>(&self, state: &mut H) { |
| 103 | self.0.hash(state) |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | impl<K, V, const SIZE: usize> Default for Map<K, V, SIZE> |
| 108 | where |
| 109 | K: Ord + Clone, |
| 110 | V: Clone, |
| 111 | { |
| 112 | fn default() -> Map<K, V, SIZE> { |
| 113 | Map::new() |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | impl<K, V, const SIZE: usize> PartialEq for Map<K, V, SIZE> |
| 118 | where |
| 119 | K: PartialEq + Ord + Clone, |
| 120 | V: PartialEq + Clone, |
| 121 | { |
| 122 | fn eq(&self, other: &Map<K, V, SIZE>) -> bool { |
| 123 | self.0 == other.0 |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | impl<K, V, const SIZE: usize> Eq for Map<K, V, SIZE> |
| 128 | where |
| 129 | K: Eq + Ord + Clone, |
| 130 | V: Eq + Clone, |
| 131 | { |
| 132 | } |
| 133 | |
| 134 | impl<K, V, const SIZE: usize> PartialOrd for Map<K, V, SIZE> |
| 135 | where |
| 136 | K: Ord + Clone, |
| 137 | V: PartialOrd + Clone, |
| 138 | { |
| 139 | fn partial_cmp(&self, other: &Map<K, V, SIZE>) -> Option<Ordering> { |
| 140 | self.0.partial_cmp(&other.0) |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | impl<K, V, const SIZE: usize> Ord for Map<K, V, SIZE> |
| 145 | where |
| 146 | K: Ord + Clone, |
| 147 | V: Ord + Clone, |
| 148 | { |
| 149 | fn cmp(&self, other: &Map<K, V, SIZE>) -> Ordering { |
| 150 | self.0.cmp(&other.0) |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | impl<K, V, const SIZE: usize> Debug for Map<K, V, SIZE> |
| 155 | where |
| 156 | K: Debug + Ord + Clone, |
| 157 | V: Debug + Clone, |
| 158 | { |
| 159 | fn fmt(&self, f: &mut Formatter) -> fmt::Result { |
| 160 | self.0.fmt(f) |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | impl<'a, Q, K, V, const SIZE: usize> Index<&'a Q> for Map<K, V, SIZE> |
| 165 | where |
| 166 | Q: Ord, |
| 167 | K: Ord + Clone + Borrow<Q>, |
| 168 | V: Clone, |
| 169 | { |
| 170 | type Output = V; |
| 171 | fn index(&self, k: &Q) -> &V { |
| 172 | self.get(k).expect(msg:"element not found for key" ) |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | impl<'a, Q, K, V, const SIZE: usize> IndexMut<&'a Q> for Map<K, V, SIZE> |
| 177 | where |
| 178 | Q: Ord, |
| 179 | K: Ord + Clone + Borrow<Q>, |
| 180 | V: Clone, |
| 181 | { |
| 182 | fn index_mut(&mut self, k: &'a Q) -> &mut Self::Output { |
| 183 | self.get_mut_cow(k).expect(msg:"element not found for key" ) |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | impl<K, V, const SIZE: usize> FromIterator<(K, V)> for Map<K, V, SIZE> |
| 188 | where |
| 189 | K: Ord + Clone, |
| 190 | V: Clone, |
| 191 | { |
| 192 | fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self { |
| 193 | Map::new().insert_many(elts:iter) |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | impl<'a, K, V, const SIZE: usize> IntoIterator for &'a Map<K, V, SIZE> |
| 198 | where |
| 199 | K: 'a + Ord + Clone, |
| 200 | V: 'a + Clone, |
| 201 | { |
| 202 | type Item = (&'a K, &'a V); |
| 203 | type IntoIter = Iter<'a, RangeFull, K, K, V, SIZE>; |
| 204 | fn into_iter(self) -> Self::IntoIter { |
| 205 | self.0.into_iter() |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | #[cfg (feature = "serde" )] |
| 210 | impl<K, V, const SIZE: usize> Serialize for Map<K, V, SIZE> |
| 211 | where |
| 212 | K: Serialize + Clone + Ord, |
| 213 | V: Serialize + Clone, |
| 214 | { |
| 215 | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
| 216 | where |
| 217 | S: Serializer, |
| 218 | { |
| 219 | let mut map = serializer.serialize_map(Some(self.len()))?; |
| 220 | for (k, v) in self { |
| 221 | map.serialize_entry(k, v)? |
| 222 | } |
| 223 | map.end() |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | #[cfg (feature = "serde" )] |
| 228 | struct MapVisitor<K: Clone + Ord, V: Clone, const SIZE: usize> { |
| 229 | marker: PhantomData<fn() -> Map<K, V, SIZE>>, |
| 230 | } |
| 231 | |
| 232 | #[cfg (feature = "serde" )] |
| 233 | impl<'a, K, V, const SIZE: usize> Visitor<'a> for MapVisitor<K, V, SIZE> |
| 234 | where |
| 235 | K: Deserialize<'a> + Clone + Ord, |
| 236 | V: Deserialize<'a> + Clone, |
| 237 | { |
| 238 | type Value = Map<K, V, SIZE>; |
| 239 | |
| 240 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
| 241 | formatter.write_str("expected an immutable_chunkmap::Map" ) |
| 242 | } |
| 243 | |
| 244 | fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> |
| 245 | where |
| 246 | A: MapAccess<'a>, |
| 247 | { |
| 248 | let mut t = Map::<K, V, SIZE>::new(); |
| 249 | while let Some((k, v)) = map.next_entry()? { |
| 250 | t.insert_cow(k, v); |
| 251 | } |
| 252 | Ok(t) |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | #[cfg (feature = "serde" )] |
| 257 | impl<'a, K, V, const SIZE: usize> Deserialize<'a> for Map<K, V, SIZE> |
| 258 | where |
| 259 | K: Deserialize<'a> + Clone + Ord, |
| 260 | V: Deserialize<'a> + Clone, |
| 261 | { |
| 262 | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
| 263 | where |
| 264 | D: Deserializer<'a>, |
| 265 | { |
| 266 | deserializer.deserialize_map(MapVisitor { |
| 267 | marker: PhantomData, |
| 268 | }) |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | #[cfg (feature = "rayon" )] |
| 273 | impl<'a, K, V, const SIZE: usize> IntoParallelIterator for &'a Map<K, V, SIZE> |
| 274 | where |
| 275 | K: 'a + Ord + Clone + Send + Sync, |
| 276 | V: Clone + Send + Sync, |
| 277 | { |
| 278 | type Item = (&'a K, &'a V); |
| 279 | type Iter = rayon::vec::IntoIter<(&'a K, &'a V)>; |
| 280 | |
| 281 | fn into_par_iter(self) -> Self::Iter { |
| 282 | self.into_iter().collect::<Vec<_>>().into_par_iter() |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | #[cfg (feature = "rayon" )] |
| 287 | impl<K, V, const SIZE: usize> FromParallelIterator<(K, V)> for Map<K, V, SIZE> |
| 288 | where |
| 289 | K: Ord + Clone + Send + Sync, |
| 290 | V: Clone + Send + Sync, |
| 291 | { |
| 292 | fn from_par_iter<I>(i: I) -> Self |
| 293 | where |
| 294 | I: IntoParallelIterator<Item = (K, V)>, |
| 295 | { |
| 296 | i.into_par_iter() |
| 297 | .fold_with(Map::new(), |mut m, (k, v)| { |
| 298 | m.insert_cow(k, v); |
| 299 | m |
| 300 | }) |
| 301 | .reduce_with(|m0, m1| m0.union(&m1, |_k, _v0, v1| Some(v1.clone()))) |
| 302 | .unwrap_or_else(Map::new) |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | impl<K, V, const SIZE: usize> Map<K, V, SIZE> |
| 307 | where |
| 308 | K: Ord + Clone, |
| 309 | V: Clone, |
| 310 | { |
| 311 | /// Create a new empty map |
| 312 | pub fn new() -> Self { |
| 313 | Map(Tree::new()) |
| 314 | } |
| 315 | |
| 316 | /// Create a weak reference to this map |
| 317 | pub fn downgrade(&self) -> WeakMapRef<K, V, SIZE> { |
| 318 | WeakMapRef(self.0.downgrade()) |
| 319 | } |
| 320 | |
| 321 | /// Return the number of strong references to this map (see Arc) |
| 322 | pub fn strong_count(&self) -> usize { |
| 323 | self.0.strong_count() |
| 324 | } |
| 325 | |
| 326 | /// Return the number of weak references to this map (see Arc) |
| 327 | pub fn weak_count(&self) -> usize { |
| 328 | self.0.weak_count() |
| 329 | } |
| 330 | |
| 331 | /// This will insert many elements at once, and is |
| 332 | /// potentially a lot faster than inserting one by one, |
| 333 | /// especially if the data is sorted. It is just a wrapper |
| 334 | /// around the more general update_many method. |
| 335 | /// |
| 336 | /// #Examples |
| 337 | ///``` |
| 338 | /// use self::immutable_chunkmap::map::MapM; |
| 339 | /// |
| 340 | /// let mut v = vec![(1, 3), (10, 1), (-12, 2), (44, 0), (50, -1)]; |
| 341 | /// v.sort_unstable_by_key(|&(k, _)| k); |
| 342 | /// |
| 343 | /// let m = MapM::new().insert_many(v.iter().map(|(k, v)| (*k, *v))); |
| 344 | /// |
| 345 | /// for (k, v) in &v { |
| 346 | /// assert_eq!(m.get(k), Option::Some(v)) |
| 347 | /// } |
| 348 | /// ``` |
| 349 | pub fn insert_many<E: IntoIterator<Item = (K, V)>>(&self, elts: E) -> Self { |
| 350 | Map(self.0.insert_many(elts)) |
| 351 | } |
| 352 | |
| 353 | /// This will remove many elements at once, and is potentially a |
| 354 | /// lot faster than removing elements one by one, especially if |
| 355 | /// the data is sorted. It is just a wrapper around the more |
| 356 | /// general update_many method. |
| 357 | pub fn remove_many<Q, E>(&self, elts: E) -> Self |
| 358 | where |
| 359 | E: IntoIterator<Item = Q>, |
| 360 | Q: Ord, |
| 361 | K: Borrow<Q>, |
| 362 | { |
| 363 | self.update_many(elts.into_iter().map(|q| (q, ())), |_, _, _| None) |
| 364 | } |
| 365 | |
| 366 | /// This method updates multiple bindings in one call. Given an |
| 367 | /// iterator of an arbitrary type (Q, D), where Q is any borrowed |
| 368 | /// form of K, an update function taking Q, D, the current binding |
| 369 | /// in the map, if any, and producing the new binding, if any, |
| 370 | /// this method will produce a new map with updated bindings of |
| 371 | /// many elements at once. It will skip intermediate node |
| 372 | /// allocations where possible. If the data in elts is sorted, it |
| 373 | /// will be able to skip many more intermediate allocations, and |
| 374 | /// can produce a speedup of about 10x compared to |
| 375 | /// inserting/updating one by one. In any case it should always be |
| 376 | /// faster than inserting elements one by one, even with random |
| 377 | /// unsorted keys. |
| 378 | /// |
| 379 | /// #Examples |
| 380 | /// ``` |
| 381 | /// use core::iter::FromIterator; |
| 382 | /// use self::immutable_chunkmap::map::MapM; |
| 383 | /// |
| 384 | /// let m = MapM::from_iter((0..4).map(|k| (k, k))); |
| 385 | /// let m = m.update_many( |
| 386 | /// (0..4).map(|x| (x, ())), |
| 387 | /// |k, (), cur| cur.map(|(_, c)| (k, c + 1)) |
| 388 | /// ); |
| 389 | /// assert_eq!( |
| 390 | /// m.into_iter().map(|(k, v)| (*k, *v)).collect::<Vec<_>>(), |
| 391 | /// vec![(0, 1), (1, 2), (2, 3), (3, 4)] |
| 392 | /// ); |
| 393 | /// ``` |
| 394 | pub fn update_many<Q, D, E, F>(&self, elts: E, mut f: F) -> Self |
| 395 | where |
| 396 | E: IntoIterator<Item = (Q, D)>, |
| 397 | Q: Ord, |
| 398 | K: Borrow<Q>, |
| 399 | F: FnMut(Q, D, Option<(&K, &V)>) -> Option<(K, V)>, |
| 400 | { |
| 401 | Map(self.0.update_many(elts, &mut f)) |
| 402 | } |
| 403 | |
| 404 | /// return a new map with (k, v) inserted into it. If k |
| 405 | /// already exists in the old map, the old binding will be |
| 406 | /// returned, and the new map will contain the new |
| 407 | /// binding. In fact this method is just a wrapper around |
| 408 | /// update. |
| 409 | pub fn insert(&self, k: K, v: V) -> (Self, Option<V>) { |
| 410 | let (root, prev) = self.0.insert(k, v); |
| 411 | (Map(root), prev) |
| 412 | } |
| 413 | |
| 414 | /// insert in place using copy on write semantics if self is not a |
| 415 | /// unique reference to the map. see `update_cow`. |
| 416 | pub fn insert_cow(&mut self, k: K, v: V) -> Option<V> { |
| 417 | self.0.insert_cow(k, v) |
| 418 | } |
| 419 | |
| 420 | /// return a new map with the binding for q, which can be any |
| 421 | /// borrowed form of k, updated to the result of f. If f returns |
| 422 | /// None, the binding will be removed from the new map, otherwise |
| 423 | /// it will be inserted. This function is more efficient than |
| 424 | /// calling `get` and then `insert`, since it makes only one tree |
| 425 | /// traversal instead of two. This method runs in log(N) time and |
| 426 | /// space where N is the size of the map. |
| 427 | /// |
| 428 | /// # Examples |
| 429 | /// ``` |
| 430 | /// use self::immutable_chunkmap::map::MapM; |
| 431 | /// |
| 432 | /// let (m, _) = MapM::new().update(0, 0, |k, d, _| Some((k, d))); |
| 433 | /// let (m, _) = m.update(1, 1, |k, d, _| Some((k, d))); |
| 434 | /// let (m, _) = m.update(2, 2, |k, d, _| Some((k, d))); |
| 435 | /// assert_eq!(m.get(&0), Some(&0)); |
| 436 | /// assert_eq!(m.get(&1), Some(&1)); |
| 437 | /// assert_eq!(m.get(&2), Some(&2)); |
| 438 | /// |
| 439 | /// let (m, _) = m.update(0, (), |k, (), v| v.map(move |(_, v)| (k, v + 1))); |
| 440 | /// assert_eq!(m.get(&0), Some(&1)); |
| 441 | /// assert_eq!(m.get(&1), Some(&1)); |
| 442 | /// assert_eq!(m.get(&2), Some(&2)); |
| 443 | /// |
| 444 | /// let (m, _) = m.update(1, (), |_, (), _| None); |
| 445 | /// assert_eq!(m.get(&0), Some(&1)); |
| 446 | /// assert_eq!(m.get(&1), None); |
| 447 | /// assert_eq!(m.get(&2), Some(&2)); |
| 448 | /// ``` |
| 449 | pub fn update<Q, D, F>(&self, q: Q, d: D, mut f: F) -> (Self, Option<V>) |
| 450 | where |
| 451 | Q: Ord, |
| 452 | K: Borrow<Q>, |
| 453 | F: FnMut(Q, D, Option<(&K, &V)>) -> Option<(K, V)>, |
| 454 | { |
| 455 | let (root, prev) = self.0.update(q, d, &mut f); |
| 456 | (Map(root), prev) |
| 457 | } |
| 458 | |
| 459 | /// Perform a copy on write update to the map. In the case that |
| 460 | /// self is a unique reference to the map, then the update will be |
| 461 | /// performed completly in place. self will be mutated, and no |
| 462 | /// previous version will be available. In the case that self has |
| 463 | /// a clone, or clones, then only the parts of the map that need |
| 464 | /// to be mutated will be copied before the update is |
| 465 | /// performed. self will reference the mutated copy, and previous |
| 466 | /// versions of the map will not be modified. self will still |
| 467 | /// share all the parts of the map that did not need to be mutated |
| 468 | /// with any pre existing clones. |
| 469 | /// |
| 470 | /// COW semantics are a flexible middle way between full |
| 471 | /// peristance and full mutability. Needless to say in the case |
| 472 | /// where you have a unique reference to the map, using update_cow |
| 473 | /// is a lot faster than using update, and a lot more flexible |
| 474 | /// than update_many. |
| 475 | /// |
| 476 | /// Other than copy on write the semanics of this method are |
| 477 | /// identical to those of update. |
| 478 | /// |
| 479 | /// #Examples |
| 480 | ///``` |
| 481 | /// use self::immutable_chunkmap::map::MapM; |
| 482 | /// |
| 483 | /// let mut m = MapM::new().update(0, 0, |k, d, _| Some((k, d))).0; |
| 484 | /// let orig = m.clone(); |
| 485 | /// m.update_cow(1, 1, |k, d, _| Some((k, d))); // copies the original chunk |
| 486 | /// m.update_cow(2, 2, |k, d, _| Some((k, d))); // doesn't copy anything |
| 487 | /// assert_eq!(m.len(), 3); |
| 488 | /// assert_eq!(orig.len(), 1); |
| 489 | /// assert_eq!(m.get(&0), Some(&0)); |
| 490 | /// assert_eq!(m.get(&1), Some(&1)); |
| 491 | /// assert_eq!(m.get(&2), Some(&2)); |
| 492 | /// assert_eq!(orig.get(&0), Some(&0)); |
| 493 | /// assert_eq!(orig.get(&1), None); |
| 494 | /// assert_eq!(orig.get(&2), None); |
| 495 | ///``` |
| 496 | pub fn update_cow<Q, D, F>(&mut self, q: Q, d: D, mut f: F) -> Option<V> |
| 497 | where |
| 498 | Q: Ord, |
| 499 | K: Borrow<Q>, |
| 500 | F: FnMut(Q, D, Option<(&K, &V)>) -> Option<(K, V)>, |
| 501 | { |
| 502 | self.0.update_cow(q, d, &mut f) |
| 503 | } |
| 504 | |
| 505 | /// Merge two maps together. Bindings that exist in both maps will |
| 506 | /// be passed to f, which may elect to remove the binding by |
| 507 | /// returning None. This function runs in O(log(n) + m) time and |
| 508 | /// space, where n is the size of the largest map, and m is the |
| 509 | /// number of intersecting chunks. It will never be slower than |
| 510 | /// calling update_many on the first map with an iterator over the |
| 511 | /// second, and will be significantly faster if the intersection |
| 512 | /// is minimal or empty. |
| 513 | /// |
| 514 | /// # Examples |
| 515 | /// ``` |
| 516 | /// use core::iter::FromIterator; |
| 517 | /// use self::immutable_chunkmap::map::MapM; |
| 518 | /// |
| 519 | /// let m0 = MapM::from_iter((0..10).map(|k| (k, 1))); |
| 520 | /// let m1 = MapM::from_iter((10..20).map(|k| (k, 1))); |
| 521 | /// let m2 = m0.union(&m1, |_k, _v0, _v1| panic!("no intersection expected" )); |
| 522 | /// |
| 523 | /// for i in 0..20 { |
| 524 | /// assert!(m2.get(&i).is_some()) |
| 525 | /// } |
| 526 | /// |
| 527 | /// let m3 = MapM::from_iter((5..9).map(|k| (k, 1))); |
| 528 | /// let m4 = m3.union(&m2, |_k, v0, v1| Some(v0 + v1)); |
| 529 | /// |
| 530 | /// for i in 0..20 { |
| 531 | /// assert!( |
| 532 | /// *m4.get(&i).unwrap() == |
| 533 | /// *m3.get(&i).unwrap_or(&0) + *m2.get(&i).unwrap_or(&0) |
| 534 | /// ) |
| 535 | /// } |
| 536 | /// ``` |
| 537 | pub fn union<F>(&self, other: &Map<K, V, SIZE>, mut f: F) -> Self |
| 538 | where |
| 539 | F: FnMut(&K, &V, &V) -> Option<V>, |
| 540 | { |
| 541 | Map(Tree::union(&self.0, &other.0, &mut f)) |
| 542 | } |
| 543 | |
| 544 | /// Produce a map containing the mapping over F of the |
| 545 | /// intersection (by key) of two maps. The function f runs on each |
| 546 | /// intersecting element, and has the option to omit elements from |
| 547 | /// the intersection by returning None, or change the value any |
| 548 | /// way it likes. Runs in O(log(N) + M) time and space where N is |
| 549 | /// the size of the smallest map, and M is the number of |
| 550 | /// intersecting chunks. |
| 551 | /// |
| 552 | /// # Examples |
| 553 | ///``` |
| 554 | /// use core::iter::FromIterator; |
| 555 | /// use self::immutable_chunkmap::map::MapM; |
| 556 | /// |
| 557 | /// let m0 = MapM::from_iter((0..100000).map(|k| (k, 1))); |
| 558 | /// let m1 = MapM::from_iter((50..30000).map(|k| (k, 1))); |
| 559 | /// let m2 = m0.intersect(&m1, |_k, v0, v1| Some(v0 + v1)); |
| 560 | /// |
| 561 | /// for i in 0..100000 { |
| 562 | /// if i >= 30000 || i < 50 { |
| 563 | /// assert!(m2.get(&i).is_none()); |
| 564 | /// } else { |
| 565 | /// assert!(*m2.get(&i).unwrap() == 2); |
| 566 | /// } |
| 567 | /// } |
| 568 | /// ``` |
| 569 | pub fn intersect<F>(&self, other: &Map<K, V, SIZE>, mut f: F) -> Self |
| 570 | where |
| 571 | F: FnMut(&K, &V, &V) -> Option<V>, |
| 572 | { |
| 573 | Map(Tree::intersect(&self.0, &other.0, &mut f)) |
| 574 | } |
| 575 | |
| 576 | /// Produce a map containing the second map subtracted from the |
| 577 | /// first. The function F is called for each intersecting element, |
| 578 | /// and ultimately decides whether it appears in the result, for |
| 579 | /// example, to compute a classical set diff, the function should |
| 580 | /// always return None. |
| 581 | /// |
| 582 | /// # Examples |
| 583 | ///``` |
| 584 | /// use core::iter::FromIterator; |
| 585 | /// use self::immutable_chunkmap::map::MapM; |
| 586 | /// |
| 587 | /// let m0 = MapM::from_iter((0..10000).map(|k| (k, 1))); |
| 588 | /// let m1 = MapM::from_iter((50..3000).map(|k| (k, 1))); |
| 589 | /// let m2 = m0.diff(&m1, |_k, _v0, _v1| None); |
| 590 | /// |
| 591 | /// m2.invariant(); |
| 592 | /// dbg!(m2.len()); |
| 593 | /// assert!(m2.len() == 10000 - 2950); |
| 594 | /// for i in 0..10000 { |
| 595 | /// if i >= 3000 || i < 50 { |
| 596 | /// assert!(*m2.get(&i).unwrap() == 1); |
| 597 | /// } else { |
| 598 | /// assert!(m2.get(&i).is_none()); |
| 599 | /// } |
| 600 | /// } |
| 601 | /// ``` |
| 602 | pub fn diff<F>(&self, other: &Map<K, V, SIZE>, mut f: F) -> Self |
| 603 | where |
| 604 | F: FnMut(&K, &V, &V) -> Option<V>, |
| 605 | K: Debug, |
| 606 | V: Debug, |
| 607 | { |
| 608 | Map(Tree::diff(&self.0, &other.0, &mut f)) |
| 609 | } |
| 610 | |
| 611 | /// lookup the mapping for k. If it doesn't exist return |
| 612 | /// None. Runs in log(N) time and constant space. where N |
| 613 | /// is the size of the map. |
| 614 | pub fn get<'a, Q: ?Sized + Ord>(&'a self, k: &Q) -> Option<&'a V> |
| 615 | where |
| 616 | K: Borrow<Q>, |
| 617 | { |
| 618 | self.0.get(k) |
| 619 | } |
| 620 | |
| 621 | /// lookup the mapping for k. Return the key. If it doesn't exist |
| 622 | /// return None. Runs in log(N) time and constant space. where N |
| 623 | /// is the size of the map. |
| 624 | pub fn get_key<'a, Q: ?Sized + Ord>(&'a self, k: &Q) -> Option<&'a K> |
| 625 | where |
| 626 | K: Borrow<Q>, |
| 627 | { |
| 628 | self.0.get_key(k) |
| 629 | } |
| 630 | |
| 631 | /// lookup the mapping for k. Return both the key and the |
| 632 | /// value. If it doesn't exist return None. Runs in log(N) time |
| 633 | /// and constant space. where N is the size of the map. |
| 634 | pub fn get_full<'a, Q: ?Sized + Ord>(&'a self, k: &Q) -> Option<(&'a K, &'a V)> |
| 635 | where |
| 636 | K: Borrow<Q>, |
| 637 | { |
| 638 | self.0.get_full(k) |
| 639 | } |
| 640 | |
| 641 | /// Get a mutable reference to the value mapped to `k` using copy on write semantics. |
| 642 | /// This works as `Arc::make_mut`, it will only clone the parts of the tree that are, |
| 643 | /// - required to reach `k` |
| 644 | /// - have a strong count > 1 |
| 645 | /// |
| 646 | /// This operation is also triggered by mut indexing on the map, e.g. `&mut m[k]` |
| 647 | /// calls `get_mut_cow` on `m` |
| 648 | /// |
| 649 | /// # Example |
| 650 | /// ``` |
| 651 | /// use core::iter::FromIterator; |
| 652 | /// use self::immutable_chunkmap::map::MapM as Map; |
| 653 | /// |
| 654 | /// let mut m = Map::from_iter((0..100).map(|k| (k, Map::from_iter((0..100).map(|k| (k, 1)))))); |
| 655 | /// let orig = m.clone(); |
| 656 | /// |
| 657 | /// if let Some(inner) = m.get_mut_cow(&0) { |
| 658 | /// if let Some(v) = inner.get_mut_cow(&0) { |
| 659 | /// *v += 1 |
| 660 | /// } |
| 661 | /// } |
| 662 | /// |
| 663 | /// assert_eq!(m.get(&0).and_then(|m| m.get(&0)), Some(&2)); |
| 664 | /// assert_eq!(orig.get(&0).and_then(|m| m.get(&0)), Some(&1)); |
| 665 | /// ``` |
| 666 | pub fn get_mut_cow<'a, Q: ?Sized + Ord>(&'a mut self, k: &Q) -> Option<&'a mut V> |
| 667 | where |
| 668 | K: Borrow<Q>, |
| 669 | { |
| 670 | self.0.get_mut_cow(k) |
| 671 | } |
| 672 | |
| 673 | /// Same as `get_mut_cow` except if the value is not in the map it will |
| 674 | /// first be inserted by calling `f` |
| 675 | pub fn get_or_insert_cow<'a, F>(&'a mut self, k: K, f: F) -> &'a mut V |
| 676 | where |
| 677 | F: FnOnce() -> V, |
| 678 | { |
| 679 | self.0.get_or_insert_cow(k, f) |
| 680 | } |
| 681 | |
| 682 | /// return a new map with the mapping under k removed. If |
| 683 | /// the binding existed in the old map return it. Runs in |
| 684 | /// log(N) time and log(N) space, where N is the size of |
| 685 | /// the map. |
| 686 | pub fn remove<Q: Sized + Ord>(&self, k: &Q) -> (Self, Option<V>) |
| 687 | where |
| 688 | K: Borrow<Q>, |
| 689 | { |
| 690 | let (t, prev) = self.0.remove(k); |
| 691 | (Map(t), prev) |
| 692 | } |
| 693 | |
| 694 | /// remove in place using copy on write semantics if self is not a |
| 695 | /// unique reference to the map. see `update_cow`. |
| 696 | pub fn remove_cow<Q: Sized + Ord>(&mut self, k: &Q) -> Option<V> |
| 697 | where |
| 698 | K: Borrow<Q>, |
| 699 | { |
| 700 | self.0.remove_cow(k) |
| 701 | } |
| 702 | |
| 703 | /// get the number of elements in the map O(1) time and space |
| 704 | pub fn len(&self) -> usize { |
| 705 | self.0.len() |
| 706 | } |
| 707 | |
| 708 | /// return an iterator over the subset of elements in the |
| 709 | /// map that are within the specified range. |
| 710 | /// |
| 711 | /// The returned iterator runs in O(log(N) + M) time, and |
| 712 | /// constant space. N is the number of elements in the |
| 713 | /// tree, and M is the number of elements you examine. |
| 714 | /// |
| 715 | /// if lbound >= ubound the returned iterator will be empty |
| 716 | pub fn range<'a, Q, R>(&'a self, r: R) -> Iter<'a, R, Q, K, V, SIZE> |
| 717 | where |
| 718 | Q: Ord + ?Sized + 'a, |
| 719 | K: Borrow<Q>, |
| 720 | R: RangeBounds<Q> + 'a, |
| 721 | { |
| 722 | self.0.range(r) |
| 723 | } |
| 724 | |
| 725 | /// return a mutable iterator over the subset of elements in the |
| 726 | /// map that are within the specified range. The iterator will |
| 727 | /// copy on write the part of the tree that it visits, |
| 728 | /// specifically it will be as if you ran get_mut_cow on every |
| 729 | /// element you visit. |
| 730 | /// |
| 731 | /// The returned iterator runs in O(log(N) + M) time, and |
| 732 | /// constant space. N is the number of elements in the |
| 733 | /// tree, and M is the number of elements you examine. |
| 734 | /// |
| 735 | /// if lbound >= ubound the returned iterator will be empty |
| 736 | pub fn range_mut_cow<'a, Q, R>(&'a mut self, r: R) -> IterMut<'a, R, Q, K, V, SIZE> |
| 737 | where |
| 738 | Q: Ord + ?Sized + 'a, |
| 739 | K: Borrow<Q>, |
| 740 | R: RangeBounds<Q> + 'a, |
| 741 | { |
| 742 | self.0.range_mut_cow(r) |
| 743 | } |
| 744 | |
| 745 | /// return a mutable iterator over the entire map. The iterator |
| 746 | /// will copy on write every element in the tree, specifically it |
| 747 | /// will be as if you ran get_mut_cow on every element. |
| 748 | /// |
| 749 | /// The returned iterator runs in O(log(N) + M) time, and |
| 750 | /// constant space. N is the number of elements in the |
| 751 | /// tree, and M is the number of elements you examine. |
| 752 | pub fn iter_mut_cow<'a>(&'a mut self) -> IterMut<'a, RangeFull, K, K, V, SIZE> { |
| 753 | self.0.iter_mut_cow() |
| 754 | } |
| 755 | } |
| 756 | |
| 757 | impl<K, V, const SIZE: usize> Map<K, V, SIZE> |
| 758 | where |
| 759 | K: Ord + Clone, |
| 760 | V: Clone + Default, |
| 761 | { |
| 762 | /// Same as `get_mut_cow` except if the value isn't in the map it will |
| 763 | /// be added by calling `V::default` |
| 764 | pub fn get_or_default_cow<'a>(&'a mut self, k: K) -> &'a mut V { |
| 765 | self.get_or_insert_cow(k, V::default) |
| 766 | } |
| 767 | } |
| 768 | |
| 769 | impl<K, V, const SIZE: usize> Map<K, V, SIZE> |
| 770 | where |
| 771 | K: Ord + Clone + Debug, |
| 772 | V: Clone + Debug, |
| 773 | { |
| 774 | #[allow (dead_code)] |
| 775 | pub fn invariant(&self) -> () { |
| 776 | self.0.invariant() |
| 777 | } |
| 778 | } |
| 779 | |