Skip to content

Commit

Permalink
feat(cordyceps): added new push_back and pop_front methods to list
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyrannican committed Jun 5, 2022
1 parent 233d2c8 commit 3a98f21
Showing 1 changed file with 105 additions and 0 deletions.
105 changes: 105 additions & 0 deletions cordyceps/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,49 @@ impl<T: Linked<Links<T>> + ?Sized> List<T> {
// tracing::trace!(?self, "push_front: pushed");
}

/// Appends an item to the tail of the list
pub fn push_back(&mut self, item: T::Handle) {
let ptr = T::into_ptr(item);
// tracing::trace!(?self, ?ptr, "push_back");
assert_ne!(self.tail, Some(ptr));
unsafe {
T::links(ptr).as_mut().set_next(None);
T::links(ptr).as_mut().set_prev(self.tail);
// tracing::trace!(?links);
if let Some(tail) = self.tail {
T::links(tail).as_mut().set_next(Some(ptr));
// tracing::trace!(tail.links = ?T::links(tail).as_ref(), "set tail next ptr");
}
}

self.tail = Some(ptr);
if self.head.is_none() {
self.head = Some(ptr);
}

// tracing::trace!(?self, "push_back: pushed");
}

/// Remove an item from the head of the list
pub fn pop_front(&mut self) -> Option<T::Handle> {
let head = self.head?;

unsafe {
let mut head_links = T::links(head);
// tracing::trace!(?self, head.addr = ?head, head.links = ?head_links, "pop_front");
self.head = head_links.as_ref().next();
if let Some(next) = head_links.as_mut().next() {
T::links(next).as_mut().set_prev(None);
} else {
self.tail = None;
}

head_links.as_mut().unlink();
// tracing::trace!(?self, head.links = ?head.links, "pop_front: popped");
Some(T::from_ptr(head))
}
}

/// Removes an item from the tail of the list.
pub fn pop_back(&mut self) -> Option<T::Handle> {
let tail = self.tail?;
Expand Down Expand Up @@ -563,6 +606,68 @@ mod tests {
assert!(list.is_empty());
}

#[test]
fn pop_front() {
let _trace = trace_init();

let a = entry(5);
let b = entry(7);
let c = entry(9);
let mut list = List::<Entry>::new();

list.push_front(a.as_ref());
list.assert_valid();

list.push_front(b.as_ref());
list.assert_valid();

list.push_front(c.as_ref());
list.assert_valid();

let d = list.pop_front().unwrap();
assert_eq!(9, d.val);

let e = list.pop_front().unwrap();
assert_eq!(7, e.val);

let f = list.pop_front().unwrap();
assert_eq!(5, f.val);

assert!(list.is_empty());
assert!(list.pop_front().is_none());
list.assert_valid();
}

#[test]
fn push_back() {
let _trace = trace_init();

let a = entry(5);
let b = entry(7);
let c = entry(9);
let mut list = List::<Entry>::new();

list.push_back(a.as_ref());
list.assert_valid();

list.push_back(b.as_ref());
list.assert_valid();

list.push_back(c.as_ref());
list.assert_valid();

let d = list.pop_back().unwrap();
assert_eq!(9, d.val);

let e = list.pop_back().unwrap();
assert_eq!(7, e.val);

let f = list.pop_back().unwrap();
assert_eq!(5, f.val);

list.assert_valid();
}

#[test]
fn push_pop_push_pop() {
let _trace = trace_init();
Expand Down

0 comments on commit 3a98f21

Please sign in to comment.