提交 8a326767 编写于 作者: B blake2-ppc

deque: Move the shorter part when growing

The deque is split at the marker lo, or logical index 0. Move the
shortest part (split by lo) when growing. This way add_front is just as
fast as add_back, on average.
上级 75015c36
......@@ -108,7 +108,7 @@ pub fn pop_back(&mut self) -> T {
/// Prepend an element to the deque
pub fn add_front(&mut self, t: T) {
if self.nelts == self.elts.len() {
grow(self.nelts, self.lo, &mut self.elts);
grow(self.nelts, &mut self.lo, &mut self.elts);
}
if self.lo == 0u {
self.lo = self.elts.len() - 1u;
......@@ -120,7 +120,7 @@ pub fn add_front(&mut self, t: T) {
/// Append an element to the deque
pub fn add_back(&mut self, t: T) {
if self.nelts == self.elts.len() {
grow(self.nelts, self.lo, &mut self.elts);
grow(self.nelts, &mut self.lo, &mut self.elts);
}
let hi = self.raw_index(self.nelts);
self.elts[hi] = Some(t);
......@@ -230,19 +230,37 @@ pub struct DequeMutRevIterator<'self, T> {
/// Grow is only called on full elts, so nelts is also len(elts), unlike
/// elsewhere.
fn grow<T>(nelts: uint, lo: uint, elts: &mut ~[Option<T>]) {
fn grow<T>(nelts: uint, loptr: &mut uint, elts: &mut ~[Option<T>]) {
assert_eq!(nelts, elts.len());
let newlen = elts.capacity() * 2;
let lo = *loptr;
let newlen = nelts * 2;
elts.reserve(newlen);
/* fill with None */
for uint::range(elts.len(), elts.capacity()) |_| {
elts.push(None);
}
/* move the former wraparound to the new half */
/*
Move the shortest half into the newly reserved area.
lo ---->|
nelts ----------->|
[o o o|o o o o o]
A [. . .|o o o o o o o o|. . . . .]
B [o o o|. . . . . . . .|o o o o o]
*/
assert!(newlen - nelts/2 >= nelts);
if lo <= (nelts - lo) { // A
for uint::range(0, lo) |i| {
elts.swap(i, nelts + i);
}
} else { // B
for uint::range(lo, nelts) |i| {
elts.swap(i, newlen - nelts + i);
}
*loptr += newlen - nelts;
}
}
fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册