Skip to content

Commit

Permalink
Optimize move_front
Browse files Browse the repository at this point in the history
  • Loading branch information
marmeladema committed Sep 23, 2022
1 parent c8d1560 commit 9e4a96e
Showing 1 changed file with 38 additions and 17 deletions.
55 changes: 38 additions & 17 deletions src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,37 +134,37 @@ impl<T> FixedSizeList<T> {

pub(crate) fn push_front(&mut self, data: T) -> Option<(usize, &mut T)> {
let idx = self.next()?;
self.nodes[idx] = Some(FixedSizeListNode {
prev: usize::MAX,
next: self.front,
data,
});
if let Some(front) = self.node_mut(self.front) {
front.prev = idx;
}
if self.node_ref(self.back).is_none() {
self.back = idx;
}
let node = self.nodes.get_mut(idx).unwrap().insert(FixedSizeListNode {
prev: usize::MAX,
next: self.front,
data,
});
self.front = idx;
Some((idx, &mut self.nodes[idx].as_mut().unwrap().data))
Some((idx, &mut node.data))
}

#[cfg(test)]
fn push_back(&mut self, data: T) -> Option<(usize, &mut T)> {
let idx = self.next()?;
self.nodes[idx] = Some(FixedSizeListNode {
prev: self.back,
next: usize::MAX,
data,
});
if let Some(back) = self.node_mut(self.back) {
back.next = idx;
}
if self.node_ref(self.front).is_none() {
self.front = idx;
}
let node = self.nodes.get_mut(idx).unwrap().insert(FixedSizeListNode {
prev: self.back,
next: usize::MAX,
data,
});
self.back = idx;
Some((idx, &mut self.nodes[idx].as_mut().unwrap().data))
Some((idx, &mut node.data))
}

#[inline]
Expand Down Expand Up @@ -306,11 +306,32 @@ impl<T> FixedSizeList<T> {
#[inline]
pub(crate) fn move_front(&mut self, idx: usize) -> Option<&mut T> {
// TODO: try to optimize this funtion as it is a fairly hot path
self.remove(idx).map(|data| {
let (new, data) = self.push_front(data).unwrap();
debug_assert_eq!(idx, new);
data
})
let node = self.nodes.get_mut(idx)?.take()?;
if let Some(prev) = self.node_mut(node.prev) {
prev.next = node.next;
} else {
self.front = node.next;
}
if let Some(next) = self.node_mut(node.next) {
next.prev = node.prev;
} else {
self.back = node.prev;
}

if let Some(front) = self.node_mut(self.front) {
front.prev = idx;
}
if self.node_ref(self.back).is_none() {
self.back = idx;
}

let node = self.nodes.get_mut(idx).unwrap().insert(FixedSizeListNode {
prev: usize::MAX,
next: self.front,
data: node.data,
});
self.front = idx;
Some(&mut node.data)
}
}

Expand Down

0 comments on commit 9e4a96e

Please sign in to comment.