1 // Copyright 2015 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.
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.
11 // This test exercises cases where cyclic structure is legal,
12 // including when the cycles go through data-structures such
13 // as `Vec` or `TypedArena`.
15 // The intent is to cover as many such cases as possible, ensuring
16 // that if the compiler did not complain circa Rust 1.x (1.2 as of
17 // this writing), then it will continue to not complain in the future.
19 // Note that while some of the tests are only exercising using the
20 // given collection as a "backing store" for a set of nodes that hold
21 // the actual cycle (and thus the cycle does not go through the
22 // collection itself in such cases), in general we *do* want to make
23 // sure to have at least one example exercising a cycle that goes
24 // through the collection, for every collection type that supports
27 // HIGH LEVEL DESCRIPTION OF THE TEST ARCHITECTURE
28 // -----------------------------------------------
30 // We pick a data structure and want to make a cyclic construction
31 // from it. Each test of interest is labelled starting with "Cycle N:
32 // { ... }" where N is the test number and the "..."`is filled in with
33 // a graphviz-style description of the graph structure that the
34 // author believes is being made. So "{ a -> b, b -> (c,d), (c,d) -> e }"
35 // describes a line connected to a diamond:
43 // (Note that the above directed graph is actually acyclic.)
45 // The different graph structures are often composed of different data
46 // types. Some may be built atop `Vec`, others atop `HashMap`, etc.
48 // For each graph structure, we actually *confirm* that a cycle exists
49 // (as a safe-guard against a test author accidentally leaving it out)
50 // by traversing each graph and "proving" that a cycle exists within it.
52 // To do this, while trying to keep the code uniform (despite working
53 // with different underlying collection and smart-pointer types), we
54 // have a standard traversal API:
56 // 1. every node in the graph carries a `mark` (a u32, init'ed to 0).
58 // 2. every node provides a method to visit its children
60 // 3. a traversal attmepts to visit the nodes of the graph and prove that
61 // it sees the same node twice. It does this by setting the mark of each
62 // node to a fresh non-zero value, and if it sees the current mark, it
63 // "knows" that it must have found a cycle, and stops attempting further
66 // 4. each traversal is controlled by a bit-string that tells it which child
67 // it visit when it can take different paths. As a simple example,
68 // in a binary tree, 0 could mean "left" (and 1, "right"), so that
69 // "00010" means "left, left, left, right, left". (In general it will
70 // read as many bits as it needs to choose one child.)
72 // The graphs in this test are all meant to be very small, and thus
73 // short bitstrings of less than 64 bits should always suffice.
75 // (An earlier version of this test infrastructure simply had any
76 // given traversal visit all children it encountered, in a
77 // depth-first manner; one problem with this approach is that an
78 // acyclic graph can still have sharing, which would then be treated
79 // as a repeat mark and reported as a detected cycle.)
81 // The travseral code is a little more complicated because it has been
82 // programmed in a somewhat defensive manner. For example it also has
83 // a max threshold for the number of nodes it will visit, to guard
84 // against scenarios where the nodes are not correctly setting their
85 // mark when asked. There are various other methods not discussed here
86 // that are for aiding debugging the test when it runs, such as the
87 // `name` method that all nodes provide.
91 // 1. allocates the nodes in the graph,
93 // 2. sets up the links in the graph,
95 // 3. clones the "ContextData"
97 // 4. chooses a new current mark value for this test
99 // 5. initiates a traversal, potentially from multiple starting points
100 // (aka "roots"), with a given control-string (potentially a
101 // different string for each root). if it does start from a
102 // distinct root, then such a test should also increment the
103 // current mark value, so that this traversal is considered
104 // distinct from the prior one on this graph structure.
106 // Note that most of the tests work with the default control string
109 // 6. assert that the context confirms that it actually saw a cycle (since a traversal
110 // might have terminated, e.g. on a tree structure that contained no cycles).
112 use std::cell::{Cell, RefCell};
113 use std::cmp::Ordering;
114 use std::collections::BinaryHeap;
115 use std::collections::HashMap;
116 use std::collections::LinkedList;
117 use std::collections::VecDeque;
118 use std::collections::btree_map::BTreeMap;
119 use std::collections::btree_set::BTreeSet;
120 use std::hash::{Hash, Hasher};
122 use std::sync::{Arc, RwLock, Mutex};
124 const PRINT: bool = false;
127 let c_orig = ContextData {
134 saw_prev_marked: false,
138 // SANITY CHECK FOR TEST SUITE (thus unnumbered)
139 // Not a cycle: { v[0] -> (v[1], v[2]), v[1] -> v[3], v[2] -> v[3] };
140 let v: Vec<S2> = vec![Named::new("s0"),
144 v[0].next.set((Some(&v[1]), Some(&v[2])));
145 v[1].next.set((Some(&v[3]), None));
146 v[2].next.set((Some(&v[3]), None));
147 v[3].next.set((None, None));
149 let mut c = c_orig.clone();
151 assert!(!c.saw_prev_marked);
152 v[0].descend_into_self(&mut c);
153 assert!(!c.saw_prev_marked); // <-- different from below, b/c acyclic above
155 if PRINT { println!(""); }
157 // Cycle 1: { v[0] -> v[1], v[1] -> v[0] };
158 // does not exercise `v` itself
159 let v: Vec<S> = vec![Named::new("s0"),
161 v[0].next.set(Some(&v[1]));
162 v[1].next.set(Some(&v[0]));
164 let mut c = c_orig.clone();
166 assert!(!c.saw_prev_marked);
167 v[0].descend_into_self(&mut c);
168 assert!(c.saw_prev_marked);
170 if PRINT { println!(""); }
172 // Cycle 2: { v[0] -> v, v[1] -> v }
173 let v: V = Named::new("v");
174 v.contents[0].set(Some(&v));
175 v.contents[1].set(Some(&v));
177 let mut c = c_orig.clone();
179 assert!(!c.saw_prev_marked);
180 v.descend_into_self(&mut c);
181 assert!(c.saw_prev_marked);
183 if PRINT { println!(""); }
185 // Cycle 3: { hk0 -> hv0, hv0 -> hk0, hk1 -> hv1, hv1 -> hk1 };
186 // does not exercise `h` itself
188 let mut h: HashMap<H,H> = HashMap::new();
189 h.insert(Named::new("hk0"), Named::new("hv0"));
190 h.insert(Named::new("hk1"), Named::new("hv1"));
191 for (key, val) in h.iter() {
192 val.next.set(Some(key));
193 key.next.set(Some(val));
196 let mut c = c_orig.clone();
198 for (key, _) in h.iter() {
200 c.saw_prev_marked = false;
201 key.descend_into_self(&mut c);
202 assert!(c.saw_prev_marked);
205 if PRINT { println!(""); }
207 // Cycle 4: { h -> (hmk0,hmv0,hmk1,hmv1), {hmk0,hmv0,hmk1,hmv1} -> h }
209 let mut h: HashMap<HM,HM> = HashMap::new();
210 h.insert(Named::new("hmk0"), Named::new("hmv0"));
211 h.insert(Named::new("hmk0"), Named::new("hmv0"));
212 for (key, val) in h.iter() {
213 val.contents.set(Some(&h));
214 key.contents.set(Some(&h));
217 let mut c = c_orig.clone();
220 for (key, _) in h.iter() {
222 c.saw_prev_marked = false;
223 key.descend_into_self(&mut c);
224 assert!(c.saw_prev_marked);
228 if PRINT { println!(""); }
230 // Cycle 5: { vd[0] -> vd[1], vd[1] -> vd[0] };
231 // does not exercise vd itself
232 let mut vd: VecDeque<S> = VecDeque::new();
233 vd.push_back(Named::new("d0"));
234 vd.push_back(Named::new("d1"));
235 vd[0].next.set(Some(&vd[1]));
236 vd[1].next.set(Some(&vd[0]));
238 let mut c = c_orig.clone();
240 assert!(!c.saw_prev_marked);
241 vd[0].descend_into_self(&mut c);
242 assert!(c.saw_prev_marked);
244 if PRINT { println!(""); }
246 // Cycle 6: { vd -> (vd0, vd1), {vd0, vd1} -> vd }
247 let mut vd: VecDeque<VD> = VecDeque::new();
248 vd.push_back(Named::new("vd0"));
249 vd.push_back(Named::new("vd1"));
250 vd[0].contents.set(Some(&vd));
251 vd[1].contents.set(Some(&vd));
253 let mut c = c_orig.clone();
255 assert!(!c.saw_prev_marked);
256 vd[0].descend_into_self(&mut c);
257 assert!(c.saw_prev_marked);
259 if PRINT { println!(""); }
261 // Cycle 7: { vm -> (vm0, vm1), {vm0, vm1} -> vm }
262 let mut vm: HashMap<usize, VM> = HashMap::new();
263 vm.insert(0, Named::new("vm0"));
264 vm.insert(1, Named::new("vm1"));
265 vm[&0].contents.set(Some(&vm));
266 vm[&1].contents.set(Some(&vm));
268 let mut c = c_orig.clone();
270 assert!(!c.saw_prev_marked);
271 vm[&0].descend_into_self(&mut c);
272 assert!(c.saw_prev_marked);
274 if PRINT { println!(""); }
276 // Cycle 8: { ll -> (ll0, ll1), {ll0, ll1} -> ll }
277 let mut ll: LinkedList<LL> = LinkedList::new();
278 ll.push_back(Named::new("ll0"));
279 ll.push_back(Named::new("ll1"));
281 e.contents.set(Some(&ll));
284 let mut c = c_orig.clone();
288 c.saw_prev_marked = false;
289 e.descend_into_self(&mut c);
290 assert!(c.saw_prev_marked);
294 if PRINT { println!(""); }
296 // Cycle 9: { bh -> (bh0, bh1), {bh0, bh1} -> bh }
297 let mut bh: BinaryHeap<BH> = BinaryHeap::new();
298 bh.push(Named::new("bh0"));
299 bh.push(Named::new("bh1"));
301 b.contents.set(Some(&bh));
304 let mut c = c_orig.clone();
308 c.saw_prev_marked = false;
309 b.descend_into_self(&mut c);
310 assert!(c.saw_prev_marked);
314 if PRINT { println!(""); }
316 // Cycle 10: { btm -> (btk0, btv1), {bt0, bt1} -> btm }
317 let mut btm: BTreeMap<BTM, BTM> = BTreeMap::new();
318 btm.insert(Named::new("btk0"), Named::new("btv0"));
319 btm.insert(Named::new("btk1"), Named::new("btv1"));
320 for (k, v) in btm.iter() {
321 k.contents.set(Some(&btm));
322 v.contents.set(Some(&btm));
325 let mut c = c_orig.clone();
329 c.saw_prev_marked = false;
330 k.descend_into_self(&mut c);
331 assert!(c.saw_prev_marked);
335 if PRINT { println!(""); }
337 // Cycle 10: { bts -> (bts0, bts1), {bts0, bts1} -> btm }
338 let mut bts: BTreeSet<BTS> = BTreeSet::new();
339 bts.insert(Named::new("bts0"));
340 bts.insert(Named::new("bts1"));
341 for v in bts.iter() {
342 v.contents.set(Some(&bts));
345 let mut c = c_orig.clone();
349 c.saw_prev_marked = false;
350 b.descend_into_self(&mut c);
351 assert!(c.saw_prev_marked);
355 if PRINT { println!(""); }
357 // Cycle 11: { rc0 -> (rc1, rc2), rc1 -> (), rc2 -> rc0 }
358 let (rc0, rc1, rc2): (RCRC, RCRC, RCRC);
359 rc0 = RCRC::new("rcrc0");
360 rc1 = RCRC::new("rcrc1");
361 rc2 = RCRC::new("rcrc2");
362 rc0.0.borrow_mut().children.0 = Some(&rc1);
363 rc0.0.borrow_mut().children.1 = Some(&rc2);
364 rc2.0.borrow_mut().children.0 = Some(&rc0);
366 let mut c = c_orig.clone();
367 c.control_bits = 0b1;
369 assert!(!c.saw_prev_marked);
370 rc0.descend_into_self(&mut c);
371 assert!(c.saw_prev_marked);
373 if PRINT { println!(""); }
375 // We want to take the previous Rc case and generalize it to Arc.
377 // We can use refcells if we're single-threaded (as this test is).
378 // If one were to generalize these constructions to a
379 // multi-threaded context, then it might seem like we could choose
380 // between either a RwLock or a Mutex to hold the owned arcs on
383 // Part of the point of this test is to actually confirm that the
384 // cycle exists by traversing it. We can do that just fine with an
385 // RwLock (since we can grab the child pointers in read-only
386 // mode), but we cannot lock a std::sync::Mutex to guard reading
387 // from each node via the same pattern, since once you hit the
388 // cycle, you'll be trying to acquring the same lock twice.
389 // (We deal with this by exiting the traversal early if try_lock fails.)
391 // Cycle 12: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, refcells
392 let (arc0, arc1, arc2): (ARCRC, ARCRC, ARCRC);
393 arc0 = ARCRC::new("arcrc0");
394 arc1 = ARCRC::new("arcrc1");
395 arc2 = ARCRC::new("arcrc2");
396 arc0.0.borrow_mut().children.0 = Some(&arc1);
397 arc0.0.borrow_mut().children.1 = Some(&arc2);
398 arc2.0.borrow_mut().children.0 = Some(&arc0);
400 let mut c = c_orig.clone();
401 c.control_bits = 0b1;
403 assert!(!c.saw_prev_marked);
404 arc0.descend_into_self(&mut c);
405 assert!(c.saw_prev_marked);
407 if PRINT { println!(""); }
409 // Cycle 13: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, rwlocks
410 let (arc0, arc1, arc2): (ARCRW, ARCRW, ARCRW);
411 arc0 = ARCRW::new("arcrw0");
412 arc1 = ARCRW::new("arcrw1");
413 arc2 = ARCRW::new("arcrw2");
414 arc0.0.write().unwrap().children.0 = Some(&arc1);
415 arc0.0.write().unwrap().children.1 = Some(&arc2);
416 arc2.0.write().unwrap().children.0 = Some(&arc0);
418 let mut c = c_orig.clone();
419 c.control_bits = 0b1;
421 assert!(!c.saw_prev_marked);
422 arc0.descend_into_self(&mut c);
423 assert!(c.saw_prev_marked);
425 if PRINT { println!(""); }
427 // Cycle 14: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, mutexs
428 let (arc0, arc1, arc2): (ARCM, ARCM, ARCM);
429 arc0 = ARCM::new("arcm0");
430 arc1 = ARCM::new("arcm1");
431 arc2 = ARCM::new("arcm2");
432 arc0.1.lock().unwrap().children.0 = Some(&arc1);
433 arc0.1.lock().unwrap().children.1 = Some(&arc2);
434 arc2.1.lock().unwrap().children.0 = Some(&arc0);
436 let mut c = c_orig.clone();
437 c.control_bits = 0b1;
439 assert!(!c.saw_prev_marked);
440 arc0.descend_into_self(&mut c);
441 assert!(c.saw_prev_marked);
445 fn new(&'static str) -> Self;
446 fn name(&self) -> &str;
451 fn set_mark(&self, mark: M);
457 next: Cell<Option<&'a S<'a>>>,
460 impl<'a> Named for S<'a> {
461 fn new<'b>(name: &'static str) -> S<'b> {
462 S { name: name, mark: Cell::new(0), next: Cell::new(None) }
464 fn name(&self) -> &str { self.name }
467 impl<'a> Marked<u32> for S<'a> {
468 fn mark(&self) -> u32 { self.mark.get() }
469 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
475 next: Cell<(Option<&'a S2<'a>>, Option<&'a S2<'a>>)>,
478 impl<'a> Named for S2<'a> {
479 fn new<'b>(name: &'static str) -> S2<'b> {
480 S2 { name: name, mark: Cell::new(0), next: Cell::new((None, None)) }
482 fn name(&self) -> &str { self.name }
485 impl<'a> Marked<u32> for S2<'a> {
486 fn mark(&self) -> u32 { self.mark.get() }
487 fn set_mark(&self, mark: u32) {
495 contents: Vec<Cell<Option<&'a V<'a>>>>,
498 impl<'a> Named for V<'a> {
499 fn new<'b>(name: &'static str) -> V<'b> {
502 contents: vec![Cell::new(None), Cell::new(None)]
505 fn name(&self) -> &str { self.name }
508 impl<'a> Marked<u32> for V<'a> {
509 fn mark(&self) -> u32 { self.mark.get() }
510 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
517 next: Cell<Option<&'a H<'a>>>,
520 impl<'a> Named for H<'a> {
521 fn new<'b>(name: &'static str) -> H<'b> {
522 H { name: name, mark: Cell::new(0), next: Cell::new(None) }
524 fn name(&self) -> &str { self.name }
527 impl<'a> Marked<u32> for H<'a> {
528 fn mark(&self) -> u32 { self.mark.get() }
529 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
532 impl<'a> PartialEq for H<'a> {
533 fn eq(&self, rhs: &H<'a>) -> bool {
534 self.name == rhs.name
538 impl<'a> Hash for H<'a> {
539 fn hash<H: Hasher>(&self, state: &mut H) {
540 self.name.hash(state)
548 contents: Cell<Option<&'a HashMap<HM<'a>, HM<'a>>>>,
551 impl<'a> Named for HM<'a> {
552 fn new<'b>(name: &'static str) -> HM<'b> {
555 contents: Cell::new(None)
558 fn name(&self) -> &str { self.name }
561 impl<'a> Marked<u32> for HM<'a> {
562 fn mark(&self) -> u32 { self.mark.get() }
563 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
566 impl<'a> PartialEq for HM<'a> {
567 fn eq(&self, rhs: &HM<'a>) -> bool {
568 self.name == rhs.name
572 impl<'a> Hash for HM<'a> {
573 fn hash<H: Hasher>(&self, state: &mut H) {
574 self.name.hash(state)
582 contents: Cell<Option<&'a VecDeque<VD<'a>>>>,
585 impl<'a> Named for VD<'a> {
586 fn new<'b>(name: &'static str) -> VD<'b> {
589 contents: Cell::new(None)
592 fn name(&self) -> &str { self.name }
595 impl<'a> Marked<u32> for VD<'a> {
596 fn mark(&self) -> u32 { self.mark.get() }
597 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
603 contents: Cell<Option<&'a HashMap<usize, VM<'a>>>>,
606 impl<'a> Named for VM<'a> {
607 fn new<'b>(name: &'static str) -> VM<'b> {
610 contents: Cell::new(None)
613 fn name(&self) -> &str { self.name }
616 impl<'a> Marked<u32> for VM<'a> {
617 fn mark(&self) -> u32 { self.mark.get() }
618 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
624 contents: Cell<Option<&'a LinkedList<LL<'a>>>>,
627 impl<'a> Named for LL<'a> {
628 fn new<'b>(name: &'static str) -> LL<'b> {
631 contents: Cell::new(None)
634 fn name(&self) -> &str { self.name }
637 impl<'a> Marked<u32> for LL<'a> {
638 fn mark(&self) -> u32 { self.mark.get() }
639 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
645 contents: Cell<Option<&'a BinaryHeap<BH<'a>>>>,
648 impl<'a> Named for BH<'a> {
649 fn new<'b>(name: &'static str) -> BH<'b> {
652 contents: Cell::new(None)
655 fn name(&self) -> &str { self.name }
658 impl<'a> Marked<u32> for BH<'a> {
659 fn mark(&self) -> u32 { self.mark.get() }
660 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
663 impl<'a> Eq for BH<'a> { }
665 impl<'a> PartialEq for BH<'a> {
666 fn eq(&self, rhs: &BH<'a>) -> bool {
667 self.name == rhs.name
671 impl<'a> PartialOrd for BH<'a> {
672 fn partial_cmp(&self, rhs: &BH<'a>) -> Option<Ordering> {
677 impl<'a> Ord for BH<'a> {
678 fn cmp(&self, rhs: &BH<'a>) -> Ordering {
679 self.name.cmp(rhs.name)
686 contents: Cell<Option<&'a BTreeMap<BTM<'a>, BTM<'a>>>>,
689 impl<'a> Named for BTM<'a> {
690 fn new<'b>(name: &'static str) -> BTM<'b> {
693 contents: Cell::new(None)
696 fn name(&self) -> &str { self.name }
699 impl<'a> Marked<u32> for BTM<'a> {
700 fn mark(&self) -> u32 { self.mark.get() }
701 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
704 impl<'a> Eq for BTM<'a> { }
706 impl<'a> PartialEq for BTM<'a> {
707 fn eq(&self, rhs: &BTM<'a>) -> bool {
708 self.name == rhs.name
712 impl<'a> PartialOrd for BTM<'a> {
713 fn partial_cmp(&self, rhs: &BTM<'a>) -> Option<Ordering> {
718 impl<'a> Ord for BTM<'a> {
719 fn cmp(&self, rhs: &BTM<'a>) -> Ordering {
720 self.name.cmp(rhs.name)
727 contents: Cell<Option<&'a BTreeSet<BTS<'a>>>>,
730 impl<'a> Named for BTS<'a> {
731 fn new<'b>(name: &'static str) -> BTS<'b> {
734 contents: Cell::new(None)
737 fn name(&self) -> &str { self.name }
740 impl<'a> Marked<u32> for BTS<'a> {
741 fn mark(&self) -> u32 { self.mark.get() }
742 fn set_mark(&self, mark: u32) { self.mark.set(mark); }
745 impl<'a> Eq for BTS<'a> { }
747 impl<'a> PartialEq for BTS<'a> {
748 fn eq(&self, rhs: &BTS<'a>) -> bool {
749 self.name == rhs.name
753 impl<'a> PartialOrd for BTS<'a> {
754 fn partial_cmp(&self, rhs: &BTS<'a>) -> Option<Ordering> {
759 impl<'a> Ord for BTS<'a> {
760 fn cmp(&self, rhs: &BTS<'a>) -> Ordering {
761 self.name.cmp(rhs.name)
766 struct RCRCData<'a> {
769 children: (Option<&'a RCRC<'a>>, Option<&'a RCRC<'a>>),
772 struct RCRC<'a>(Rc<RefCell<RCRCData<'a>>>);
774 impl<'a> Named for RCRC<'a> {
775 fn new(name: &'static str) -> Self {
776 RCRC(Rc::new(RefCell::new(RCRCData {
777 name: name, mark: Cell::new(0), children: (None, None), })))
779 fn name(&self) -> &str { self.0.borrow().name }
782 impl<'a> Marked<u32> for RCRC<'a> {
783 fn mark(&self) -> u32 { self.0.borrow().mark.get() }
784 fn set_mark(&self, mark: u32) { self.0.borrow().mark.set(mark); }
787 impl<'a> Children<'a> for RCRC<'a> {
788 fn count_children(&self) -> usize { 2 }
789 fn descend_one_child<C>(&self, context: &mut C, index: usize)
790 where C: Context + PrePost<Self>, Self: Sized
792 let children = &self.0.borrow().children;
793 let child = match index {
794 0 => if let Some(child) = children.0 { child } else { return; },
795 1 => if let Some(child) = children.1 { child } else { return; },
796 _ => panic!("bad children"),
798 // println!("S2 {} descending into child {} at index {}", self.name, child.name, index);
799 child.descend_into_self(context);
803 struct ARCRCData<'a> {
806 children: (Option<&'a ARCRC<'a>>, Option<&'a ARCRC<'a>>),
809 struct ARCRC<'a>(Arc<RefCell<ARCRCData<'a>>>);
811 impl<'a> Named for ARCRC<'a> {
812 fn new(name: &'static str) -> Self {
813 ARCRC(Arc::new(RefCell::new(ARCRCData {
814 name: name, mark: Cell::new(0), children: (None, None), })))
816 fn name(&self) -> &str { self.0.borrow().name }
819 impl<'a> Marked<u32> for ARCRC<'a> {
820 fn mark(&self) -> u32 { self.0.borrow().mark.get() }
821 fn set_mark(&self, mark: u32) { self.0.borrow().mark.set(mark); }
824 impl<'a> Children<'a> for ARCRC<'a> {
825 fn count_children(&self) -> usize { 2 }
826 fn descend_one_child<C>(&self, context: &mut C, index: usize)
827 where C: Context + PrePost<Self>, Self: Sized
829 let children = &self.0.borrow().children;
831 0 => if let Some(ref child) = children.0 {
832 child.descend_into_self(context);
834 1 => if let Some(ref child) = children.1 {
835 child.descend_into_self(context);
837 _ => panic!("bad children!"),
843 struct ARCMData<'a> {
845 children: (Option<&'a ARCM<'a>>, Option<&'a ARCM<'a>>),
849 struct ARCM<'a>(&'static str, Arc<Mutex<ARCMData<'a>>>);
851 impl<'a> Named for ARCM<'a> {
852 fn new(name: &'static str) -> Self {
853 ARCM(name, Arc::new(Mutex::new(ARCMData {
854 mark: Cell::new(0), children: (None, None), })))
856 fn name(&self) -> &str { self.0 }
859 impl<'a> Marked<u32> for ARCM<'a> {
860 fn mark(&self) -> u32 { self.1.lock().unwrap().mark.get() }
861 fn set_mark(&self, mark: u32) { self.1.lock().unwrap().mark.set(mark); }
864 impl<'a> Children<'a> for ARCM<'a> {
865 fn count_children(&self) -> usize { 2 }
866 fn descend_one_child<C>(&self, context: &mut C, index: usize)
867 where C: Context + PrePost<Self>, Self: Sized
869 let ref children = if let Ok(data) = self.1.try_lock() {
873 0 => if let Some(ref child) = children.0 {
874 child.descend_into_self(context);
876 1 => if let Some(ref child) = children.1 {
877 child.descend_into_self(context);
879 _ => panic!("bad children!"),
885 struct ARCRWData<'a> {
888 children: (Option<&'a ARCRW<'a>>, Option<&'a ARCRW<'a>>),
892 struct ARCRW<'a>(Arc<RwLock<ARCRWData<'a>>>);
894 impl<'a> Named for ARCRW<'a> {
895 fn new(name: &'static str) -> Self {
896 ARCRW(Arc::new(RwLock::new(ARCRWData {
897 name: name, mark: Cell::new(0), children: (None, None), })))
899 fn name(&self) -> &str { self.0.read().unwrap().name }
902 impl<'a> Marked<u32> for ARCRW<'a> {
903 fn mark(&self) -> u32 { self.0.read().unwrap().mark.get() }
904 fn set_mark(&self, mark: u32) { self.0.read().unwrap().mark.set(mark); }
907 impl<'a> Children<'a> for ARCRW<'a> {
908 fn count_children(&self) -> usize { 2 }
909 fn descend_one_child<C>(&self, context: &mut C, index: usize)
910 where C: Context + PrePost<Self>, Self: Sized
912 let children = &self.0.read().unwrap().children;
914 0 => if let Some(ref child) = children.0 {
915 child.descend_into_self(context);
917 1 => if let Some(ref child) = children.1 {
918 child.descend_into_self(context);
920 _ => panic!("bad children!"),
926 fn next_index(&mut self, len: usize) -> usize;
927 fn should_act(&self) -> bool;
928 fn increase_visited(&mut self);
929 fn increase_skipped(&mut self);
930 fn increase_depth(&mut self);
931 fn decrease_depth(&mut self);
935 fn pre(&mut self, &T);
936 fn post(&mut self, &T);
937 fn hit_limit(&mut self, &T);
941 fn count_children(&self) -> usize;
942 fn descend_one_child<C>(&self, context: &mut C, index: usize)
943 where C: Context + PrePost<Self>, Self: Sized;
945 fn next_child<C>(&self, context: &mut C)
946 where C: Context + PrePost<Self>, Self: Sized
948 let index = context.next_index(self.count_children());
949 self.descend_one_child(context, index);
952 fn descend_into_self<C>(&self, context: &mut C)
953 where C: Context + PrePost<Self>, Self: Sized
956 if context.should_act() {
957 context.increase_visited();
958 context.increase_depth();
959 self.next_child(context);
960 context.decrease_depth();
962 context.hit_limit(self);
963 context.increase_skipped();
968 fn descend<'b, C>(&self, c: &Cell<Option<&'b Self>>, context: &mut C)
969 where C: Context + PrePost<Self>, Self: Sized
971 if let Some(r) = c.get() {
972 r.descend_into_self(context);
977 impl<'a> Children<'a> for S<'a> {
978 fn count_children(&self) -> usize { 1 }
979 fn descend_one_child<C>(&self, context: &mut C, _: usize)
980 where C: Context + PrePost<Self>, Self: Sized {
981 self.descend(&self.next, context);
985 impl<'a> Children<'a> for S2<'a> {
986 fn count_children(&self) -> usize { 2 }
987 fn descend_one_child<C>(&self, context: &mut C, index: usize)
988 where C: Context + PrePost<Self>, Self: Sized
990 let children = self.next.get();
991 let child = match index {
992 0 => if let Some(child) = children.0 { child } else { return; },
993 1 => if let Some(child) = children.1 { child } else { return; },
994 _ => panic!("bad children"),
996 // println!("S2 {} descending into child {} at index {}", self.name, child.name, index);
997 child.descend_into_self(context);
1001 impl<'a> Children<'a> for V<'a> {
1002 fn count_children(&self) -> usize { self.contents.len() }
1003 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1004 where C: Context + PrePost<Self>, Self: Sized
1006 if let Some(child) = self.contents[index].get() {
1007 child.descend_into_self(context);
1012 impl<'a> Children<'a> for H<'a> {
1013 fn count_children(&self) -> usize { 1 }
1014 fn descend_one_child<C>(&self, context: &mut C, _: usize)
1015 where C: Context + PrePost<Self>, Self: Sized
1017 self.descend(&self.next, context);
1021 impl<'a> Children<'a> for HM<'a> {
1022 fn count_children(&self) -> usize {
1023 if let Some(m) = self.contents.get() { 2 * m.iter().count() } else { 0 }
1025 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1026 where C: Context + PrePost<Self>, Self: Sized
1028 if let Some(ref hm) = self.contents.get() {
1029 for (k, v) in hm.iter().nth(index / 2) {
1030 [k, v][index % 2].descend_into_self(context);
1036 impl<'a> Children<'a> for VD<'a> {
1037 fn count_children(&self) -> usize {
1038 if let Some(d) = self.contents.get() { d.iter().count() } else { 0 }
1040 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1041 where C: Context + PrePost<Self>, Self: Sized
1043 if let Some(ref vd) = self.contents.get() {
1044 for r in vd.iter().nth(index) {
1045 r.descend_into_self(context);
1051 impl<'a> Children<'a> for VM<'a> {
1052 fn count_children(&self) -> usize {
1053 if let Some(m) = self.contents.get() { m.iter().count() } else { 0 }
1055 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1056 where C: Context + PrePost<VM<'a>>
1058 if let Some(ref vd) = self.contents.get() {
1059 for (_idx, r) in vd.iter().nth(index) {
1060 r.descend_into_self(context);
1066 impl<'a> Children<'a> for LL<'a> {
1067 fn count_children(&self) -> usize {
1068 if let Some(l) = self.contents.get() { l.iter().count() } else { 0 }
1070 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1071 where C: Context + PrePost<LL<'a>>
1073 if let Some(ref ll) = self.contents.get() {
1074 for r in ll.iter().nth(index) {
1075 r.descend_into_self(context);
1081 impl<'a> Children<'a> for BH<'a> {
1082 fn count_children(&self) -> usize {
1083 if let Some(h) = self.contents.get() { h.iter().count() } else { 0 }
1085 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1086 where C: Context + PrePost<BH<'a>>
1088 if let Some(ref bh) = self.contents.get() {
1089 for r in bh.iter().nth(index) {
1090 r.descend_into_self(context);
1096 impl<'a> Children<'a> for BTM<'a> {
1097 fn count_children(&self) -> usize {
1098 if let Some(m) = self.contents.get() { 2 * m.iter().count() } else { 0 }
1100 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1101 where C: Context + PrePost<BTM<'a>>
1103 if let Some(ref bh) = self.contents.get() {
1104 for (k, v) in bh.iter().nth(index / 2) {
1105 [k, v][index % 2].descend_into_self(context);
1111 impl<'a> Children<'a> for BTS<'a> {
1112 fn count_children(&self) -> usize {
1113 if let Some(s) = self.contents.get() { s.iter().count() } else { 0 }
1115 fn descend_one_child<C>(&self, context: &mut C, index: usize)
1116 where C: Context + PrePost<BTS<'a>>
1118 if let Some(ref bh) = self.contents.get() {
1119 for r in bh.iter().nth(index) {
1120 r.descend_into_self(context);
1126 #[derive(Copy, Clone)]
1127 struct ContextData {
1134 saw_prev_marked: bool,
1138 impl Context for ContextData {
1139 fn next_index(&mut self, len: usize) -> usize {
1140 if len < 2 { return 0; }
1141 let mut pow2 = len.next_power_of_two();
1142 let _pow2_orig = pow2;
1144 let mut bits = self.control_bits;
1146 idx = (idx << 1) | (bits & 1) as usize;
1151 // println!("next_index({} [{:b}]) says {}, pre(bits): {:b} post(bits): {:b}",
1152 // len, _pow2_orig, idx, self.control_bits, bits);
1153 self.control_bits = bits;
1156 fn should_act(&self) -> bool {
1157 self.curr_depth < self.max_depth && self.visited < self.max_visits
1159 fn increase_visited(&mut self) { self.visited += 1; }
1160 fn increase_skipped(&mut self) { self.skipped += 1; }
1161 fn increase_depth(&mut self) { self.curr_depth += 1; }
1162 fn decrease_depth(&mut self) { self.curr_depth -= 1; }
1165 impl<T:Named+Marked<u32>> PrePost<T> for ContextData {
1166 fn pre(&mut self, t: &T) {
1167 for _ in 0..self.curr_depth {
1168 if PRINT { print!(" "); }
1170 if PRINT { println!("prev {}", t.name()); }
1171 if t.mark() == self.curr_mark {
1172 for _ in 0..self.curr_depth {
1173 if PRINT { print!(" "); }
1175 if PRINT { println!("(probably previously marked)"); }
1176 self.saw_prev_marked = true;
1178 t.set_mark(self.curr_mark);
1180 fn post(&mut self, t: &T) {
1181 for _ in 0..self.curr_depth {
1182 if PRINT { print!(" "); }
1184 if PRINT { println!("post {}", t.name()); }
1186 fn hit_limit(&mut self, t: &T) {
1187 for _ in 0..self.curr_depth {
1188 if PRINT { print!(" "); }
1190 if PRINT { println!("LIMIT {}", t.name()); }