Rust implementation of the CVM algorithm for counting distinct elements in a stream
0

Configure Feed

Select the types of activity you want to include in your feed.

Add treap BST and heap property tests, and stress tests (#16)

- test_bst_property: verifies in-order traversal yields sorted keys
- test_heap_property: verifies parent priority >= child priorities
- Adds helper functions for property verification

+192
+192
src/treap.rs
··· 271 271 use rand::SeedableRng; 272 272 use rand::rngs::StdRng; 273 273 274 + // Helper: collect keys via in-order traversal (should yield sorted order for valid BST) 275 + fn collect_inorder<T: Ord + Clone>(node: &Option<Box<Node<T>>>) -> Vec<T> { 276 + match node { 277 + None => vec![], 278 + Some(n) => { 279 + let mut result = collect_inorder(&n.left); 280 + result.push(n.key.clone()); 281 + result.extend(collect_inorder(&n.right)); 282 + result 283 + } 284 + } 285 + } 286 + 287 + // Helper: verify max-heap property (parent priority >= child priorities) 288 + fn verify_heap_property<T: Ord>(node: &Option<Box<Node<T>>>) -> bool { 289 + match node { 290 + None => true, 291 + Some(n) => { 292 + let left_ok = n.left.as_ref().is_none_or(|l| n.priority >= l.priority); 293 + let right_ok = n.right.as_ref().is_none_or(|r| n.priority >= r.priority); 294 + left_ok 295 + && right_ok 296 + && verify_heap_property(&n.left) 297 + && verify_heap_property(&n.right) 298 + } 299 + } 300 + } 301 + 274 302 #[test] 275 303 fn test_insert_and_contains() { 276 304 let mut treap = Treap::new(); ··· 351 379 assert_eq!(treap.len(), 2); 352 380 assert!(treap.insert(5, &mut rng)); // Re-insertion returns true 353 381 assert_eq!(treap.len(), 3); 382 + } 383 + 384 + #[test] 385 + fn test_bst_property() { 386 + let mut treap = Treap::new(); 387 + let mut rng = StdRng::seed_from_u64(123); 388 + 389 + // Insert elements in random order 390 + let elements = vec![50, 25, 75, 10, 30, 60, 90, 5, 15, 27, 35]; 391 + for elem in &elements { 392 + treap.insert(*elem, &mut rng); 393 + } 394 + 395 + // In-order traversal should yield sorted keys 396 + let inorder = collect_inorder(&treap.root); 397 + let mut sorted = elements.clone(); 398 + sorted.sort(); 399 + assert_eq!(inorder, sorted); 400 + 401 + // Test after some removals 402 + treap.remove(&25); 403 + treap.remove(&75); 404 + let inorder_after = collect_inorder(&treap.root); 405 + let expected: Vec<i32> = sorted.into_iter().filter(|&x| x != 25 && x != 75).collect(); 406 + assert_eq!(inorder_after, expected); 407 + } 408 + 409 + #[test] 410 + fn test_heap_property() { 411 + let mut treap = Treap::new(); 412 + let mut rng = StdRng::seed_from_u64(456); 413 + 414 + // Insert many elements 415 + for i in 0..100 { 416 + treap.insert(i, &mut rng); 417 + assert!( 418 + verify_heap_property(&treap.root), 419 + "Heap property violated after inserting {}", 420 + i 421 + ); 422 + } 423 + 424 + // Test after removals 425 + for i in (0..100).step_by(3) { 426 + treap.remove(&i); 427 + assert!( 428 + verify_heap_property(&treap.root), 429 + "Heap property violated after removing {}", 430 + i 431 + ); 432 + } 433 + 434 + // Test after retain 435 + treap.retain(|&x| x % 2 == 0); 436 + assert!( 437 + verify_heap_property(&treap.root), 438 + "Heap property violated after retain" 439 + ); 440 + } 441 + 442 + #[test] 443 + fn test_stress_insert_remove() { 444 + let mut treap = Treap::new(); 445 + let mut rng = StdRng::seed_from_u64(789); 446 + 447 + // Insert 1000 elements 448 + for i in 0..1000 { 449 + treap.insert(i, &mut rng); 450 + } 451 + assert_eq!(treap.len(), 1000); 452 + 453 + // Verify all elements present 454 + for i in 0..1000 { 455 + assert!(treap.contains(&i), "Element {} should be present", i); 456 + } 457 + 458 + // Remove every other element 459 + for i in (0..1000).step_by(2) { 460 + assert!(treap.remove(&i), "Should remove {}", i); 461 + } 462 + assert_eq!(treap.len(), 500); 463 + 464 + // Verify correct elements remain 465 + for i in 0..1000 { 466 + if i % 2 == 0 { 467 + assert!(!treap.contains(&i), "Element {} should be removed", i); 468 + } else { 469 + assert!(treap.contains(&i), "Element {} should remain", i); 470 + } 471 + } 472 + 473 + // Re-insert removed elements 474 + for i in (0..1000).step_by(2) { 475 + assert!(treap.insert(i, &mut rng), "Should insert {}", i); 476 + } 477 + assert_eq!(treap.len(), 1000); 478 + 479 + // Verify invariants 480 + let inorder = collect_inorder(&treap.root); 481 + let expected: Vec<i32> = (0..1000).collect(); 482 + assert_eq!(inorder, expected); 483 + assert!(verify_heap_property(&treap.root)); 484 + } 485 + 486 + #[test] 487 + fn test_empty_tree_operations() { 488 + let mut treap: Treap<i32> = Treap::new(); 489 + let mut rng = StdRng::seed_from_u64(999); 490 + 491 + // Operations on empty treap 492 + assert!(treap.is_empty()); 493 + assert_eq!(treap.len(), 0); 494 + assert!(!treap.contains(&42)); 495 + assert!(!treap.remove(&42)); 496 + 497 + // Retain on empty treap (should be no-op) 498 + treap.retain(|_| true); 499 + assert!(treap.is_empty()); 500 + 501 + // Clear on empty treap 502 + treap.clear(); 503 + assert!(treap.is_empty()); 504 + 505 + // Insert then clear 506 + treap.insert(1, &mut rng); 507 + treap.insert(2, &mut rng); 508 + assert_eq!(treap.len(), 2); 509 + treap.clear(); 510 + assert!(treap.is_empty()); 511 + assert!(!treap.contains(&1)); 512 + assert!(!treap.contains(&2)); 513 + } 514 + 515 + #[test] 516 + fn test_single_element() { 517 + let mut treap = Treap::new(); 518 + let mut rng = StdRng::seed_from_u64(111); 519 + 520 + // Single element operations 521 + treap.insert(42, &mut rng); 522 + assert_eq!(treap.len(), 1); 523 + assert!(treap.contains(&42)); 524 + assert!(!treap.contains(&0)); 525 + 526 + // Duplicate of single element 527 + assert!(!treap.insert(42, &mut rng)); 528 + assert_eq!(treap.len(), 1); 529 + 530 + // Remove single element 531 + assert!(treap.remove(&42)); 532 + assert!(treap.is_empty()); 533 + assert!(!treap.contains(&42)); 534 + 535 + // Re-insert 536 + treap.insert(42, &mut rng); 537 + assert_eq!(treap.len(), 1); 538 + 539 + // Retain that keeps the element 540 + treap.retain(|&x| x == 42); 541 + assert_eq!(treap.len(), 1); 542 + 543 + // Retain that removes the element 544 + treap.retain(|&x| x != 42); 545 + assert!(treap.is_empty()); 354 546 } 355 547 }