Skip to content

Commit 9fce8c9

Browse files
committed
auto merge of #7652 : blake2-ppc/rust/dlist, r=huonw
This is a new doubly-linked list using owned nodes. In the forward direction, the list is linked with owned pointers, and the backwards direction is linked with &'static Node pointers. This intends to replace the previous extra::DList that was using managed nodes and also featured freestanding nodes. The new List does not give access to the nodes, but means to implement all relevant linked-list methods. The list supports pop_back, push_back, pop_front, push_front, front, back, iter, mut_iter, +more iterators, append, insert_ordered, and merge. * Add a trait Deque for double ended sequences. * Both List and Deque implement this trait. Rename Deque to ArrayDeque. *The text has been updated to summarize resolved items* ## RFC Topics ### Resolved * Should be in extra * Representation for the backlinks ### Container Method Names and Trait Names and Type Names * Location and name of trait `extra::collection::Deque`? * Name of the ring buffer `extra::deque::ArrayDeque` ? * Name of the doubly linked list `extra::dlist::List` ? For container methods I think we have two options: * Align with the existing methods on the vector. That would be `.push()`, `.pop()`, `.shift()`, `.unshift()`. * Use the API described in https://github.com/mozilla/rust/wiki/Containers Obviously that's the way List is written right now. Should we use `pop_front() -> Option<T>` or `pop_front() -> T` ? ### Benchmarks Some basic bench numbers for List vs. Vec, Deque and *old DList* This List implementation's performance is dominated by the allocation of Nodes required when pushing. Iterate (by-ref) collection of 128 elements test test_bench::bench_iter ... bench: 198 ns/iter (+/- 0) test test_bench::bench_iter_mut ... bench: 294 ns/iter (+/- 0) test test_bench::bench_iter_rev ... bench: 198 ns/iter (+/- 0) test test_bench::bench_iter_mut_rev ... bench: 198 ns/iter (+/- 3) test test_bench::bench_iter_vec ... bench: 101 ns/iter (+/- 0) test test_bench::bench_iter_deque ... bench: 581 ns/iter (+/- 0) test test_bench::bench_iter_dlist ... bench: 9262 ns/iter (+/- 273) Sequence of `.push(elt)`, `.pop()` or equivalent at the tail end test test_bench::bench_push_back_pop_back ... bench: 72 ns/iter (+/- 0) test test_bench::bench_push_back_pop_back_vec ... bench: 5 ns/iter (+/- 0) test test_bench::bench_push_back_pop_back_deque ... bench: 15 ns/iter (+/- 0) test test_bench::bench_push_back_pop_back_dlist ... bench: 234 ns/iter (+/- 0)
2 parents 278ed50 + 0f9b9a5 commit 9fce8c9

File tree

7 files changed

+1132
-1068
lines changed

7 files changed

+1132
-1068
lines changed

src/libextra/container.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Container traits for extra
12+
13+
use std::container::Mutable;
14+
15+
/// A double-ended sequence that allows querying, insertion and deletion at both ends.
16+
pub trait Deque<T> : Mutable {
17+
/// Provide a reference to the front element, or None if the sequence is empty
18+
fn front<'a>(&'a self) -> Option<&'a T>;
19+
20+
/// Provide a mutable reference to the front element, or None if the sequence is empty
21+
fn front_mut<'a>(&'a mut self) -> Option<&'a mut T>;
22+
23+
/// Provide a reference to the back element, or None if the sequence is empty
24+
fn back<'a>(&'a self) -> Option<&'a T>;
25+
26+
/// Provide a mutable reference to the back element, or None if the sequence is empty
27+
fn back_mut<'a>(&'a mut self) -> Option<&'a mut T>;
28+
29+
/// Insert an element first in the sequence
30+
fn push_front(&mut self, elt: T);
31+
32+
/// Insert an element last in the sequence
33+
fn push_back(&mut self, elt: T);
34+
35+
/// Remove the last element and return it, or None if the sequence is empty
36+
fn pop_back(&mut self) -> Option<T>;
37+
38+
/// Remove the first element and return it, or None if the sequence is empty
39+
fn pop_front(&mut self) -> Option<T>;
40+
}

0 commit comments

Comments
 (0)