Skip to content

Commit 0f94e76

Browse files
committed
---
yaml --- r: 31440 b: refs/heads/dist-snap c: de48b7d h: refs/heads/master v: v3
1 parent c8a6c75 commit 0f94e76

File tree

2 files changed

+51
-25
lines changed

2 files changed

+51
-25
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df
99
refs/heads/incoming: d9317a174e434d4c99fc1a37fd7dc0d2f5328d37
10-
refs/heads/dist-snap: 20c6f3c37a7ec90ed308ae564d78a38639ac8146
10+
refs/heads/dist-snap: de48b7d4c4bba0212080c9aeb63ac8a13bb04b06
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/dist-snap/src/libcore/dlist.rs

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,28 @@ enum dlist_node<T> = @{
1818
mut next: dlist_link<T>
1919
};
2020

21-
// Needs to be an @-box so nodes can back-reference it.
22-
enum dlist<T> = @{
23-
mut size: uint,
24-
mut hd: dlist_link<T>,
25-
mut tl: dlist_link<T>
26-
};
21+
class dlist_root<T> {
22+
let mut size: uint;
23+
let mut hd: dlist_link<T>;
24+
let mut tl: dlist_link<T>;
25+
new() {
26+
self.size = 0; self.hd = none; self.tl = none;
27+
}
28+
drop {
29+
/* FIXME (#????) This doesn't work during task failure - the box
30+
* annihilator might have killed some of our nodes already. This will
31+
* be safe to uncomment when the box annihilator is safer. As is,
32+
* this makes test_dlist_cyclic_link below crash the runtime.
33+
// Empty the list. Not doing this explicitly would leave cyclic links
34+
// around, not to be freed until cycle collection at task exit.
35+
while self.hd.is_some() {
36+
self.unlink(self.hd.get());
37+
}
38+
*/
39+
}
40+
}
41+
42+
type dlist<T> = @dlist_root<T>;
2743

2844
impl private_methods<T> for dlist_node<T> {
2945
pure fn assert_links() {
@@ -91,7 +107,7 @@ pure fn new_dlist_node<T>(+data: T) -> dlist_node<T> {
91107

92108
/// Creates a new, empty dlist.
93109
pure fn new_dlist<T>() -> dlist<T> {
94-
dlist(@{mut size: 0, mut hd: none, mut tl: none})
110+
@unchecked { dlist_root() }
95111
}
96112

97113
/// Creates a new dlist with a single element
@@ -118,7 +134,7 @@ fn concat<T>(lists: dlist<dlist<T>>) -> dlist<T> {
118134
result
119135
}
120136

121-
impl private_methods<T> for dlist<T> {
137+
impl private_methods<T> for dlist_root<T> {
122138
pure fn new_link(-data: T) -> dlist_link<T> {
123139
some(dlist_node(@{data: data, mut linked: true,
124140
mut prev: none, mut next: none}))
@@ -334,7 +350,7 @@ impl extensions<T> for dlist<T> {
334350
* to the other list's head. O(1).
335351
*/
336352
fn append(them: dlist<T>) {
337-
if box::ptr_eq(*self, *them) {
353+
if box::ptr_eq(self, them) {
338354
fail ~"Cannot append a dlist to itself!"
339355
}
340356
if them.len() > 0 {
@@ -351,7 +367,7 @@ impl extensions<T> for dlist<T> {
351367
* list's tail to this list's head. O(1).
352368
*/
353369
fn prepend(them: dlist<T>) {
354-
if box::ptr_eq(*self, *them) {
370+
if box::ptr_eq(self, them) {
355371
fail ~"Cannot prepend a dlist to itself!"
356372
}
357373
if them.len() > 0 {
@@ -366,15 +382,25 @@ impl extensions<T> for dlist<T> {
366382

367383
/// Reverse the list's elements in place. O(n).
368384
fn reverse() {
369-
let temp = new_dlist::<T>();
385+
do option::while_some(self.hd) |nobe| {
386+
let next_nobe = nobe.next;
387+
self.remove(nobe);
388+
self.make_mine(nobe);
389+
self.add_head(some(nobe));
390+
next_nobe
391+
}
392+
}
393+
394+
/**
395+
* Remove everything from the list. This is important because the cyclic
396+
* links won't otherwise be automatically refcounted-collected. O(n).
397+
*/
398+
fn clear() {
399+
// Cute as it would be to simply detach the list and proclaim "O(1)!",
400+
// the GC would still be a hidden O(n). Better to be honest about it.
370401
while !self.is_empty() {
371-
let nobe = self.pop_n().get();
372-
nobe.linked = true; // meh, kind of disorganised.
373-
temp.add_head(some(nobe));
402+
let _ = self.pop();
374403
}
375-
self.hd = temp.hd;
376-
self.tl = temp.tl;
377-
self.size = temp.size;
378404
}
379405

380406
/// Iterate over nodes.
@@ -847,15 +873,15 @@ mod tests {
847873
l.assert_consistent(); assert l.is_empty();
848874
}
849875
#[test] #[should_fail] #[ignore(cfg(windows))]
850-
fn test_asymmetric_link() {
876+
fn test_dlist_asymmetric_link() {
851877
let l = new_dlist::<int>();
852878
let _one = l.push_n(1);
853879
let two = l.push_n(2);
854880
two.prev = none;
855881
l.assert_consistent();
856882
}
857883
#[test] #[should_fail] #[ignore(cfg(windows))]
858-
fn test_cyclic_list() {
884+
fn test_dlist_cyclic_list() {
859885
let l = new_dlist::<int>();
860886
let one = l.push_n(1);
861887
let _two = l.push_n(2);
@@ -865,32 +891,32 @@ mod tests {
865891
l.assert_consistent();
866892
}
867893
#[test] #[should_fail] #[ignore(cfg(windows))]
868-
fn test_headless() {
894+
fn test_dlist_headless() {
869895
new_dlist::<int>().head();
870896
}
871897
#[test] #[should_fail] #[ignore(cfg(windows))]
872-
fn test_insert_already_present_before() {
898+
fn test_dlist_insert_already_present_before() {
873899
let l = new_dlist::<int>();
874900
let one = l.push_n(1);
875901
let two = l.push_n(2);
876902
l.insert_n_before(two, one);
877903
}
878904
#[test] #[should_fail] #[ignore(cfg(windows))]
879-
fn test_insert_already_present_after() {
905+
fn test_dlist_insert_already_present_after() {
880906
let l = new_dlist::<int>();
881907
let one = l.push_n(1);
882908
let two = l.push_n(2);
883909
l.insert_n_after(one, two);
884910
}
885911
#[test] #[should_fail] #[ignore(cfg(windows))]
886-
fn test_insert_before_orphan() {
912+
fn test_dlist_insert_before_orphan() {
887913
let l = new_dlist::<int>();
888914
let one = new_dlist_node(1);
889915
let two = new_dlist_node(2);
890916
l.insert_n_before(one, two);
891917
}
892918
#[test] #[should_fail] #[ignore(cfg(windows))]
893-
fn test_insert_after_orphan() {
919+
fn test_dlist_insert_after_orphan() {
894920
let l = new_dlist::<int>();
895921
let one = new_dlist_node(1);
896922
let two = new_dlist_node(2);

0 commit comments

Comments
 (0)