From 5f2bc72ffea3361cf98f5c0688335093f80f851e Mon Sep 17 00:00:00 2001 From: Ian McCormack Date: Thu, 9 Feb 2023 12:33:29 -0500 Subject: [PATCH 1/3] Eliminated memory leaks due to use of Rc in tests for fast_clear and fast_clear. --- src/linked_list.rs | 89 ++++++++++++++++----------- src/rbtree.rs | 119 +++++++++++++++++++++--------------- src/singly_linked_list.rs | 103 ++++++++++++++++++------------- src/xor_linked_list.rs | 124 +++++++++++++++++++++----------------- 4 files changed, 257 insertions(+), 178 deletions(-) diff --git a/src/linked_list.rs b/src/linked_list.rs index efcdb8a..f4e2f35 100644 --- a/src/linked_list.rs +++ b/src/linked_list.rs @@ -16,7 +16,6 @@ use core::sync::atomic::{AtomicPtr, Ordering}; use crate::link_ops::{self, DefaultLinkOps}; use crate::pointer_ops::PointerOps; use crate::singly_linked_list::SinglyLinkedListOps; -use crate::unchecked_option::UncheckedOptionExt; use crate::xor_linked_list::XorLinkedListOps; use crate::Adapter; @@ -1487,6 +1486,10 @@ where #[cfg(test)] mod tests { + use alloc::boxed::Box; + + use crate::UnsafeRef; + use super::{Link, LinkedList}; use std::fmt; use std::format; @@ -1505,17 +1508,23 @@ mod tests { } intrusive_adapter!(ObjAdapter1 = Rc: Obj { link1: Link }); intrusive_adapter!(ObjAdapter2 = Rc: Obj { link2: Link }); - fn make_obj(value: u32) -> Rc { - Rc::new(Obj { + intrusive_adapter!(UnsafeRefObjAdapter1 = UnsafeRef: Obj { link1: Link }); + + fn make_rc_obj(value: u32) -> Rc { + Rc::new(make_obj(value)) + } + + fn make_obj(value: u32) -> Obj { + Obj { link1: Link::new(), link2: Link::default(), value, - }) + } } #[test] fn test_link() { - let a = make_obj(1); + let a = make_rc_obj(1); assert!(!a.link1.is_linked()); assert!(!a.link2.is_linked()); @@ -1540,9 +1549,9 @@ mod tests { #[test] fn test_cursor() { - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); let mut l = LinkedList::new(ObjAdapter1::new()); let mut cur = l.cursor_mut(); @@ -1623,9 +1632,9 @@ mod tests { #[test] fn test_push_pop() { - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); let mut l = LinkedList::new(ObjAdapter1::new()); l.push_front(a); @@ -1652,10 +1661,10 @@ mod tests { let mut l2 = LinkedList::new(ObjAdapter1::new()); let mut l3 = LinkedList::new(ObjAdapter1::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l1.cursor_mut().insert_before(a); l1.cursor_mut().insert_before(b); l1.cursor_mut().insert_before(c); @@ -1740,10 +1749,10 @@ mod tests { #[test] fn test_iter() { let mut l = LinkedList::new(ObjAdapter1::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l.cursor_mut().insert_before(a.clone()); l.cursor_mut().insert_before(b.clone()); l.cursor_mut().insert_before(c.clone()); @@ -1814,10 +1823,10 @@ mod tests { fn test_multi_list() { let mut l1 = LinkedList::new(ObjAdapter1::new()); let mut l2 = LinkedList::new(ObjAdapter2::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l1.cursor_mut().insert_before(a.clone()); l1.cursor_mut().insert_before(b.clone()); l1.cursor_mut().insert_before(c.clone()); @@ -1831,29 +1840,39 @@ mod tests { } #[test] - fn test_force_unlink() { - let mut l = LinkedList::new(ObjAdapter1::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + fn test_fast_clear_force_unlink() { + let mut l = LinkedList::new(UnsafeRefObjAdapter1::new()); + let a = UnsafeRef::from_box(Box::new(make_obj(1))); + let b = UnsafeRef::from_box(Box::new(make_obj(2))); + let c = UnsafeRef::from_box(Box::new(make_obj(3))); l.cursor_mut().insert_before(a.clone()); l.cursor_mut().insert_before(b.clone()); l.cursor_mut().insert_before(c.clone()); l.fast_clear(); assert!(l.is_empty()); - assert!(a.link1.is_linked()); - assert!(b.link1.is_linked()); - assert!(c.link1.is_linked()); + unsafe { + assert!(a.link1.is_linked()); + assert!(b.link1.is_linked()); + assert!(c.link1.is_linked()); + a.link1.force_unlink(); b.link1.force_unlink(); c.link1.force_unlink(); + + assert!(l.is_empty()); + + assert!(!a.link1.is_linked()); + assert!(!b.link1.is_linked()); + assert!(!c.link1.is_linked()); + } + + unsafe { + UnsafeRef::into_box(a); + UnsafeRef::into_box(b); + UnsafeRef::into_box(c); } - assert!(l.is_empty()); - assert!(!a.link1.is_linked()); - assert!(!b.link1.is_linked()); - assert!(!c.link1.is_linked()); } #[test] diff --git a/src/rbtree.rs b/src/rbtree.rs index 87badec..28d7e7b 100644 --- a/src/rbtree.rs +++ b/src/rbtree.rs @@ -22,7 +22,6 @@ use crate::link_ops::{self, DefaultLinkOps}; use crate::linked_list::LinkedListOps; use crate::pointer_ops::PointerOps; use crate::singly_linked_list::SinglyLinkedListOps; -use crate::unchecked_option::UncheckedOptionExt; use crate::xor_linked_list::XorLinkedListOps; use crate::Adapter; use crate::KeyAdapter; @@ -2383,7 +2382,8 @@ where #[cfg(test)] mod tests { use super::{Entry, KeyAdapter, Link, PointerOps, RBTree}; - use crate::Bound::*; + use crate::{Bound::*, UnsafeRef}; + use alloc::boxed::Box; use rand::prelude::*; use rand_xorshift::XorShiftRng; use std::fmt; @@ -2401,27 +2401,42 @@ mod tests { write!(f, "{}", self.value) } } - intrusive_adapter!(ObjAdapter = Rc: Obj { link: Link }); - impl<'a> KeyAdapter<'a> for ObjAdapter { + intrusive_adapter!(RcObjAdapter = Rc: Obj { link: Link }); + + impl<'a> KeyAdapter<'a> for RcObjAdapter { type Key = i32; fn get_key(&self, value: &'a ::Value) -> i32 { value.value } } - fn make_obj(value: i32) -> Rc { - Rc::new(Obj { + + intrusive_adapter!(UnsafeRefObjAdapter = UnsafeRef: Obj { link: Link }); + + impl<'a> KeyAdapter<'a> for UnsafeRefObjAdapter { + type Key = i32; + fn get_key(&self, value: &'a ::Value) -> i32 { + value.value + } + } + + fn make_rc_obj(value: i32) -> Rc { + Rc::new(make_obj(value)) + } + + fn make_obj(value: i32) -> Obj { + Obj { link: Link::new(), value, - }) + } } #[test] fn test_link() { - let a = make_obj(1); + let a = make_rc_obj(1); assert!(!a.link.is_linked()); assert_eq!(format!("{:?}", a.link), "unlinked"); - let mut b = RBTree::::default(); + let mut b = RBTree::::default(); assert!(b.is_empty()); assert_eq!(b.insert(a.clone()).get().unwrap().value, 1); @@ -2447,10 +2462,10 @@ mod tests { #[test] fn test_cursor() { - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let mut t = RBTree::new(ObjAdapter::new()); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let mut t = RBTree::new(RcObjAdapter::new()); let mut cur = t.cursor_mut(); assert!(cur.is_null()); assert!(cur.get().is_none()); @@ -2488,9 +2503,9 @@ mod tests { } assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _); - let a2 = make_obj(1); - let b2 = make_obj(2); - let c2 = make_obj(3); + let a2 = make_rc_obj(1); + let b2 = make_rc_obj(2); + let c2 = make_rc_obj(3); assert_eq!( cur.replace_with(a2).unwrap().as_ref() as *const _, a.as_ref() as *const _ @@ -2518,9 +2533,9 @@ mod tests { #[cfg(not(miri))] #[test] fn test_insert_remove() { - let v = (0..100).map(make_obj).collect::>(); + let v = (0..100).map(make_rc_obj).collect::>(); assert!(v.iter().all(|x| !x.link.is_linked())); - let mut t = RBTree::new(ObjAdapter::new()); + let mut t = RBTree::new(RcObjAdapter::new()); assert!(t.is_empty()); let mut rng = XorShiftRng::seed_from_u64(0); @@ -2638,8 +2653,8 @@ mod tests { #[cfg(not(miri))] #[test] fn test_iter() { - let v = (0..10).map(|x| make_obj(x * 10)).collect::>(); - let mut t = RBTree::new(ObjAdapter::new()); + let v = (0..10).map(|x| make_rc_obj(x * 10)).collect::>(); + let mut t = RBTree::new(RcObjAdapter::new()); for x in v.iter() { t.insert(x.clone()); } @@ -2884,8 +2899,8 @@ mod tests { #[test] fn test_find() { - let v = (0..10).map(|x| make_obj(x * 10)).collect::>(); - let mut t = RBTree::new(ObjAdapter::new()); + let v = (0..10).map(|x| make_rc_obj(x * 10)).collect::>(); + let mut t = RBTree::new(RcObjAdapter::new()); for x in v.iter() { t.insert(x.clone()); } @@ -3012,40 +3027,50 @@ mod tests { } #[test] - fn test_fast_clear() { - let mut t = RBTree::new(ObjAdapter::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + fn test_fast_clear_force_unlink() { + let mut t = RBTree::new(UnsafeRefObjAdapter::new()); + let a = UnsafeRef::from_box(Box::new(make_obj(1))); + let b = UnsafeRef::from_box(Box::new(make_obj(2))); + let c = UnsafeRef::from_box(Box::new(make_obj(3))); t.insert(a.clone()); t.insert(b.clone()); t.insert(c.clone()); t.fast_clear(); assert!(t.is_empty()); - assert!(a.link.is_linked()); - assert!(b.link.is_linked()); - assert!(c.link.is_linked()); + unsafe { + assert!(a.link.is_linked()); + assert!(b.link.is_linked()); + assert!(c.link.is_linked()); + a.link.force_unlink(); b.link.force_unlink(); c.link.force_unlink(); + + assert!(t.is_empty()); + + assert!(!a.link.is_linked()); + assert!(!b.link.is_linked()); + assert!(!c.link.is_linked()); + } + + unsafe { + UnsafeRef::into_box(a); + UnsafeRef::into_box(b); + UnsafeRef::into_box(c); } - assert!(t.is_empty()); - assert!(!a.link.is_linked()); - assert!(!b.link.is_linked()); - assert!(!c.link.is_linked()); } #[test] fn test_entry() { - let mut t = RBTree::new(ObjAdapter::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); - let e = make_obj(5); - let f = make_obj(6); + let mut t = RBTree::new(RcObjAdapter::new()); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); + let e = make_rc_obj(5); + let f = make_rc_obj(6); t.entry(&3).or_insert(c); t.entry(&2).or_insert(b.clone()); t.entry(&1).or_insert(a); @@ -3089,8 +3114,8 @@ mod tests { link: Link, value: &'a T, } - intrusive_adapter!(ObjAdapter<'a, T> = &'a Obj<'a, T>: Obj<'a, T> {link: Link} where T: 'a); - impl<'a, 'b, T: 'a + 'b> KeyAdapter<'a> for ObjAdapter<'b, T> { + intrusive_adapter!(RcObjAdapter<'a, T> = &'a Obj<'a, T>: Obj<'a, T> {link: Link} where T: 'a); + impl<'a, 'b, T: 'a + 'b> KeyAdapter<'a> for RcObjAdapter<'b, T> { type Key = &'a T; fn get_key(&self, value: &'a Obj<'b, T>) -> &'a T { value.value @@ -3103,7 +3128,7 @@ mod tests { value: &v, }; let b = a.clone(); - let mut l = RBTree::new(ObjAdapter::new()); + let mut l = RBTree::new(RcObjAdapter::new()); l.insert(&a); l.insert(&b); assert_eq!(*l.front().get().unwrap().value, 5); @@ -3119,8 +3144,8 @@ mod tests { link: Link, value: usize, } - intrusive_adapter!(ObjAdapter = $ptr: Obj { link: Link }); - impl<'a> KeyAdapter<'a> for ObjAdapter { + intrusive_adapter!(RcObjAdapter = $ptr: Obj { link: Link }); + impl<'a> KeyAdapter<'a> for RcObjAdapter { type Key = usize; fn get_key(&self, value: &'a Obj) -> usize { value.value @@ -3131,7 +3156,7 @@ mod tests { link: Link::new(), value: 5, }); - let mut l = RBTree::new(ObjAdapter::new()); + let mut l = RBTree::new(RcObjAdapter::new()); l.insert(a.clone()); assert_eq!(2, $ptr::strong_count(&a)); diff --git a/src/singly_linked_list.rs b/src/singly_linked_list.rs index fb0618e..bc89e7e 100644 --- a/src/singly_linked_list.rs +++ b/src/singly_linked_list.rs @@ -1190,6 +1190,10 @@ where #[cfg(test)] mod tests { + use alloc::boxed::Box; + + use crate::UnsafeRef; + use super::{Link, SinglyLinkedList}; use std::fmt; use std::format; @@ -1206,23 +1210,28 @@ mod tests { write!(f, "{}", self.value) } } - intrusive_adapter!(ObjAdapter1 = Rc: Obj { link1: Link }); - intrusive_adapter!(ObjAdapter2 = Rc: Obj { link2: Link }); - fn make_obj(value: u32) -> Rc { - Rc::new(Obj { + intrusive_adapter!(RcObjAdapter1 = Rc: Obj { link1: Link }); + intrusive_adapter!(RcObjAdapter2 = Rc: Obj { link2: Link }); + intrusive_adapter!(UnsafeRefObjAdapter1 = UnsafeRef: Obj { link1: Link }); + + fn make_rc_obj(value: u32) -> Rc { + Rc::new(make_obj(value)) + } + fn make_obj(value: u32) -> Obj { + Obj { link1: Link::new(), link2: Link::default(), value, - }) + } } #[test] fn test_link() { - let a = make_obj(1); + let a = make_rc_obj(1); assert!(!a.link1.is_linked()); assert!(!a.link2.is_linked()); - let mut b = SinglyLinkedList::::default(); + let mut b = SinglyLinkedList::::default(); assert!(b.is_empty()); b.push_front(a.clone()); @@ -1243,11 +1252,11 @@ mod tests { #[test] fn test_cursor() { - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); - let mut l = SinglyLinkedList::new(ObjAdapter1::new()); + let mut l = SinglyLinkedList::new(RcObjAdapter1::new()); let mut cur = l.cursor_mut(); assert!(cur.is_null()); assert!(cur.get().is_none()); @@ -1324,14 +1333,14 @@ mod tests { #[test] fn test_split_splice() { - let mut l1 = SinglyLinkedList::new(ObjAdapter1::new()); - let mut l2 = SinglyLinkedList::new(ObjAdapter1::new()); - let mut l3 = SinglyLinkedList::new(ObjAdapter1::new()); - - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let mut l1 = SinglyLinkedList::new(RcObjAdapter1::new()); + let mut l2 = SinglyLinkedList::new(RcObjAdapter1::new()); + let mut l3 = SinglyLinkedList::new(RcObjAdapter1::new()); + + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l1.cursor_mut().insert_after(d); l1.cursor_mut().insert_after(c); l1.cursor_mut().insert_after(b); @@ -1417,11 +1426,11 @@ mod tests { #[test] fn test_iter() { - let mut l = SinglyLinkedList::new(ObjAdapter1::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let mut l = SinglyLinkedList::new(RcObjAdapter1::new()); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l.cursor_mut().insert_after(d.clone()); l.cursor_mut().insert_after(c.clone()); l.cursor_mut().insert_after(b.clone()); @@ -1471,12 +1480,12 @@ mod tests { #[test] fn test_multi_list() { - let mut l1 = SinglyLinkedList::new(ObjAdapter1::new()); - let mut l2 = SinglyLinkedList::new(ObjAdapter2::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let mut l1 = SinglyLinkedList::new(RcObjAdapter1::new()); + let mut l2 = SinglyLinkedList::new(RcObjAdapter2::new()); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l1.cursor_mut().insert_after(d.clone()); l1.cursor_mut().insert_after(c.clone()); l1.cursor_mut().insert_after(b.clone()); @@ -1490,29 +1499,39 @@ mod tests { } #[test] - fn test_fast_clear() { - let mut l = SinglyLinkedList::new(ObjAdapter1::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + fn test_fast_clear_force_unlink() { + let mut l = SinglyLinkedList::new(UnsafeRefObjAdapter1::new()); + let a = UnsafeRef::from_box(Box::new(make_obj(1))); + let b = UnsafeRef::from_box(Box::new(make_obj(2))); + let c = UnsafeRef::from_box(Box::new(make_obj(3))); l.cursor_mut().insert_after(a.clone()); l.cursor_mut().insert_after(b.clone()); l.cursor_mut().insert_after(c.clone()); l.fast_clear(); assert!(l.is_empty()); - assert!(a.link1.is_linked()); - assert!(b.link1.is_linked()); - assert!(c.link1.is_linked()); + unsafe { + assert!(a.link1.is_linked()); + assert!(b.link1.is_linked()); + assert!(c.link1.is_linked()); + a.link1.force_unlink(); b.link1.force_unlink(); c.link1.force_unlink(); + + assert!(l.is_empty()); + + assert!(!a.link1.is_linked()); + assert!(!b.link1.is_linked()); + assert!(!c.link1.is_linked()); + } + + unsafe { + UnsafeRef::into_box(a); + UnsafeRef::into_box(b); + UnsafeRef::into_box(c); } - assert!(l.is_empty()); - assert!(!a.link1.is_linked()); - assert!(!b.link1.is_linked()); - assert!(!c.link1.is_linked()); } #[test] diff --git a/src/xor_linked_list.rs b/src/xor_linked_list.rs index d5c2ca3..8c870a6 100644 --- a/src/xor_linked_list.rs +++ b/src/xor_linked_list.rs @@ -19,7 +19,6 @@ use core::sync::atomic::{AtomicUsize, Ordering}; use crate::link_ops::{self, DefaultLinkOps}; use crate::pointer_ops::PointerOps; use crate::singly_linked_list::SinglyLinkedListOps; -use crate::unchecked_option::UncheckedOptionExt; use crate::Adapter; // ============================================================================= @@ -1616,6 +1615,8 @@ where #[cfg(test)] mod tests { + use crate::UnsafeRef; + use super::{Link, XorLinkedList}; use core::cell::Cell; use core::ptr; @@ -1635,24 +1636,29 @@ mod tests { write!(f, "{}", self.value) } } - intrusive_adapter!(ObjAdapter1 = Rc: Obj { link1: Link }); - intrusive_adapter!(ObjAdapter2 = Rc: Obj { link2: Link }); + intrusive_adapter!(RcObjAdapter1 = Rc: Obj { link1: Link }); + intrusive_adapter!(RcObjAdapter2 = Rc: Obj { link2: Link }); + intrusive_adapter!(UnsafeRefObjAdapter1 = UnsafeRef: Obj { link1: Link }); + + fn make_rc_obj(value: u32) -> Rc { + Rc::new(make_obj(value)) + } - fn make_obj(value: u32) -> Rc { - Rc::new(Obj { + fn make_obj(value: u32) -> Obj { + Obj { link1: Link::new(), link2: Link::default(), value, - }) + } } #[test] fn test_link() { - let a = make_obj(1); + let a = make_rc_obj(1); assert!(!a.link1.is_linked()); assert!(!a.link2.is_linked()); - let mut b = XorLinkedList::::default(); + let mut b = XorLinkedList::::default(); assert!(b.is_empty()); b.cursor_mut().insert_after(a.clone()); @@ -1673,11 +1679,11 @@ mod tests { #[test] fn test_cursor() { - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); - let mut l = XorLinkedList::new(ObjAdapter1::new()); + let mut l = XorLinkedList::new(RcObjAdapter1::new()); let mut cur = l.cursor_mut(); assert!(cur.is_null()); assert!(cur.get().is_none()); @@ -1756,11 +1762,11 @@ mod tests { #[test] fn test_push_pop() { - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); - let mut l = XorLinkedList::new(ObjAdapter1::new()); + let mut l = XorLinkedList::new(RcObjAdapter1::new()); l.push_front(a); assert_eq!(l.iter().map(|x| x.value).collect::>(), [1]); l.push_front(b); @@ -1781,14 +1787,14 @@ mod tests { #[test] fn test_split_splice() { - let mut l1 = XorLinkedList::new(ObjAdapter1::new()); - let mut l2 = XorLinkedList::new(ObjAdapter1::new()); - let mut l3 = XorLinkedList::new(ObjAdapter1::new()); - - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let mut l1 = XorLinkedList::new(RcObjAdapter1::new()); + let mut l2 = XorLinkedList::new(RcObjAdapter1::new()); + let mut l3 = XorLinkedList::new(RcObjAdapter1::new()); + + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l1.cursor_mut().insert_before(a); l1.cursor_mut().insert_before(b); l1.cursor_mut().insert_before(c); @@ -1872,11 +1878,11 @@ mod tests { #[test] fn test_iter() { - let mut l = XorLinkedList::new(ObjAdapter1::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let mut l = XorLinkedList::new(RcObjAdapter1::new()); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l.cursor_mut().insert_before(a.clone()); l.cursor_mut().insert_before(b.clone()); l.cursor_mut().insert_before(c.clone()); @@ -1979,12 +1985,12 @@ mod tests { #[test] fn test_multi_list() { - let mut l1 = XorLinkedList::new(ObjAdapter1::new()); - let mut l2 = XorLinkedList::new(ObjAdapter2::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); - let d = make_obj(4); + let mut l1 = XorLinkedList::new(RcObjAdapter1::new()); + let mut l2 = XorLinkedList::new(RcObjAdapter2::new()); + let a = make_rc_obj(1); + let b = make_rc_obj(2); + let c = make_rc_obj(3); + let d = make_rc_obj(4); l1.cursor_mut().insert_before(a.clone()); l1.cursor_mut().insert_before(b.clone()); l1.cursor_mut().insert_before(c.clone()); @@ -1998,46 +2004,56 @@ mod tests { } #[test] - fn test_force_unlink() { - let mut l = XorLinkedList::new(ObjAdapter1::new()); - let a = make_obj(1); - let b = make_obj(2); - let c = make_obj(3); + fn test_fast_clear_force_unlink() { + let mut l = XorLinkedList::new(UnsafeRefObjAdapter1::new()); + let a = UnsafeRef::from_box(Box::new(make_obj(1))); + let b = UnsafeRef::from_box(Box::new(make_obj(2))); + let c = UnsafeRef::from_box(Box::new(make_obj(3))); l.cursor_mut().insert_before(a.clone()); l.cursor_mut().insert_before(b.clone()); l.cursor_mut().insert_before(c.clone()); l.fast_clear(); assert!(l.is_empty()); - assert!(a.link1.is_linked()); - assert!(b.link1.is_linked()); - assert!(c.link1.is_linked()); + unsafe { + assert!(a.link1.is_linked()); + assert!(b.link1.is_linked()); + assert!(c.link1.is_linked()); + a.link1.force_unlink(); b.link1.force_unlink(); c.link1.force_unlink(); + + assert!(l.is_empty()); + + assert!(!a.link1.is_linked()); + assert!(!b.link1.is_linked()); + assert!(!c.link1.is_linked()); + } + + unsafe { + UnsafeRef::into_box(a); + UnsafeRef::into_box(b); + UnsafeRef::into_box(c); } - assert!(l.is_empty()); - assert!(!a.link1.is_linked()); - assert!(!b.link1.is_linked()); - assert!(!c.link1.is_linked()); } #[test] fn test_reverse() { - let mut l = XorLinkedList::new(ObjAdapter1::new()); + let mut l = XorLinkedList::new(RcObjAdapter1::new()); - l.push_back(make_obj(1)); - l.push_back(make_obj(2)); - l.push_back(make_obj(3)); - l.push_back(make_obj(4)); + l.push_back(make_rc_obj(1)); + l.push_back(make_rc_obj(2)); + l.push_back(make_rc_obj(3)); + l.push_back(make_rc_obj(4)); assert_eq!(l.iter().map(|x| x.value).collect::>(), [1, 2, 3, 4]); l.reverse(); assert_eq!(l.iter().map(|x| x.value).collect::>(), [4, 3, 2, 1]); - l.push_back(make_obj(5)); - l.push_back(make_obj(6)); + l.push_back(make_rc_obj(5)); + l.push_back(make_rc_obj(6)); assert_eq!( l.iter().map(|x| x.value).collect::>(), [4, 3, 2, 1, 5, 6] From 51c2325d15407ea1df9d9228faf535d543cc8703 Mon Sep 17 00:00:00 2001 From: Ian McCormack Date: Sun, 12 Feb 2023 09:16:52 -0500 Subject: [PATCH 2/3] Added back crate::unchecked_option::UncheckedOptionExt for 1.56. --- src/linked_list.rs | 1 + src/rbtree.rs | 1 + src/xor_linked_list.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/linked_list.rs b/src/linked_list.rs index f4e2f35..0a5055f 100644 --- a/src/linked_list.rs +++ b/src/linked_list.rs @@ -17,6 +17,7 @@ use crate::link_ops::{self, DefaultLinkOps}; use crate::pointer_ops::PointerOps; use crate::singly_linked_list::SinglyLinkedListOps; use crate::xor_linked_list::XorLinkedListOps; +use crate::unchecked_option::UncheckedOptionExt; use crate::Adapter; // ============================================================================= diff --git a/src/rbtree.rs b/src/rbtree.rs index 28d7e7b..dc2465a 100644 --- a/src/rbtree.rs +++ b/src/rbtree.rs @@ -22,6 +22,7 @@ use crate::link_ops::{self, DefaultLinkOps}; use crate::linked_list::LinkedListOps; use crate::pointer_ops::PointerOps; use crate::singly_linked_list::SinglyLinkedListOps; +use crate::unchecked_option::UncheckedOptionExt; use crate::xor_linked_list::XorLinkedListOps; use crate::Adapter; use crate::KeyAdapter; diff --git a/src/xor_linked_list.rs b/src/xor_linked_list.rs index 8c870a6..4438b10 100644 --- a/src/xor_linked_list.rs +++ b/src/xor_linked_list.rs @@ -19,6 +19,7 @@ use core::sync::atomic::{AtomicUsize, Ordering}; use crate::link_ops::{self, DefaultLinkOps}; use crate::pointer_ops::PointerOps; use crate::singly_linked_list::SinglyLinkedListOps; +use crate::unchecked_option::UncheckedOptionExt; use crate::Adapter; // ============================================================================= From 5269cf0982625fde12b3457694fc5b95963316c4 Mon Sep 17 00:00:00 2001 From: Ian McCormack Date: Sun, 12 Feb 2023 09:48:00 -0500 Subject: [PATCH 3/3] Fixed format. --- src/linked_list.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linked_list.rs b/src/linked_list.rs index 0a5055f..1b5c3d3 100644 --- a/src/linked_list.rs +++ b/src/linked_list.rs @@ -16,8 +16,8 @@ use core::sync::atomic::{AtomicPtr, Ordering}; use crate::link_ops::{self, DefaultLinkOps}; use crate::pointer_ops::PointerOps; use crate::singly_linked_list::SinglyLinkedListOps; -use crate::xor_linked_list::XorLinkedListOps; use crate::unchecked_option::UncheckedOptionExt; +use crate::xor_linked_list::XorLinkedListOps; use crate::Adapter; // =============================================================================