Skip to content

Commit

Permalink
Merge pull request #82 from icmccorm/master
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanieu committed Feb 12, 2023
2 parents 5b1d6a1 + 5269cf0 commit 2798465
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 175 deletions.
88 changes: 54 additions & 34 deletions src/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,10 @@ where

#[cfg(test)]
mod tests {
use alloc::boxed::Box;

use crate::UnsafeRef;

use super::{Link, LinkedList};
use std::fmt;
use std::format;
Expand All @@ -1505,17 +1509,23 @@ mod tests {
}
intrusive_adapter!(ObjAdapter1 = Rc<Obj>: Obj { link1: Link });
intrusive_adapter!(ObjAdapter2 = Rc<Obj>: Obj { link2: Link });
fn make_obj(value: u32) -> Rc<Obj> {
Rc::new(Obj {
intrusive_adapter!(UnsafeRefObjAdapter1 = UnsafeRef<Obj>: Obj { link1: Link });

fn make_rc_obj(value: u32) -> Rc<Obj> {
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());

Expand All @@ -1540,9 +1550,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();
Expand Down Expand Up @@ -1623,9 +1633,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);
Expand All @@ -1652,10 +1662,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);
Expand Down Expand Up @@ -1740,10 +1750,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());
Expand Down Expand Up @@ -1814,10 +1824,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());
Expand All @@ -1831,29 +1841,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]
Expand Down
118 changes: 72 additions & 46 deletions src/rbtree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2383,7 +2383,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;
Expand All @@ -2401,27 +2402,42 @@ mod tests {
write!(f, "{}", self.value)
}
}
intrusive_adapter!(ObjAdapter = Rc<Obj>: Obj { link: Link });
impl<'a> KeyAdapter<'a> for ObjAdapter {
intrusive_adapter!(RcObjAdapter = Rc<Obj>: Obj { link: Link });

impl<'a> KeyAdapter<'a> for RcObjAdapter {
type Key = i32;
fn get_key(&self, value: &'a <Self::PointerOps as PointerOps>::Value) -> i32 {
value.value
}
}
fn make_obj(value: i32) -> Rc<Obj> {
Rc::new(Obj {

intrusive_adapter!(UnsafeRefObjAdapter = UnsafeRef<Obj>: Obj { link: Link });

impl<'a> KeyAdapter<'a> for UnsafeRefObjAdapter {
type Key = i32;
fn get_key(&self, value: &'a <Self::PointerOps as PointerOps>::Value) -> i32 {
value.value
}
}

fn make_rc_obj(value: i32) -> Rc<Obj> {
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::<ObjAdapter>::default();
let mut b = RBTree::<RcObjAdapter>::default();
assert!(b.is_empty());

assert_eq!(b.insert(a.clone()).get().unwrap().value, 1);
Expand All @@ -2447,10 +2463,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());
Expand Down Expand Up @@ -2488,9 +2504,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 _
Expand Down Expand Up @@ -2518,9 +2534,9 @@ mod tests {
#[cfg(not(miri))]
#[test]
fn test_insert_remove() {
let v = (0..100).map(make_obj).collect::<Vec<_>>();
let v = (0..100).map(make_rc_obj).collect::<Vec<_>>();
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);

Expand Down Expand Up @@ -2638,8 +2654,8 @@ mod tests {
#[cfg(not(miri))]
#[test]
fn test_iter() {
let v = (0..10).map(|x| make_obj(x * 10)).collect::<Vec<_>>();
let mut t = RBTree::new(ObjAdapter::new());
let v = (0..10).map(|x| make_rc_obj(x * 10)).collect::<Vec<_>>();
let mut t = RBTree::new(RcObjAdapter::new());
for x in v.iter() {
t.insert(x.clone());
}
Expand Down Expand Up @@ -2884,8 +2900,8 @@ mod tests {

#[test]
fn test_find() {
let v = (0..10).map(|x| make_obj(x * 10)).collect::<Vec<_>>();
let mut t = RBTree::new(ObjAdapter::new());
let v = (0..10).map(|x| make_rc_obj(x * 10)).collect::<Vec<_>>();
let mut t = RBTree::new(RcObjAdapter::new());
for x in v.iter() {
t.insert(x.clone());
}
Expand Down Expand Up @@ -3012,40 +3028,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);
Expand Down Expand Up @@ -3089,8 +3115,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
Expand All @@ -3103,7 +3129,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);
Expand All @@ -3119,8 +3145,8 @@ mod tests {
link: Link,
value: usize,
}
intrusive_adapter!(ObjAdapter = $ptr<Obj>: Obj { link: Link });
impl<'a> KeyAdapter<'a> for ObjAdapter {
intrusive_adapter!(RcObjAdapter = $ptr<Obj>: Obj { link: Link });
impl<'a> KeyAdapter<'a> for RcObjAdapter {
type Key = usize;
fn get_key(&self, value: &'a Obj) -> usize {
value.value
Expand All @@ -3131,7 +3157,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));

Expand Down
Loading

0 comments on commit 2798465

Please sign in to comment.