1 //! Forest of sets. 2 3 use super::{Comparator, Forest, INNER_SIZE, Node, NodeData, NodePool, Path, SetValue}; 4 use crate::packed_option::PackedOption; 5 #[cfg(test)] 6 use alloc::string::String; 7 #[cfg(test)] 8 use core::fmt; 9 use core::marker::PhantomData; 10 use wasmtime_core::{alloc::PanicOnOom, error::OutOfMemory}; 11 12 /// Tag type defining forest types for a set. 13 struct SetTypes<K>(PhantomData<K>); 14 15 impl<K> Forest for SetTypes<K> 16 where 17 K: Copy, 18 { 19 type Key = K; 20 type Value = SetValue; 21 type LeafKeys = [K; 2 * INNER_SIZE - 1]; 22 type LeafValues = [SetValue; 2 * INNER_SIZE - 1]; 23 splat_key(key: Self::Key) -> Self::LeafKeys24 fn splat_key(key: Self::Key) -> Self::LeafKeys { 25 [key; 2 * INNER_SIZE - 1] 26 } 27 splat_value(value: Self::Value) -> Self::LeafValues28 fn splat_value(value: Self::Value) -> Self::LeafValues { 29 [value; 2 * INNER_SIZE - 1] 30 } 31 } 32 33 /// Memory pool for a forest of `Set` instances. 34 pub struct SetForest<K> 35 where 36 K: Copy, 37 { 38 nodes: NodePool<SetTypes<K>>, 39 } 40 41 impl<K> SetForest<K> 42 where 43 K: Copy, 44 { 45 /// Create a new empty forest. new() -> Self46 pub fn new() -> Self { 47 Self { 48 nodes: NodePool::new(), 49 } 50 } 51 52 /// Clear all sets in the forest. 53 /// 54 /// All `Set` instances belong to this forest are invalidated and should no longer be used. clear(&mut self)55 pub fn clear(&mut self) { 56 self.nodes.clear(); 57 } 58 } 59 60 /// B-tree representing an ordered set of `K`s using `C` for comparing elements. 61 /// 62 /// This is not a general-purpose replacement for `BTreeSet`. See the [module 63 /// documentation](index.html) for more information about design tradeoffs. 64 /// 65 /// Sets can be cloned, but that operation should only be used as part of cloning the whole forest 66 /// they belong to. *Cloning a set does not allocate new memory for the clone*. It creates an alias 67 /// of the same memory. 68 #[derive(Clone)] 69 pub struct Set<K> 70 where 71 K: Copy, 72 { 73 root: PackedOption<Node>, 74 unused: PhantomData<K>, 75 } 76 77 impl<K> Set<K> 78 where 79 K: Copy, 80 { 81 /// Make an empty set. new() -> Self82 pub fn new() -> Self { 83 Self { 84 root: None.into(), 85 unused: PhantomData, 86 } 87 } 88 89 /// Is this an empty set? is_empty(&self) -> bool90 pub fn is_empty(&self) -> bool { 91 self.root.is_none() 92 } 93 94 /// Does the set contain `key`?. contains<C: Comparator<K>>(&self, key: K, forest: &SetForest<K>, comp: &C) -> bool95 pub fn contains<C: Comparator<K>>(&self, key: K, forest: &SetForest<K>, comp: &C) -> bool { 96 self.root 97 .expand() 98 .and_then(|root| Path::default().find(key, root, &forest.nodes, comp)) 99 .is_some() 100 } 101 102 /// Try to insert `key` into the set. 103 /// 104 /// If the set did not contain `key`, insert it and return true. 105 /// 106 /// If `key` is already present, don't change the set and return false. insert<C: Comparator<K>>( &mut self, key: K, forest: &mut SetForest<K>, comp: &C, ) -> bool107 pub fn insert<C: Comparator<K>>( 108 &mut self, 109 key: K, 110 forest: &mut SetForest<K>, 111 comp: &C, 112 ) -> bool { 113 self.cursor(forest, comp).insert(key) 114 } 115 116 /// Like `insert` but returns an error on allocation failure. try_insert<C: Comparator<K>>( &mut self, key: K, forest: &mut SetForest<K>, comp: &C, ) -> Result<bool, OutOfMemory>117 pub fn try_insert<C: Comparator<K>>( 118 &mut self, 119 key: K, 120 forest: &mut SetForest<K>, 121 comp: &C, 122 ) -> Result<bool, OutOfMemory> { 123 self.cursor(forest, comp).try_insert(key) 124 } 125 126 /// Remove `key` from the set and return true. 127 /// 128 /// If `key` was not present in the set, return false. remove<C: Comparator<K>>( &mut self, key: K, forest: &mut SetForest<K>, comp: &C, ) -> bool129 pub fn remove<C: Comparator<K>>( 130 &mut self, 131 key: K, 132 forest: &mut SetForest<K>, 133 comp: &C, 134 ) -> bool { 135 let mut c = self.cursor(forest, comp); 136 if c.goto(key) { 137 c.remove(); 138 true 139 } else { 140 false 141 } 142 } 143 144 /// Remove all entries. clear(&mut self, forest: &mut SetForest<K>)145 pub fn clear(&mut self, forest: &mut SetForest<K>) { 146 if let Some(root) = self.root.take() { 147 forest.nodes.free_tree(root); 148 } 149 } 150 151 /// Retains only the elements specified by the predicate. 152 /// 153 /// Remove all elements where the predicate returns false. retain<F>(&mut self, forest: &mut SetForest<K>, mut predicate: F) where F: FnMut(K) -> bool,154 pub fn retain<F>(&mut self, forest: &mut SetForest<K>, mut predicate: F) 155 where 156 F: FnMut(K) -> bool, 157 { 158 let mut path = Path::default(); 159 if let Some(root) = self.root.expand() { 160 path.first(root, &forest.nodes); 161 } 162 while let Some((node, entry)) = path.leaf_pos() { 163 if predicate(forest.nodes[node].unwrap_leaf().0[entry]) { 164 path.next(&forest.nodes); 165 } else { 166 self.root = path.remove(&mut forest.nodes).into(); 167 } 168 } 169 } 170 171 /// Create a cursor for navigating this set. The cursor is initially positioned off the end of 172 /// the set. cursor<'a, C: Comparator<K>>( &'a mut self, forest: &'a mut SetForest<K>, comp: &'a C, ) -> SetCursor<'a, K, C>173 pub fn cursor<'a, C: Comparator<K>>( 174 &'a mut self, 175 forest: &'a mut SetForest<K>, 176 comp: &'a C, 177 ) -> SetCursor<'a, K, C> { 178 SetCursor::new(self, forest, comp) 179 } 180 181 /// Create an iterator traversing this set. The iterator type is `K`. iter<'a>(&'a self, forest: &'a SetForest<K>) -> SetIter<'a, K>182 pub fn iter<'a>(&'a self, forest: &'a SetForest<K>) -> SetIter<'a, K> { 183 SetIter { 184 root: self.root, 185 pool: &forest.nodes, 186 path: Path::default(), 187 } 188 } 189 } 190 191 impl<K> Default for Set<K> 192 where 193 K: Copy, 194 { default() -> Self195 fn default() -> Self { 196 Self::new() 197 } 198 } 199 200 /// A position in a `Set` used to navigate and modify the ordered set. 201 /// 202 /// A cursor always points at an element in the set, or "off the end" which is a position after the 203 /// last element in the set. 204 pub struct SetCursor<'a, K, C> 205 where 206 K: 'a + Copy, 207 C: 'a + Comparator<K>, 208 { 209 root: &'a mut PackedOption<Node>, 210 pool: &'a mut NodePool<SetTypes<K>>, 211 comp: &'a C, 212 path: Path<SetTypes<K>>, 213 } 214 215 impl<'a, K, C> SetCursor<'a, K, C> 216 where 217 K: Copy, 218 C: Comparator<K>, 219 { 220 /// Create a cursor with a default (invalid) location. new(container: &'a mut Set<K>, forest: &'a mut SetForest<K>, comp: &'a C) -> Self221 fn new(container: &'a mut Set<K>, forest: &'a mut SetForest<K>, comp: &'a C) -> Self { 222 Self { 223 root: &mut container.root, 224 pool: &mut forest.nodes, 225 comp, 226 path: Path::default(), 227 } 228 } 229 230 /// Is this cursor pointing to an empty set? is_empty(&self) -> bool231 pub fn is_empty(&self) -> bool { 232 self.root.is_none() 233 } 234 235 /// Move cursor to the next element and return it. 236 /// 237 /// If the cursor reaches the end, return `None` and leave the cursor at the off-the-end 238 /// position. next(&mut self) -> Option<K>239 pub fn next(&mut self) -> Option<K> { 240 self.path.next(self.pool).map(|(k, _)| k) 241 } 242 243 /// Move cursor to the previous element and return it. 244 /// 245 /// If the cursor is already pointing at the first element, leave it there and return `None`. prev(&mut self) -> Option<K>246 pub fn prev(&mut self) -> Option<K> { 247 self.root 248 .expand() 249 .and_then(|root| self.path.prev(root, self.pool).map(|(k, _)| k)) 250 } 251 252 /// Get the current element, or `None` if the cursor is at the end. elem(&self) -> Option<K>253 pub fn elem(&self) -> Option<K> { 254 self.path 255 .leaf_pos() 256 .and_then(|(node, entry)| self.pool[node].unwrap_leaf().0.get(entry).cloned()) 257 } 258 259 /// Move this cursor to `elem`. 260 /// 261 /// If `elem` is in the set, place the cursor at `elem` and return true. 262 /// 263 /// If `elem` is not in the set, place the cursor at the next larger element (or the end) and 264 /// return false. goto(&mut self, elem: K) -> bool265 pub fn goto(&mut self, elem: K) -> bool { 266 match self.root.expand() { 267 None => false, 268 Some(root) => { 269 if self.path.find(elem, root, self.pool, self.comp).is_some() { 270 true 271 } else { 272 self.path.normalize(self.pool); 273 false 274 } 275 } 276 } 277 } 278 279 /// Move this cursor to the first element. goto_first(&mut self) -> Option<K>280 pub fn goto_first(&mut self) -> Option<K> { 281 self.root.map(|root| self.path.first(root, self.pool).0) 282 } 283 284 /// Try to insert `elem` into the set and leave the cursor at the inserted element. 285 /// 286 /// If the set did not contain `elem`, insert it and return true. 287 /// 288 /// If `elem` is already present, don't change the set, place the cursor at `goto(elem)`, and 289 /// return false. insert(&mut self, elem: K) -> bool290 pub fn insert(&mut self, elem: K) -> bool { 291 self.try_insert(elem).panic_on_oom() 292 } 293 294 /// Like `insert` but returns an error on allocation failure. try_insert(&mut self, elem: K) -> Result<bool, OutOfMemory>295 pub fn try_insert(&mut self, elem: K) -> Result<bool, OutOfMemory> { 296 match self.root.expand() { 297 None => { 298 let root = self.pool.alloc_node(NodeData::leaf(elem, SetValue()))?; 299 *self.root = root.into(); 300 self.path.set_root_node(root); 301 Ok(true) 302 } 303 Some(root) => { 304 // TODO: Optimize the case where `self.path` is already at the correct insert pos. 305 if self.path.find(elem, root, self.pool, self.comp).is_none() { 306 *self.root = self.path.insert(elem, SetValue(), self.pool)?.into(); 307 Ok(true) 308 } else { 309 Ok(false) 310 } 311 } 312 } 313 } 314 315 /// Remove the current element (if any) and return it. 316 /// This advances the cursor to the next element after the removed one. remove(&mut self) -> Option<K>317 pub fn remove(&mut self) -> Option<K> { 318 let elem = self.elem(); 319 if elem.is_some() { 320 *self.root = self.path.remove(self.pool).into(); 321 } 322 elem 323 } 324 } 325 326 #[cfg(test)] 327 impl<'a, K, C> SetCursor<'a, K, C> 328 where 329 K: Copy + fmt::Display, 330 C: Comparator<K>, 331 { verify(&self)332 fn verify(&self) { 333 self.path.verify(self.pool); 334 self.root.map(|root| self.pool.verify_tree(root, self.comp)); 335 } 336 337 /// Get a text version of the path to the current position. tpath(&self) -> String338 fn tpath(&self) -> String { 339 use alloc::string::ToString; 340 self.path.to_string() 341 } 342 } 343 344 /// An iterator visiting the elements of a `Set`. 345 pub struct SetIter<'a, K> 346 where 347 K: 'a + Copy, 348 { 349 root: PackedOption<Node>, 350 pool: &'a NodePool<SetTypes<K>>, 351 path: Path<SetTypes<K>>, 352 } 353 354 impl<'a, K> Iterator for SetIter<'a, K> 355 where 356 K: 'a + Copy, 357 { 358 type Item = K; 359 next(&mut self) -> Option<Self::Item>360 fn next(&mut self) -> Option<Self::Item> { 361 // We use `self.root` to indicate if we need to go to the first element. Reset to `None` 362 // once we've returned the first element. This also works for an empty tree since the 363 // `path.next()` call returns `None` when the path is empty. This also fuses the iterator. 364 match self.root.take() { 365 Some(root) => Some(self.path.first(root, self.pool).0), 366 None => self.path.next(self.pool).map(|(k, _)| k), 367 } 368 } 369 } 370 371 #[cfg(test)] 372 mod tests { 373 use super::*; 374 use alloc::vec::Vec; 375 use core::mem; 376 377 #[test] node_size()378 fn node_size() { 379 // check that nodes are cache line sized when keys are 32 bits. 380 type F = SetTypes<u32>; 381 assert_eq!(mem::size_of::<NodeData<F>>(), 64); 382 } 383 384 #[test] empty()385 fn empty() { 386 let mut f = SetForest::<u32>::new(); 387 f.clear(); 388 389 let mut s = Set::<u32>::new(); 390 assert!(s.is_empty()); 391 s.clear(&mut f); 392 assert!(!s.contains(7, &f, &())); 393 394 // Iterator for an empty set. 395 assert_eq!(s.iter(&f).next(), None); 396 397 s.retain(&mut f, |_| unreachable!()); 398 399 let mut c = SetCursor::new(&mut s, &mut f, &()); 400 c.verify(); 401 assert_eq!(c.elem(), None); 402 403 assert_eq!(c.goto_first(), None); 404 assert_eq!(c.tpath(), "<empty path>"); 405 } 406 407 #[test] simple_cursor()408 fn simple_cursor() { 409 let mut f = SetForest::<u32>::new(); 410 let mut s = Set::<u32>::new(); 411 let mut c = SetCursor::new(&mut s, &mut f, &()); 412 413 assert!(c.insert(50)); 414 c.verify(); 415 assert_eq!(c.elem(), Some(50)); 416 417 assert!(c.insert(100)); 418 c.verify(); 419 assert_eq!(c.elem(), Some(100)); 420 421 assert!(c.insert(10)); 422 c.verify(); 423 assert_eq!(c.elem(), Some(10)); 424 425 // Basic movement. 426 assert_eq!(c.next(), Some(50)); 427 assert_eq!(c.next(), Some(100)); 428 assert_eq!(c.next(), None); 429 assert_eq!(c.next(), None); 430 assert_eq!(c.prev(), Some(100)); 431 assert_eq!(c.prev(), Some(50)); 432 assert_eq!(c.prev(), Some(10)); 433 assert_eq!(c.prev(), None); 434 assert_eq!(c.prev(), None); 435 436 assert!(c.goto(50)); 437 assert_eq!(c.elem(), Some(50)); 438 assert_eq!(c.remove(), Some(50)); 439 c.verify(); 440 441 assert_eq!(c.elem(), Some(100)); 442 assert_eq!(c.remove(), Some(100)); 443 c.verify(); 444 assert_eq!(c.elem(), None); 445 assert_eq!(c.remove(), None); 446 c.verify(); 447 } 448 449 #[test] two_level_sparse_tree()450 fn two_level_sparse_tree() { 451 let mut f = SetForest::<u32>::new(); 452 let mut s = Set::<u32>::new(); 453 let mut c = SetCursor::new(&mut s, &mut f, &()); 454 455 // Insert enough elements that we get a two-level tree. 456 // Each leaf node holds 8 elements 457 assert!(c.is_empty()); 458 for i in 0..50 { 459 assert!(c.insert(i)); 460 assert_eq!(c.elem(), Some(i)); 461 } 462 assert!(!c.is_empty()); 463 464 assert_eq!(c.goto_first(), Some(0)); 465 assert_eq!(c.tpath(), "node2[0]--node0[0]"); 466 467 assert_eq!(c.prev(), None); 468 for i in 1..50 { 469 assert_eq!(c.next(), Some(i)); 470 } 471 assert_eq!(c.next(), None); 472 for i in (0..50).rev() { 473 assert_eq!(c.prev(), Some(i)); 474 } 475 assert_eq!(c.prev(), None); 476 477 assert!(c.goto(25)); 478 for i in 25..50 { 479 assert_eq!(c.remove(), Some(i)); 480 assert!(!c.is_empty()); 481 c.verify(); 482 } 483 484 for i in (0..25).rev() { 485 assert!(!c.is_empty()); 486 assert_eq!(c.elem(), None); 487 assert_eq!(c.prev(), Some(i)); 488 assert_eq!(c.remove(), Some(i)); 489 c.verify(); 490 } 491 assert_eq!(c.elem(), None); 492 assert!(c.is_empty()); 493 } 494 495 #[test] three_level_sparse_tree()496 fn three_level_sparse_tree() { 497 let mut f = SetForest::<u32>::new(); 498 let mut s = Set::<u32>::new(); 499 let mut c = SetCursor::new(&mut s, &mut f, &()); 500 501 // Insert enough elements that we get a 3-level tree. 502 // Each leaf node holds 8 elements when filled up sequentially. 503 // Inner nodes hold 8 node pointers. 504 assert!(c.is_empty()); 505 for i in 0..150 { 506 assert!(c.insert(i)); 507 assert_eq!(c.elem(), Some(i)); 508 } 509 assert!(!c.is_empty()); 510 511 assert!(c.goto(0)); 512 assert_eq!(c.tpath(), "node11[0]--node2[0]--node0[0]"); 513 514 assert_eq!(c.prev(), None); 515 for i in 1..150 { 516 assert_eq!(c.next(), Some(i)); 517 } 518 assert_eq!(c.next(), None); 519 for i in (0..150).rev() { 520 assert_eq!(c.prev(), Some(i)); 521 } 522 assert_eq!(c.prev(), None); 523 524 assert!(c.goto(125)); 525 for i in 125..150 { 526 assert_eq!(c.remove(), Some(i)); 527 assert!(!c.is_empty()); 528 c.verify(); 529 } 530 531 for i in (0..125).rev() { 532 assert!(!c.is_empty()); 533 assert_eq!(c.elem(), None); 534 assert_eq!(c.prev(), Some(i)); 535 assert_eq!(c.remove(), Some(i)); 536 c.verify(); 537 } 538 assert_eq!(c.elem(), None); 539 assert!(c.is_empty()); 540 } 541 542 // Generate a densely populated 4-level tree. 543 // 544 // Level 1: 1 root 545 // Level 2: 8 inner 546 // Level 3: 64 inner 547 // Level 4: 512 leaves, up to 7680 elements 548 // 549 // A 3-level tree can hold at most 960 elements. dense4l(f: &mut SetForest<i32>) -> Set<i32>550 fn dense4l(f: &mut SetForest<i32>) -> Set<i32> { 551 f.clear(); 552 let mut s = Set::new(); 553 554 // Insert 400 elements in 7 passes over the range to avoid the half-full leaf node pattern 555 // that comes from sequential insertion. This will generate a normal leaf layer. 556 for n in 0..4000 { 557 assert!(s.insert((n * 7) % 4000, f, &())); 558 } 559 s 560 } 561 562 #[test] four_level()563 fn four_level() { 564 let mut f = SetForest::<i32>::new(); 565 let mut s = dense4l(&mut f); 566 567 assert_eq!( 568 s.iter(&f).collect::<Vec<_>>()[0..10], 569 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 570 ); 571 572 let mut c = s.cursor(&mut f, &()); 573 574 c.verify(); 575 576 // Peel off a whole sub-tree of the root by deleting from the front. 577 // The 900 element is near the front of the second sub-tree. 578 assert!(c.goto(900)); 579 assert_eq!(c.tpath(), "node48[1]--node47[0]--node26[0]--node20[4]"); 580 assert!(c.goto(0)); 581 for i in 0..900 { 582 assert!(!c.is_empty()); 583 assert_eq!(c.remove(), Some(i)); 584 } 585 c.verify(); 586 assert_eq!(c.elem(), Some(900)); 587 588 // Delete backwards from somewhere in the middle. 589 assert!(c.goto(3000)); 590 for i in (2000..3000).rev() { 591 assert_eq!(c.prev(), Some(i)); 592 assert_eq!(c.remove(), Some(i)); 593 assert_eq!(c.elem(), Some(3000)); 594 } 595 c.verify(); 596 597 // Remove everything in a scattered manner, triggering many collapsing patterns. 598 for i in 0..4000 { 599 if c.goto((i * 7) % 4000) { 600 c.remove(); 601 } 602 } 603 assert!(c.is_empty()); 604 } 605 606 #[test] four_level_clear()607 fn four_level_clear() { 608 let mut f = SetForest::<i32>::new(); 609 let mut s = dense4l(&mut f); 610 s.clear(&mut f); 611 } 612 } 613