Skip to content

Commit

Permalink
doc(cordyceps): reorganize List methods
Browse files Browse the repository at this point in the history
this is a little nicer

Signed-off-by: Eliza Weisman <[email protected]>
  • Loading branch information
hawkw committed Jun 21, 2022
1 parent 2c0cbbb commit a3d6088
Showing 1 changed file with 70 additions and 70 deletions.
140 changes: 70 additions & 70 deletions cordyceps/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,38 +503,64 @@ impl<T: Linked<Links<T>> + ?Sized> List<T> {
);
}

/// Appends an item to the head of the list.
/// Removes an item from the tail of the list.
///
/// This operation should compute in *O*(*n*) time.
///
/// This takes a [`Handle`] that owns the appended `item`. While the element
/// is in the list, it is owned by the list, and will be dropped when the
/// list is dropped. If the element is removed or otherwise unlinked from
/// the list, ownership is assigned back to the [`Handle`].
/// This returns a [`Handle`] that owns the popped element. Dropping the
/// [`Handle`] will drop the element.
///
/// [`Handle`]: crate::Linked::Handle
pub fn push_front(&mut self, item: T::Handle) {
let ptr = T::into_ptr(item);
// tracing::trace!(?self, ?ptr, "push_front");
assert_ne!(self.head, Some(ptr));
pub fn pop_back(&mut self) -> Option<T::Handle> {
let tail = self.tail?;
self.len -= 1;

unsafe {
T::links(ptr).as_mut().set_next(self.head);
T::links(ptr).as_mut().set_prev(None);
// tracing::trace!(?links);
if let Some(head) = self.head {
T::links(head).as_mut().set_prev(Some(ptr));
// tracing::trace!(head.links = ?T::links(head).as_ref(), "set head prev ptr",);
let mut tail_links = T::links(tail);
// tracing::trace!(?self, tail.addr = ?tail, tail.links = ?tail_links, "pop_back");
self.tail = tail_links.as_ref().prev();
debug_assert_eq!(
tail_links.as_ref().next(),
None,
"the tail node must not have a next link"
);

if let Some(prev) = tail_links.as_mut().prev() {
T::links(prev).as_mut().set_next(None);
} else {
self.head = None;
}

tail_links.as_mut().unlink();
// tracing::trace!(?self, tail.links = ?tail_links, "pop_back: popped");
Some(T::from_ptr(tail))
}
}

self.head = Some(ptr);
/// Remove an item from the head of the list.
///
/// This operation should compute in *O*(*n*) time.
///
/// This returns a [`Handle`] that owns the popped element. Dropping the
/// [`Handle`] will drop the element.
///
/// [`Handle`]: crate::Linked::Handle
pub fn pop_front(&mut self) -> Option<T::Handle> {
let head = self.head?;
self.len -= 1;

if self.tail.is_none() {
self.tail = Some(ptr);
}
unsafe {
let mut head_links = T::links(head);
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;
}

self.len += 1;
// tracing::trace!(?self, "push_front: pushed");
head_links.as_mut().unlink();
Some(T::from_ptr(head))
}
}

/// Appends an item to the tail of the list.
Expand Down Expand Up @@ -566,30 +592,38 @@ impl<T: Linked<Links<T>> + ?Sized> List<T> {
self.len += 1;
}

/// Remove an item from the head of the list.
/// Appends an item to the head of the list.
///
/// This operation should compute in *O*(*n*) time.
///
/// This returns a [`Handle`] that owns the popped element. Dropping the
/// [`Handle`] will drop the element.
/// This takes a [`Handle`] that owns the appended `item`. While the element
/// is in the list, it is owned by the list, and will be dropped when the
/// list is dropped. If the element is removed or otherwise unlinked from
/// the list, ownership is assigned back to the [`Handle`].
///
/// [`Handle`]: crate::Linked::Handle
pub fn pop_front(&mut self) -> Option<T::Handle> {
let head = self.head?;
self.len -= 1;

pub fn push_front(&mut self, item: T::Handle) {
let ptr = T::into_ptr(item);
// tracing::trace!(?self, ?ptr, "push_front");
assert_ne!(self.head, Some(ptr));
unsafe {
let mut head_links = T::links(head);
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;
T::links(ptr).as_mut().set_next(self.head);
T::links(ptr).as_mut().set_prev(None);
// tracing::trace!(?links);
if let Some(head) = self.head {
T::links(head).as_mut().set_prev(Some(ptr));
// tracing::trace!(head.links = ?T::links(head).as_ref(), "set head prev ptr",);
}
}

head_links.as_mut().unlink();
Some(T::from_ptr(head))
self.head = Some(ptr);

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

self.len += 1;
// tracing::trace!(?self, "push_front: pushed");
}

/// Returns a reference to the first element in the list, or `None`
Expand Down Expand Up @@ -676,40 +710,6 @@ impl<T: Linked<Links<T>> + ?Sized> List<T> {
Some(pin)
}

/// Removes an item from the tail of the list.
///
/// This operation should compute in *O*(*n*) time.
///
/// This returns a [`Handle`] that owns the popped element. Dropping the
/// [`Handle`] will drop the element.
///
/// [`Handle`]: crate::Linked::Handle
pub fn pop_back(&mut self) -> Option<T::Handle> {
let tail = self.tail?;
self.len -= 1;

unsafe {
let mut tail_links = T::links(tail);
// tracing::trace!(?self, tail.addr = ?tail, tail.links = ?tail_links, "pop_back");
self.tail = tail_links.as_ref().prev();
debug_assert_eq!(
tail_links.as_ref().next(),
None,
"the tail node must not have a next link"
);

if let Some(prev) = tail_links.as_mut().prev() {
T::links(prev).as_mut().set_next(None);
} else {
self.head = None;
}

tail_links.as_mut().unlink();
// tracing::trace!(?self, tail.links = ?tail_links, "pop_back: popped");
Some(T::from_ptr(tail))
}
}

/// Remove an arbitrary node from the list.
///
/// This returns a [`Handle`] that owns the popped element. Dropping the
Expand Down

0 comments on commit a3d6088

Please sign in to comment.