]>
Commit | Line | Data |
---|---|---|
b7449926 | 1 | // run-pass |
c1a9b12d SL |
2 | // This test exercises cases where cyclic structure is legal, |
3 | // including when the cycles go through data-structures such | |
4 | // as `Vec` or `TypedArena`. | |
5 | // | |
6 | // The intent is to cover as many such cases as possible, ensuring | |
7 | // that if the compiler did not complain circa Rust 1.x (1.2 as of | |
8 | // this writing), then it will continue to not complain in the future. | |
9 | // | |
10 | // Note that while some of the tests are only exercising using the | |
11 | // given collection as a "backing store" for a set of nodes that hold | |
12 | // the actual cycle (and thus the cycle does not go through the | |
13 | // collection itself in such cases), in general we *do* want to make | |
14 | // sure to have at least one example exercising a cycle that goes | |
15 | // through the collection, for every collection type that supports | |
16 | // this. | |
17 | ||
b039eaaf SL |
18 | // HIGH LEVEL DESCRIPTION OF THE TEST ARCHITECTURE |
19 | // ----------------------------------------------- | |
20 | // | |
21 | // We pick a data structure and want to make a cyclic construction | |
22 | // from it. Each test of interest is labelled starting with "Cycle N: | |
23 | // { ... }" where N is the test number and the "..."`is filled in with | |
24 | // a graphviz-style description of the graph structure that the | |
25 | // author believes is being made. So "{ a -> b, b -> (c,d), (c,d) -> e }" | |
26 | // describes a line connected to a diamond: | |
27 | // | |
28 | // c | |
29 | // / \ | |
30 | // a - b e | |
31 | // \ / | |
32 | // d | |
33 | // | |
34 | // (Note that the above directed graph is actually acyclic.) | |
35 | // | |
36 | // The different graph structures are often composed of different data | |
37 | // types. Some may be built atop `Vec`, others atop `HashMap`, etc. | |
38 | // | |
39 | // For each graph structure, we actually *confirm* that a cycle exists | |
40 | // (as a safe-guard against a test author accidentally leaving it out) | |
41 | // by traversing each graph and "proving" that a cycle exists within it. | |
42 | // | |
43 | // To do this, while trying to keep the code uniform (despite working | |
44 | // with different underlying collection and smart-pointer types), we | |
45 | // have a standard traversal API: | |
46 | // | |
47 | // 1. every node in the graph carries a `mark` (a u32, init'ed to 0). | |
48 | // | |
49 | // 2. every node provides a method to visit its children | |
50 | // | |
51 | // 3. a traversal attmepts to visit the nodes of the graph and prove that | |
52 | // it sees the same node twice. It does this by setting the mark of each | |
53 | // node to a fresh non-zero value, and if it sees the current mark, it | |
54 | // "knows" that it must have found a cycle, and stops attempting further | |
55 | // traversal. | |
56 | // | |
57 | // 4. each traversal is controlled by a bit-string that tells it which child | |
58 | // it visit when it can take different paths. As a simple example, | |
59 | // in a binary tree, 0 could mean "left" (and 1, "right"), so that | |
60 | // "00010" means "left, left, left, right, left". (In general it will | |
61 | // read as many bits as it needs to choose one child.) | |
62 | // | |
63 | // The graphs in this test are all meant to be very small, and thus | |
64 | // short bitstrings of less than 64 bits should always suffice. | |
65 | // | |
66 | // (An earlier version of this test infrastructure simply had any | |
67 | // given traversal visit all children it encountered, in a | |
68 | // depth-first manner; one problem with this approach is that an | |
69 | // acyclic graph can still have sharing, which would then be treated | |
70 | // as a repeat mark and reported as a detected cycle.) | |
71 | // | |
72 | // The travseral code is a little more complicated because it has been | |
73 | // programmed in a somewhat defensive manner. For example it also has | |
74 | // a max threshold for the number of nodes it will visit, to guard | |
75 | // against scenarios where the nodes are not correctly setting their | |
76 | // mark when asked. There are various other methods not discussed here | |
77 | // that are for aiding debugging the test when it runs, such as the | |
78 | // `name` method that all nodes provide. | |
79 | // | |
80 | // So each test: | |
81 | // | |
82 | // 1. allocates the nodes in the graph, | |
83 | // | |
84 | // 2. sets up the links in the graph, | |
85 | // | |
86 | // 3. clones the "ContextData" | |
87 | // | |
88 | // 4. chooses a new current mark value for this test | |
89 | // | |
90 | // 5. initiates a traversal, potentially from multiple starting points | |
91 | // (aka "roots"), with a given control-string (potentially a | |
92 | // different string for each root). if it does start from a | |
93 | // distinct root, then such a test should also increment the | |
94 | // current mark value, so that this traversal is considered | |
95 | // distinct from the prior one on this graph structure. | |
96 | // | |
97 | // Note that most of the tests work with the default control string | |
98 | // of all-zeroes. | |
99 | // | |
100 | // 6. assert that the context confirms that it actually saw a cycle (since a traversal | |
0731742a | 101 | // might have terminated, e.g., on a tree structure that contained no cycles). |
c1a9b12d | 102 | |
b039eaaf | 103 | use std::cell::{Cell, RefCell}; |
c1a9b12d SL |
104 | use std::cmp::Ordering; |
105 | use std::collections::BinaryHeap; | |
106 | use std::collections::HashMap; | |
107 | use std::collections::LinkedList; | |
108 | use std::collections::VecDeque; | |
c1a9b12d SL |
109 | use std::collections::btree_map::BTreeMap; |
110 | use std::collections::btree_set::BTreeSet; | |
111 | use std::hash::{Hash, Hasher}; | |
b039eaaf SL |
112 | use std::rc::Rc; |
113 | use std::sync::{Arc, RwLock, Mutex}; | |
c1a9b12d SL |
114 | |
115 | const PRINT: bool = false; | |
116 | ||
117 | pub fn main() { | |
118 | let c_orig = ContextData { | |
119 | curr_depth: 0, | |
120 | max_depth: 3, | |
121 | visited: 0, | |
122 | max_visits: 1000, | |
123 | skipped: 0, | |
124 | curr_mark: 0, | |
125 | saw_prev_marked: false, | |
b039eaaf | 126 | control_bits: 0, |
c1a9b12d SL |
127 | }; |
128 | ||
b039eaaf SL |
129 | // SANITY CHECK FOR TEST SUITE (thus unnumbered) |
130 | // Not a cycle: { v[0] -> (v[1], v[2]), v[1] -> v[3], v[2] -> v[3] }; | |
131 | let v: Vec<S2> = vec![Named::new("s0"), | |
132 | Named::new("s1"), | |
133 | Named::new("s2"), | |
134 | Named::new("s3")]; | |
135 | v[0].next.set((Some(&v[1]), Some(&v[2]))); | |
136 | v[1].next.set((Some(&v[3]), None)); | |
137 | v[2].next.set((Some(&v[3]), None)); | |
138 | v[3].next.set((None, None)); | |
139 | ||
140 | let mut c = c_orig.clone(); | |
141 | c.curr_mark = 10; | |
142 | assert!(!c.saw_prev_marked); | |
143 | v[0].descend_into_self(&mut c); | |
144 | assert!(!c.saw_prev_marked); // <-- different from below, b/c acyclic above | |
145 | ||
e1599b0c | 146 | if PRINT { println!(); } |
b039eaaf | 147 | |
c1a9b12d SL |
148 | // Cycle 1: { v[0] -> v[1], v[1] -> v[0] }; |
149 | // does not exercise `v` itself | |
150 | let v: Vec<S> = vec![Named::new("s0"), | |
151 | Named::new("s1")]; | |
152 | v[0].next.set(Some(&v[1])); | |
153 | v[1].next.set(Some(&v[0])); | |
154 | ||
155 | let mut c = c_orig.clone(); | |
156 | c.curr_mark = 10; | |
157 | assert!(!c.saw_prev_marked); | |
b039eaaf | 158 | v[0].descend_into_self(&mut c); |
c1a9b12d SL |
159 | assert!(c.saw_prev_marked); |
160 | ||
e1599b0c | 161 | if PRINT { println!(); } |
c1a9b12d SL |
162 | |
163 | // Cycle 2: { v[0] -> v, v[1] -> v } | |
164 | let v: V = Named::new("v"); | |
165 | v.contents[0].set(Some(&v)); | |
166 | v.contents[1].set(Some(&v)); | |
167 | ||
168 | let mut c = c_orig.clone(); | |
169 | c.curr_mark = 20; | |
170 | assert!(!c.saw_prev_marked); | |
b039eaaf | 171 | v.descend_into_self(&mut c); |
c1a9b12d SL |
172 | assert!(c.saw_prev_marked); |
173 | ||
e1599b0c | 174 | if PRINT { println!(); } |
c1a9b12d SL |
175 | |
176 | // Cycle 3: { hk0 -> hv0, hv0 -> hk0, hk1 -> hv1, hv1 -> hk1 }; | |
177 | // does not exercise `h` itself | |
178 | ||
179 | let mut h: HashMap<H,H> = HashMap::new(); | |
180 | h.insert(Named::new("hk0"), Named::new("hv0")); | |
181 | h.insert(Named::new("hk1"), Named::new("hv1")); | |
182 | for (key, val) in h.iter() { | |
183 | val.next.set(Some(key)); | |
184 | key.next.set(Some(val)); | |
185 | } | |
186 | ||
187 | let mut c = c_orig.clone(); | |
188 | c.curr_mark = 30; | |
189 | for (key, _) in h.iter() { | |
190 | c.curr_mark += 1; | |
191 | c.saw_prev_marked = false; | |
b039eaaf | 192 | key.descend_into_self(&mut c); |
c1a9b12d SL |
193 | assert!(c.saw_prev_marked); |
194 | } | |
195 | ||
e1599b0c | 196 | if PRINT { println!(); } |
c1a9b12d SL |
197 | |
198 | // Cycle 4: { h -> (hmk0,hmv0,hmk1,hmv1), {hmk0,hmv0,hmk1,hmv1} -> h } | |
199 | ||
200 | let mut h: HashMap<HM,HM> = HashMap::new(); | |
201 | h.insert(Named::new("hmk0"), Named::new("hmv0")); | |
202 | h.insert(Named::new("hmk0"), Named::new("hmv0")); | |
203 | for (key, val) in h.iter() { | |
204 | val.contents.set(Some(&h)); | |
205 | key.contents.set(Some(&h)); | |
206 | } | |
207 | ||
208 | let mut c = c_orig.clone(); | |
209 | c.max_depth = 2; | |
210 | c.curr_mark = 40; | |
211 | for (key, _) in h.iter() { | |
212 | c.curr_mark += 1; | |
213 | c.saw_prev_marked = false; | |
b039eaaf | 214 | key.descend_into_self(&mut c); |
c1a9b12d SL |
215 | assert!(c.saw_prev_marked); |
216 | // break; | |
217 | } | |
218 | ||
e1599b0c | 219 | if PRINT { println!(); } |
c1a9b12d SL |
220 | |
221 | // Cycle 5: { vd[0] -> vd[1], vd[1] -> vd[0] }; | |
222 | // does not exercise vd itself | |
223 | let mut vd: VecDeque<S> = VecDeque::new(); | |
224 | vd.push_back(Named::new("d0")); | |
225 | vd.push_back(Named::new("d1")); | |
226 | vd[0].next.set(Some(&vd[1])); | |
227 | vd[1].next.set(Some(&vd[0])); | |
228 | ||
229 | let mut c = c_orig.clone(); | |
230 | c.curr_mark = 50; | |
231 | assert!(!c.saw_prev_marked); | |
b039eaaf | 232 | vd[0].descend_into_self(&mut c); |
c1a9b12d SL |
233 | assert!(c.saw_prev_marked); |
234 | ||
e1599b0c | 235 | if PRINT { println!(); } |
c1a9b12d SL |
236 | |
237 | // Cycle 6: { vd -> (vd0, vd1), {vd0, vd1} -> vd } | |
238 | let mut vd: VecDeque<VD> = VecDeque::new(); | |
239 | vd.push_back(Named::new("vd0")); | |
240 | vd.push_back(Named::new("vd1")); | |
241 | vd[0].contents.set(Some(&vd)); | |
242 | vd[1].contents.set(Some(&vd)); | |
243 | ||
244 | let mut c = c_orig.clone(); | |
245 | c.curr_mark = 60; | |
246 | assert!(!c.saw_prev_marked); | |
b039eaaf | 247 | vd[0].descend_into_self(&mut c); |
c1a9b12d SL |
248 | assert!(c.saw_prev_marked); |
249 | ||
e1599b0c | 250 | if PRINT { println!(); } |
c1a9b12d SL |
251 | |
252 | // Cycle 7: { vm -> (vm0, vm1), {vm0, vm1} -> vm } | |
e9174d1e | 253 | let mut vm: HashMap<usize, VM> = HashMap::new(); |
c1a9b12d SL |
254 | vm.insert(0, Named::new("vm0")); |
255 | vm.insert(1, Named::new("vm1")); | |
e9174d1e SL |
256 | vm[&0].contents.set(Some(&vm)); |
257 | vm[&1].contents.set(Some(&vm)); | |
c1a9b12d SL |
258 | |
259 | let mut c = c_orig.clone(); | |
260 | c.curr_mark = 70; | |
261 | assert!(!c.saw_prev_marked); | |
b039eaaf | 262 | vm[&0].descend_into_self(&mut c); |
c1a9b12d SL |
263 | assert!(c.saw_prev_marked); |
264 | ||
e1599b0c | 265 | if PRINT { println!(); } |
c1a9b12d SL |
266 | |
267 | // Cycle 8: { ll -> (ll0, ll1), {ll0, ll1} -> ll } | |
268 | let mut ll: LinkedList<LL> = LinkedList::new(); | |
269 | ll.push_back(Named::new("ll0")); | |
270 | ll.push_back(Named::new("ll1")); | |
271 | for e in &ll { | |
272 | e.contents.set(Some(&ll)); | |
273 | } | |
274 | ||
275 | let mut c = c_orig.clone(); | |
276 | c.curr_mark = 80; | |
277 | for e in &ll { | |
278 | c.curr_mark += 1; | |
279 | c.saw_prev_marked = false; | |
b039eaaf | 280 | e.descend_into_self(&mut c); |
c1a9b12d SL |
281 | assert!(c.saw_prev_marked); |
282 | // break; | |
283 | } | |
284 | ||
e1599b0c | 285 | if PRINT { println!(); } |
c1a9b12d SL |
286 | |
287 | // Cycle 9: { bh -> (bh0, bh1), {bh0, bh1} -> bh } | |
288 | let mut bh: BinaryHeap<BH> = BinaryHeap::new(); | |
289 | bh.push(Named::new("bh0")); | |
290 | bh.push(Named::new("bh1")); | |
291 | for b in bh.iter() { | |
292 | b.contents.set(Some(&bh)); | |
293 | } | |
294 | ||
295 | let mut c = c_orig.clone(); | |
296 | c.curr_mark = 90; | |
297 | for b in &bh { | |
298 | c.curr_mark += 1; | |
299 | c.saw_prev_marked = false; | |
b039eaaf | 300 | b.descend_into_self(&mut c); |
c1a9b12d SL |
301 | assert!(c.saw_prev_marked); |
302 | // break; | |
303 | } | |
304 | ||
e1599b0c | 305 | if PRINT { println!(); } |
c1a9b12d SL |
306 | |
307 | // Cycle 10: { btm -> (btk0, btv1), {bt0, bt1} -> btm } | |
308 | let mut btm: BTreeMap<BTM, BTM> = BTreeMap::new(); | |
309 | btm.insert(Named::new("btk0"), Named::new("btv0")); | |
310 | btm.insert(Named::new("btk1"), Named::new("btv1")); | |
311 | for (k, v) in btm.iter() { | |
312 | k.contents.set(Some(&btm)); | |
313 | v.contents.set(Some(&btm)); | |
314 | } | |
315 | ||
316 | let mut c = c_orig.clone(); | |
317 | c.curr_mark = 100; | |
318 | for (k, _) in &btm { | |
319 | c.curr_mark += 1; | |
320 | c.saw_prev_marked = false; | |
b039eaaf | 321 | k.descend_into_self(&mut c); |
c1a9b12d SL |
322 | assert!(c.saw_prev_marked); |
323 | // break; | |
324 | } | |
325 | ||
e1599b0c | 326 | if PRINT { println!(); } |
c1a9b12d SL |
327 | |
328 | // Cycle 10: { bts -> (bts0, bts1), {bts0, bts1} -> btm } | |
329 | let mut bts: BTreeSet<BTS> = BTreeSet::new(); | |
330 | bts.insert(Named::new("bts0")); | |
331 | bts.insert(Named::new("bts1")); | |
332 | for v in bts.iter() { | |
333 | v.contents.set(Some(&bts)); | |
334 | } | |
335 | ||
336 | let mut c = c_orig.clone(); | |
337 | c.curr_mark = 100; | |
338 | for b in &bts { | |
339 | c.curr_mark += 1; | |
340 | c.saw_prev_marked = false; | |
b039eaaf | 341 | b.descend_into_self(&mut c); |
c1a9b12d SL |
342 | assert!(c.saw_prev_marked); |
343 | // break; | |
344 | } | |
b039eaaf | 345 | |
e1599b0c | 346 | if PRINT { println!(); } |
b039eaaf SL |
347 | |
348 | // Cycle 11: { rc0 -> (rc1, rc2), rc1 -> (), rc2 -> rc0 } | |
349 | let (rc0, rc1, rc2): (RCRC, RCRC, RCRC); | |
350 | rc0 = RCRC::new("rcrc0"); | |
351 | rc1 = RCRC::new("rcrc1"); | |
352 | rc2 = RCRC::new("rcrc2"); | |
353 | rc0.0.borrow_mut().children.0 = Some(&rc1); | |
354 | rc0.0.borrow_mut().children.1 = Some(&rc2); | |
355 | rc2.0.borrow_mut().children.0 = Some(&rc0); | |
356 | ||
357 | let mut c = c_orig.clone(); | |
358 | c.control_bits = 0b1; | |
359 | c.curr_mark = 110; | |
360 | assert!(!c.saw_prev_marked); | |
361 | rc0.descend_into_self(&mut c); | |
362 | assert!(c.saw_prev_marked); | |
363 | ||
e1599b0c | 364 | if PRINT { println!(); } |
b039eaaf SL |
365 | |
366 | // We want to take the previous Rc case and generalize it to Arc. | |
367 | // | |
368 | // We can use refcells if we're single-threaded (as this test is). | |
369 | // If one were to generalize these constructions to a | |
370 | // multi-threaded context, then it might seem like we could choose | |
94222f64 | 371 | // between either an RwLock or a Mutex to hold the owned arcs on |
b039eaaf SL |
372 | // each node. |
373 | // | |
374 | // Part of the point of this test is to actually confirm that the | |
375 | // cycle exists by traversing it. We can do that just fine with an | |
376 | // RwLock (since we can grab the child pointers in read-only | |
377 | // mode), but we cannot lock a std::sync::Mutex to guard reading | |
378 | // from each node via the same pattern, since once you hit the | |
b7449926 | 379 | // cycle, you'll be trying to acquiring the same lock twice. |
b039eaaf SL |
380 | // (We deal with this by exiting the traversal early if try_lock fails.) |
381 | ||
382 | // Cycle 12: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, refcells | |
383 | let (arc0, arc1, arc2): (ARCRC, ARCRC, ARCRC); | |
384 | arc0 = ARCRC::new("arcrc0"); | |
385 | arc1 = ARCRC::new("arcrc1"); | |
386 | arc2 = ARCRC::new("arcrc2"); | |
387 | arc0.0.borrow_mut().children.0 = Some(&arc1); | |
388 | arc0.0.borrow_mut().children.1 = Some(&arc2); | |
389 | arc2.0.borrow_mut().children.0 = Some(&arc0); | |
390 | ||
391 | let mut c = c_orig.clone(); | |
392 | c.control_bits = 0b1; | |
393 | c.curr_mark = 110; | |
394 | assert!(!c.saw_prev_marked); | |
395 | arc0.descend_into_self(&mut c); | |
396 | assert!(c.saw_prev_marked); | |
397 | ||
e1599b0c | 398 | if PRINT { println!(); } |
b039eaaf SL |
399 | |
400 | // Cycle 13: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, rwlocks | |
401 | let (arc0, arc1, arc2): (ARCRW, ARCRW, ARCRW); | |
402 | arc0 = ARCRW::new("arcrw0"); | |
403 | arc1 = ARCRW::new("arcrw1"); | |
404 | arc2 = ARCRW::new("arcrw2"); | |
405 | arc0.0.write().unwrap().children.0 = Some(&arc1); | |
406 | arc0.0.write().unwrap().children.1 = Some(&arc2); | |
407 | arc2.0.write().unwrap().children.0 = Some(&arc0); | |
408 | ||
409 | let mut c = c_orig.clone(); | |
410 | c.control_bits = 0b1; | |
411 | c.curr_mark = 110; | |
412 | assert!(!c.saw_prev_marked); | |
413 | arc0.descend_into_self(&mut c); | |
414 | assert!(c.saw_prev_marked); | |
415 | ||
e1599b0c | 416 | if PRINT { println!(); } |
b039eaaf SL |
417 | |
418 | // Cycle 14: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, mutexs | |
419 | let (arc0, arc1, arc2): (ARCM, ARCM, ARCM); | |
420 | arc0 = ARCM::new("arcm0"); | |
421 | arc1 = ARCM::new("arcm1"); | |
422 | arc2 = ARCM::new("arcm2"); | |
423 | arc0.1.lock().unwrap().children.0 = Some(&arc1); | |
424 | arc0.1.lock().unwrap().children.1 = Some(&arc2); | |
425 | arc2.1.lock().unwrap().children.0 = Some(&arc0); | |
426 | ||
427 | let mut c = c_orig.clone(); | |
428 | c.control_bits = 0b1; | |
429 | c.curr_mark = 110; | |
430 | assert!(!c.saw_prev_marked); | |
431 | arc0.descend_into_self(&mut c); | |
432 | assert!(c.saw_prev_marked); | |
c1a9b12d SL |
433 | } |
434 | ||
435 | trait Named { | |
041b39d2 | 436 | fn new(_: &'static str) -> Self; |
c1a9b12d SL |
437 | fn name(&self) -> &str; |
438 | } | |
439 | ||
440 | trait Marked<M> { | |
441 | fn mark(&self) -> M; | |
442 | fn set_mark(&self, mark: M); | |
443 | } | |
444 | ||
445 | struct S<'a> { | |
446 | name: &'static str, | |
447 | mark: Cell<u32>, | |
448 | next: Cell<Option<&'a S<'a>>>, | |
449 | } | |
450 | ||
451 | impl<'a> Named for S<'a> { | |
3157f602 | 452 | fn new(name: &'static str) -> S<'a> { |
c1a9b12d SL |
453 | S { name: name, mark: Cell::new(0), next: Cell::new(None) } |
454 | } | |
455 | fn name(&self) -> &str { self.name } | |
456 | } | |
457 | ||
458 | impl<'a> Marked<u32> for S<'a> { | |
459 | fn mark(&self) -> u32 { self.mark.get() } | |
460 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
461 | } | |
462 | ||
b039eaaf SL |
463 | struct S2<'a> { |
464 | name: &'static str, | |
465 | mark: Cell<u32>, | |
466 | next: Cell<(Option<&'a S2<'a>>, Option<&'a S2<'a>>)>, | |
467 | } | |
468 | ||
469 | impl<'a> Named for S2<'a> { | |
3157f602 | 470 | fn new(name: &'static str) -> S2<'a> { |
b039eaaf SL |
471 | S2 { name: name, mark: Cell::new(0), next: Cell::new((None, None)) } |
472 | } | |
473 | fn name(&self) -> &str { self.name } | |
474 | } | |
475 | ||
476 | impl<'a> Marked<u32> for S2<'a> { | |
477 | fn mark(&self) -> u32 { self.mark.get() } | |
478 | fn set_mark(&self, mark: u32) { | |
479 | self.mark.set(mark); | |
480 | } | |
481 | } | |
482 | ||
c1a9b12d SL |
483 | struct V<'a> { |
484 | name: &'static str, | |
485 | mark: Cell<u32>, | |
486 | contents: Vec<Cell<Option<&'a V<'a>>>>, | |
487 | } | |
488 | ||
489 | impl<'a> Named for V<'a> { | |
3157f602 | 490 | fn new(name: &'static str) -> V<'a> { |
c1a9b12d SL |
491 | V { name: name, |
492 | mark: Cell::new(0), | |
493 | contents: vec![Cell::new(None), Cell::new(None)] | |
494 | } | |
495 | } | |
496 | fn name(&self) -> &str { self.name } | |
497 | } | |
498 | ||
499 | impl<'a> Marked<u32> for V<'a> { | |
500 | fn mark(&self) -> u32 { self.mark.get() } | |
501 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
502 | } | |
503 | ||
504 | #[derive(Eq)] | |
505 | struct H<'a> { | |
506 | name: &'static str, | |
507 | mark: Cell<u32>, | |
508 | next: Cell<Option<&'a H<'a>>>, | |
509 | } | |
510 | ||
511 | impl<'a> Named for H<'a> { | |
3157f602 | 512 | fn new(name: &'static str) -> H<'a> { |
c1a9b12d SL |
513 | H { name: name, mark: Cell::new(0), next: Cell::new(None) } |
514 | } | |
515 | fn name(&self) -> &str { self.name } | |
516 | } | |
517 | ||
518 | impl<'a> Marked<u32> for H<'a> { | |
519 | fn mark(&self) -> u32 { self.mark.get() } | |
520 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
521 | } | |
522 | ||
523 | impl<'a> PartialEq for H<'a> { | |
524 | fn eq(&self, rhs: &H<'a>) -> bool { | |
525 | self.name == rhs.name | |
526 | } | |
527 | } | |
528 | ||
529 | impl<'a> Hash for H<'a> { | |
530 | fn hash<H: Hasher>(&self, state: &mut H) { | |
531 | self.name.hash(state) | |
532 | } | |
533 | } | |
534 | ||
535 | #[derive(Eq)] | |
536 | struct HM<'a> { | |
537 | name: &'static str, | |
538 | mark: Cell<u32>, | |
539 | contents: Cell<Option<&'a HashMap<HM<'a>, HM<'a>>>>, | |
540 | } | |
541 | ||
542 | impl<'a> Named for HM<'a> { | |
3157f602 | 543 | fn new(name: &'static str) -> HM<'a> { |
c1a9b12d SL |
544 | HM { name: name, |
545 | mark: Cell::new(0), | |
546 | contents: Cell::new(None) | |
547 | } | |
548 | } | |
549 | fn name(&self) -> &str { self.name } | |
550 | } | |
551 | ||
552 | impl<'a> Marked<u32> for HM<'a> { | |
553 | fn mark(&self) -> u32 { self.mark.get() } | |
554 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
555 | } | |
556 | ||
557 | impl<'a> PartialEq for HM<'a> { | |
558 | fn eq(&self, rhs: &HM<'a>) -> bool { | |
559 | self.name == rhs.name | |
560 | } | |
561 | } | |
562 | ||
563 | impl<'a> Hash for HM<'a> { | |
564 | fn hash<H: Hasher>(&self, state: &mut H) { | |
565 | self.name.hash(state) | |
566 | } | |
567 | } | |
568 | ||
569 | ||
570 | struct VD<'a> { | |
571 | name: &'static str, | |
572 | mark: Cell<u32>, | |
573 | contents: Cell<Option<&'a VecDeque<VD<'a>>>>, | |
574 | } | |
575 | ||
576 | impl<'a> Named for VD<'a> { | |
3157f602 | 577 | fn new(name: &'static str) -> VD<'a> { |
c1a9b12d SL |
578 | VD { name: name, |
579 | mark: Cell::new(0), | |
580 | contents: Cell::new(None) | |
581 | } | |
582 | } | |
583 | fn name(&self) -> &str { self.name } | |
584 | } | |
585 | ||
586 | impl<'a> Marked<u32> for VD<'a> { | |
587 | fn mark(&self) -> u32 { self.mark.get() } | |
588 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
589 | } | |
590 | ||
591 | struct VM<'a> { | |
592 | name: &'static str, | |
593 | mark: Cell<u32>, | |
e9174d1e | 594 | contents: Cell<Option<&'a HashMap<usize, VM<'a>>>>, |
c1a9b12d SL |
595 | } |
596 | ||
597 | impl<'a> Named for VM<'a> { | |
3157f602 | 598 | fn new(name: &'static str) -> VM<'a> { |
c1a9b12d SL |
599 | VM { name: name, |
600 | mark: Cell::new(0), | |
601 | contents: Cell::new(None) | |
602 | } | |
603 | } | |
604 | fn name(&self) -> &str { self.name } | |
605 | } | |
606 | ||
607 | impl<'a> Marked<u32> for VM<'a> { | |
608 | fn mark(&self) -> u32 { self.mark.get() } | |
609 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
610 | } | |
611 | ||
612 | struct LL<'a> { | |
613 | name: &'static str, | |
614 | mark: Cell<u32>, | |
615 | contents: Cell<Option<&'a LinkedList<LL<'a>>>>, | |
616 | } | |
617 | ||
618 | impl<'a> Named for LL<'a> { | |
3157f602 | 619 | fn new(name: &'static str) -> LL<'a> { |
c1a9b12d SL |
620 | LL { name: name, |
621 | mark: Cell::new(0), | |
622 | contents: Cell::new(None) | |
623 | } | |
624 | } | |
625 | fn name(&self) -> &str { self.name } | |
626 | } | |
627 | ||
628 | impl<'a> Marked<u32> for LL<'a> { | |
629 | fn mark(&self) -> u32 { self.mark.get() } | |
630 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
631 | } | |
632 | ||
633 | struct BH<'a> { | |
634 | name: &'static str, | |
635 | mark: Cell<u32>, | |
636 | contents: Cell<Option<&'a BinaryHeap<BH<'a>>>>, | |
637 | } | |
638 | ||
639 | impl<'a> Named for BH<'a> { | |
3157f602 | 640 | fn new(name: &'static str) -> BH<'a> { |
c1a9b12d SL |
641 | BH { name: name, |
642 | mark: Cell::new(0), | |
643 | contents: Cell::new(None) | |
644 | } | |
645 | } | |
646 | fn name(&self) -> &str { self.name } | |
647 | } | |
648 | ||
649 | impl<'a> Marked<u32> for BH<'a> { | |
650 | fn mark(&self) -> u32 { self.mark.get() } | |
651 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
652 | } | |
653 | ||
654 | impl<'a> Eq for BH<'a> { } | |
655 | ||
656 | impl<'a> PartialEq for BH<'a> { | |
657 | fn eq(&self, rhs: &BH<'a>) -> bool { | |
658 | self.name == rhs.name | |
659 | } | |
660 | } | |
661 | ||
662 | impl<'a> PartialOrd for BH<'a> { | |
663 | fn partial_cmp(&self, rhs: &BH<'a>) -> Option<Ordering> { | |
664 | Some(self.cmp(rhs)) | |
665 | } | |
666 | } | |
667 | ||
668 | impl<'a> Ord for BH<'a> { | |
669 | fn cmp(&self, rhs: &BH<'a>) -> Ordering { | |
670 | self.name.cmp(rhs.name) | |
671 | } | |
672 | } | |
673 | ||
674 | struct BTM<'a> { | |
675 | name: &'static str, | |
676 | mark: Cell<u32>, | |
677 | contents: Cell<Option<&'a BTreeMap<BTM<'a>, BTM<'a>>>>, | |
678 | } | |
679 | ||
680 | impl<'a> Named for BTM<'a> { | |
3157f602 | 681 | fn new(name: &'static str) -> BTM<'a> { |
c1a9b12d SL |
682 | BTM { name: name, |
683 | mark: Cell::new(0), | |
684 | contents: Cell::new(None) | |
685 | } | |
686 | } | |
687 | fn name(&self) -> &str { self.name } | |
688 | } | |
689 | ||
690 | impl<'a> Marked<u32> for BTM<'a> { | |
691 | fn mark(&self) -> u32 { self.mark.get() } | |
692 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
693 | } | |
694 | ||
695 | impl<'a> Eq for BTM<'a> { } | |
696 | ||
697 | impl<'a> PartialEq for BTM<'a> { | |
698 | fn eq(&self, rhs: &BTM<'a>) -> bool { | |
699 | self.name == rhs.name | |
700 | } | |
701 | } | |
702 | ||
703 | impl<'a> PartialOrd for BTM<'a> { | |
704 | fn partial_cmp(&self, rhs: &BTM<'a>) -> Option<Ordering> { | |
705 | Some(self.cmp(rhs)) | |
706 | } | |
707 | } | |
708 | ||
709 | impl<'a> Ord for BTM<'a> { | |
710 | fn cmp(&self, rhs: &BTM<'a>) -> Ordering { | |
711 | self.name.cmp(rhs.name) | |
712 | } | |
713 | } | |
714 | ||
715 | struct BTS<'a> { | |
716 | name: &'static str, | |
717 | mark: Cell<u32>, | |
718 | contents: Cell<Option<&'a BTreeSet<BTS<'a>>>>, | |
719 | } | |
720 | ||
721 | impl<'a> Named for BTS<'a> { | |
3157f602 | 722 | fn new(name: &'static str) -> BTS<'a> { |
c1a9b12d SL |
723 | BTS { name: name, |
724 | mark: Cell::new(0), | |
725 | contents: Cell::new(None) | |
726 | } | |
727 | } | |
728 | fn name(&self) -> &str { self.name } | |
729 | } | |
730 | ||
731 | impl<'a> Marked<u32> for BTS<'a> { | |
732 | fn mark(&self) -> u32 { self.mark.get() } | |
733 | fn set_mark(&self, mark: u32) { self.mark.set(mark); } | |
734 | } | |
735 | ||
736 | impl<'a> Eq for BTS<'a> { } | |
737 | ||
738 | impl<'a> PartialEq for BTS<'a> { | |
739 | fn eq(&self, rhs: &BTS<'a>) -> bool { | |
740 | self.name == rhs.name | |
741 | } | |
742 | } | |
743 | ||
744 | impl<'a> PartialOrd for BTS<'a> { | |
745 | fn partial_cmp(&self, rhs: &BTS<'a>) -> Option<Ordering> { | |
746 | Some(self.cmp(rhs)) | |
747 | } | |
748 | } | |
749 | ||
750 | impl<'a> Ord for BTS<'a> { | |
751 | fn cmp(&self, rhs: &BTS<'a>) -> Ordering { | |
752 | self.name.cmp(rhs.name) | |
753 | } | |
754 | } | |
755 | ||
b039eaaf SL |
756 | #[derive(Clone)] |
757 | struct RCRCData<'a> { | |
758 | name: &'static str, | |
759 | mark: Cell<u32>, | |
760 | children: (Option<&'a RCRC<'a>>, Option<&'a RCRC<'a>>), | |
761 | } | |
762 | #[derive(Clone)] | |
763 | struct RCRC<'a>(Rc<RefCell<RCRCData<'a>>>); | |
764 | ||
765 | impl<'a> Named for RCRC<'a> { | |
766 | fn new(name: &'static str) -> Self { | |
767 | RCRC(Rc::new(RefCell::new(RCRCData { | |
768 | name: name, mark: Cell::new(0), children: (None, None), }))) | |
769 | } | |
770 | fn name(&self) -> &str { self.0.borrow().name } | |
771 | } | |
772 | ||
773 | impl<'a> Marked<u32> for RCRC<'a> { | |
774 | fn mark(&self) -> u32 { self.0.borrow().mark.get() } | |
775 | fn set_mark(&self, mark: u32) { self.0.borrow().mark.set(mark); } | |
776 | } | |
777 | ||
778 | impl<'a> Children<'a> for RCRC<'a> { | |
779 | fn count_children(&self) -> usize { 2 } | |
780 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
781 | where C: Context + PrePost<Self>, Self: Sized | |
782 | { | |
783 | let children = &self.0.borrow().children; | |
784 | let child = match index { | |
785 | 0 => if let Some(child) = children.0 { child } else { return; }, | |
786 | 1 => if let Some(child) = children.1 { child } else { return; }, | |
787 | _ => panic!("bad children"), | |
788 | }; | |
789 | // println!("S2 {} descending into child {} at index {}", self.name, child.name, index); | |
790 | child.descend_into_self(context); | |
791 | } | |
792 | } | |
793 | #[derive(Clone)] | |
794 | struct ARCRCData<'a> { | |
795 | name: &'static str, | |
796 | mark: Cell<u32>, | |
797 | children: (Option<&'a ARCRC<'a>>, Option<&'a ARCRC<'a>>), | |
798 | } | |
799 | #[derive(Clone)] | |
800 | struct ARCRC<'a>(Arc<RefCell<ARCRCData<'a>>>); | |
801 | ||
802 | impl<'a> Named for ARCRC<'a> { | |
803 | fn new(name: &'static str) -> Self { | |
804 | ARCRC(Arc::new(RefCell::new(ARCRCData { | |
805 | name: name, mark: Cell::new(0), children: (None, None), }))) | |
806 | } | |
807 | fn name(&self) -> &str { self.0.borrow().name } | |
808 | } | |
809 | ||
810 | impl<'a> Marked<u32> for ARCRC<'a> { | |
811 | fn mark(&self) -> u32 { self.0.borrow().mark.get() } | |
812 | fn set_mark(&self, mark: u32) { self.0.borrow().mark.set(mark); } | |
813 | } | |
814 | ||
815 | impl<'a> Children<'a> for ARCRC<'a> { | |
816 | fn count_children(&self) -> usize { 2 } | |
817 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
818 | where C: Context + PrePost<Self>, Self: Sized | |
819 | { | |
820 | let children = &self.0.borrow().children; | |
821 | match index { | |
822 | 0 => if let Some(ref child) = children.0 { | |
823 | child.descend_into_self(context); | |
824 | }, | |
825 | 1 => if let Some(ref child) = children.1 { | |
826 | child.descend_into_self(context); | |
827 | }, | |
828 | _ => panic!("bad children!"), | |
829 | } | |
830 | } | |
831 | } | |
832 | ||
833 | #[derive(Clone)] | |
834 | struct ARCMData<'a> { | |
835 | mark: Cell<u32>, | |
836 | children: (Option<&'a ARCM<'a>>, Option<&'a ARCM<'a>>), | |
837 | } | |
838 | ||
839 | #[derive(Clone)] | |
840 | struct ARCM<'a>(&'static str, Arc<Mutex<ARCMData<'a>>>); | |
841 | ||
842 | impl<'a> Named for ARCM<'a> { | |
843 | fn new(name: &'static str) -> Self { | |
844 | ARCM(name, Arc::new(Mutex::new(ARCMData { | |
845 | mark: Cell::new(0), children: (None, None), }))) | |
846 | } | |
847 | fn name(&self) -> &str { self.0 } | |
848 | } | |
849 | ||
850 | impl<'a> Marked<u32> for ARCM<'a> { | |
851 | fn mark(&self) -> u32 { self.1.lock().unwrap().mark.get() } | |
852 | fn set_mark(&self, mark: u32) { self.1.lock().unwrap().mark.set(mark); } | |
853 | } | |
854 | ||
855 | impl<'a> Children<'a> for ARCM<'a> { | |
856 | fn count_children(&self) -> usize { 2 } | |
857 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
858 | where C: Context + PrePost<Self>, Self: Sized | |
859 | { | |
860 | let ref children = if let Ok(data) = self.1.try_lock() { | |
861 | data.children | |
862 | } else { return; }; | |
863 | match index { | |
864 | 0 => if let Some(ref child) = children.0 { | |
865 | child.descend_into_self(context); | |
866 | }, | |
867 | 1 => if let Some(ref child) = children.1 { | |
868 | child.descend_into_self(context); | |
869 | }, | |
870 | _ => panic!("bad children!"), | |
871 | } | |
872 | } | |
873 | } | |
874 | ||
875 | #[derive(Clone)] | |
876 | struct ARCRWData<'a> { | |
877 | name: &'static str, | |
878 | mark: Cell<u32>, | |
879 | children: (Option<&'a ARCRW<'a>>, Option<&'a ARCRW<'a>>), | |
880 | } | |
881 | ||
882 | #[derive(Clone)] | |
883 | struct ARCRW<'a>(Arc<RwLock<ARCRWData<'a>>>); | |
884 | ||
885 | impl<'a> Named for ARCRW<'a> { | |
886 | fn new(name: &'static str) -> Self { | |
887 | ARCRW(Arc::new(RwLock::new(ARCRWData { | |
888 | name: name, mark: Cell::new(0), children: (None, None), }))) | |
889 | } | |
890 | fn name(&self) -> &str { self.0.read().unwrap().name } | |
891 | } | |
892 | ||
893 | impl<'a> Marked<u32> for ARCRW<'a> { | |
894 | fn mark(&self) -> u32 { self.0.read().unwrap().mark.get() } | |
895 | fn set_mark(&self, mark: u32) { self.0.read().unwrap().mark.set(mark); } | |
896 | } | |
897 | ||
898 | impl<'a> Children<'a> for ARCRW<'a> { | |
899 | fn count_children(&self) -> usize { 2 } | |
900 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
901 | where C: Context + PrePost<Self>, Self: Sized | |
902 | { | |
903 | let children = &self.0.read().unwrap().children; | |
904 | match index { | |
905 | 0 => if let Some(ref child) = children.0 { | |
906 | child.descend_into_self(context); | |
907 | }, | |
908 | 1 => if let Some(ref child) = children.1 { | |
909 | child.descend_into_self(context); | |
910 | }, | |
911 | _ => panic!("bad children!"), | |
912 | } | |
913 | } | |
914 | } | |
c1a9b12d SL |
915 | |
916 | trait Context { | |
b039eaaf | 917 | fn next_index(&mut self, len: usize) -> usize; |
c1a9b12d SL |
918 | fn should_act(&self) -> bool; |
919 | fn increase_visited(&mut self); | |
920 | fn increase_skipped(&mut self); | |
921 | fn increase_depth(&mut self); | |
922 | fn decrease_depth(&mut self); | |
923 | } | |
924 | ||
925 | trait PrePost<T> { | |
041b39d2 XL |
926 | fn pre(&mut self, _: &T); |
927 | fn post(&mut self, _: &T); | |
928 | fn hit_limit(&mut self, _: &T); | |
c1a9b12d SL |
929 | } |
930 | ||
931 | trait Children<'a> { | |
b039eaaf SL |
932 | fn count_children(&self) -> usize; |
933 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
c1a9b12d SL |
934 | where C: Context + PrePost<Self>, Self: Sized; |
935 | ||
b039eaaf SL |
936 | fn next_child<C>(&self, context: &mut C) |
937 | where C: Context + PrePost<Self>, Self: Sized | |
938 | { | |
939 | let index = context.next_index(self.count_children()); | |
940 | self.descend_one_child(context, index); | |
941 | } | |
942 | ||
c1a9b12d SL |
943 | fn descend_into_self<C>(&self, context: &mut C) |
944 | where C: Context + PrePost<Self>, Self: Sized | |
945 | { | |
946 | context.pre(self); | |
947 | if context.should_act() { | |
948 | context.increase_visited(); | |
949 | context.increase_depth(); | |
b039eaaf | 950 | self.next_child(context); |
c1a9b12d SL |
951 | context.decrease_depth(); |
952 | } else { | |
953 | context.hit_limit(self); | |
954 | context.increase_skipped(); | |
955 | } | |
956 | context.post(self); | |
957 | } | |
958 | ||
959 | fn descend<'b, C>(&self, c: &Cell<Option<&'b Self>>, context: &mut C) | |
960 | where C: Context + PrePost<Self>, Self: Sized | |
961 | { | |
962 | if let Some(r) = c.get() { | |
963 | r.descend_into_self(context); | |
964 | } | |
965 | } | |
966 | } | |
967 | ||
968 | impl<'a> Children<'a> for S<'a> { | |
b039eaaf SL |
969 | fn count_children(&self) -> usize { 1 } |
970 | fn descend_one_child<C>(&self, context: &mut C, _: usize) | |
971 | where C: Context + PrePost<Self>, Self: Sized { | |
972 | self.descend(&self.next, context); | |
973 | } | |
974 | } | |
975 | ||
976 | impl<'a> Children<'a> for S2<'a> { | |
977 | fn count_children(&self) -> usize { 2 } | |
978 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
979 | where C: Context + PrePost<Self>, Self: Sized | |
c1a9b12d | 980 | { |
b039eaaf SL |
981 | let children = self.next.get(); |
982 | let child = match index { | |
983 | 0 => if let Some(child) = children.0 { child } else { return; }, | |
984 | 1 => if let Some(child) = children.1 { child } else { return; }, | |
985 | _ => panic!("bad children"), | |
986 | }; | |
987 | // println!("S2 {} descending into child {} at index {}", self.name, child.name, index); | |
988 | child.descend_into_self(context); | |
c1a9b12d SL |
989 | } |
990 | } | |
991 | ||
992 | impl<'a> Children<'a> for V<'a> { | |
b039eaaf SL |
993 | fn count_children(&self) -> usize { self.contents.len() } |
994 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
995 | where C: Context + PrePost<Self>, Self: Sized | |
c1a9b12d | 996 | { |
b039eaaf SL |
997 | if let Some(child) = self.contents[index].get() { |
998 | child.descend_into_self(context); | |
c1a9b12d SL |
999 | } |
1000 | } | |
1001 | } | |
1002 | ||
1003 | impl<'a> Children<'a> for H<'a> { | |
b039eaaf SL |
1004 | fn count_children(&self) -> usize { 1 } |
1005 | fn descend_one_child<C>(&self, context: &mut C, _: usize) | |
1006 | where C: Context + PrePost<Self>, Self: Sized | |
c1a9b12d SL |
1007 | { |
1008 | self.descend(&self.next, context); | |
1009 | } | |
1010 | } | |
1011 | ||
1012 | impl<'a> Children<'a> for HM<'a> { | |
b039eaaf SL |
1013 | fn count_children(&self) -> usize { |
1014 | if let Some(m) = self.contents.get() { 2 * m.iter().count() } else { 0 } | |
1015 | } | |
1016 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
1017 | where C: Context + PrePost<Self>, Self: Sized | |
c1a9b12d SL |
1018 | { |
1019 | if let Some(ref hm) = self.contents.get() { | |
2b03887a | 1020 | if let Some((k, v)) = hm.iter().nth(index / 2) { |
b039eaaf | 1021 | [k, v][index % 2].descend_into_self(context); |
c1a9b12d SL |
1022 | } |
1023 | } | |
1024 | } | |
1025 | } | |
1026 | ||
1027 | impl<'a> Children<'a> for VD<'a> { | |
b039eaaf SL |
1028 | fn count_children(&self) -> usize { |
1029 | if let Some(d) = self.contents.get() { d.iter().count() } else { 0 } | |
1030 | } | |
1031 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
1032 | where C: Context + PrePost<Self>, Self: Sized | |
c1a9b12d SL |
1033 | { |
1034 | if let Some(ref vd) = self.contents.get() { | |
2b03887a | 1035 | if let Some(r) = vd.iter().nth(index) { |
c1a9b12d SL |
1036 | r.descend_into_self(context); |
1037 | } | |
1038 | } | |
1039 | } | |
1040 | } | |
1041 | ||
1042 | impl<'a> Children<'a> for VM<'a> { | |
b039eaaf SL |
1043 | fn count_children(&self) -> usize { |
1044 | if let Some(m) = self.contents.get() { m.iter().count() } else { 0 } | |
1045 | } | |
1046 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
c1a9b12d SL |
1047 | where C: Context + PrePost<VM<'a>> |
1048 | { | |
1049 | if let Some(ref vd) = self.contents.get() { | |
2b03887a | 1050 | if let Some((_idx, r)) = vd.iter().nth(index) { |
c1a9b12d SL |
1051 | r.descend_into_self(context); |
1052 | } | |
1053 | } | |
1054 | } | |
1055 | } | |
1056 | ||
1057 | impl<'a> Children<'a> for LL<'a> { | |
b039eaaf SL |
1058 | fn count_children(&self) -> usize { |
1059 | if let Some(l) = self.contents.get() { l.iter().count() } else { 0 } | |
1060 | } | |
1061 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
c1a9b12d SL |
1062 | where C: Context + PrePost<LL<'a>> |
1063 | { | |
1064 | if let Some(ref ll) = self.contents.get() { | |
2b03887a | 1065 | if let Some(r) = ll.iter().nth(index) { |
c1a9b12d SL |
1066 | r.descend_into_self(context); |
1067 | } | |
1068 | } | |
1069 | } | |
1070 | } | |
1071 | ||
1072 | impl<'a> Children<'a> for BH<'a> { | |
b039eaaf SL |
1073 | fn count_children(&self) -> usize { |
1074 | if let Some(h) = self.contents.get() { h.iter().count() } else { 0 } | |
1075 | } | |
1076 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
c1a9b12d SL |
1077 | where C: Context + PrePost<BH<'a>> |
1078 | { | |
1079 | if let Some(ref bh) = self.contents.get() { | |
2b03887a | 1080 | if let Some(r) = bh.iter().nth(index) { |
c1a9b12d SL |
1081 | r.descend_into_self(context); |
1082 | } | |
1083 | } | |
1084 | } | |
1085 | } | |
1086 | ||
1087 | impl<'a> Children<'a> for BTM<'a> { | |
b039eaaf SL |
1088 | fn count_children(&self) -> usize { |
1089 | if let Some(m) = self.contents.get() { 2 * m.iter().count() } else { 0 } | |
1090 | } | |
1091 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
c1a9b12d SL |
1092 | where C: Context + PrePost<BTM<'a>> |
1093 | { | |
1094 | if let Some(ref bh) = self.contents.get() { | |
2b03887a | 1095 | if let Some((k, v)) = bh.iter().nth(index / 2) { |
b039eaaf | 1096 | [k, v][index % 2].descend_into_self(context); |
c1a9b12d SL |
1097 | } |
1098 | } | |
1099 | } | |
1100 | } | |
1101 | ||
1102 | impl<'a> Children<'a> for BTS<'a> { | |
b039eaaf SL |
1103 | fn count_children(&self) -> usize { |
1104 | if let Some(s) = self.contents.get() { s.iter().count() } else { 0 } | |
1105 | } | |
1106 | fn descend_one_child<C>(&self, context: &mut C, index: usize) | |
c1a9b12d SL |
1107 | where C: Context + PrePost<BTS<'a>> |
1108 | { | |
1109 | if let Some(ref bh) = self.contents.get() { | |
2b03887a | 1110 | if let Some(r) = bh.iter().nth(index) { |
c1a9b12d SL |
1111 | r.descend_into_self(context); |
1112 | } | |
1113 | } | |
1114 | } | |
1115 | } | |
1116 | ||
1117 | #[derive(Copy, Clone)] | |
1118 | struct ContextData { | |
1119 | curr_depth: usize, | |
1120 | max_depth: usize, | |
1121 | visited: usize, | |
1122 | max_visits: usize, | |
1123 | skipped: usize, | |
1124 | curr_mark: u32, | |
1125 | saw_prev_marked: bool, | |
b039eaaf | 1126 | control_bits: u64, |
c1a9b12d SL |
1127 | } |
1128 | ||
1129 | impl Context for ContextData { | |
b039eaaf SL |
1130 | fn next_index(&mut self, len: usize) -> usize { |
1131 | if len < 2 { return 0; } | |
1132 | let mut pow2 = len.next_power_of_two(); | |
1133 | let _pow2_orig = pow2; | |
1134 | let mut idx = 0; | |
1135 | let mut bits = self.control_bits; | |
1136 | while pow2 > 1 { | |
1137 | idx = (idx << 1) | (bits & 1) as usize; | |
1138 | bits = bits >> 1; | |
1139 | pow2 = pow2 >> 1; | |
1140 | } | |
1141 | idx = idx % len; | |
1142 | // println!("next_index({} [{:b}]) says {}, pre(bits): {:b} post(bits): {:b}", | |
1143 | // len, _pow2_orig, idx, self.control_bits, bits); | |
1144 | self.control_bits = bits; | |
1145 | return idx; | |
1146 | } | |
c1a9b12d SL |
1147 | fn should_act(&self) -> bool { |
1148 | self.curr_depth < self.max_depth && self.visited < self.max_visits | |
1149 | } | |
1150 | fn increase_visited(&mut self) { self.visited += 1; } | |
1151 | fn increase_skipped(&mut self) { self.skipped += 1; } | |
1152 | fn increase_depth(&mut self) { self.curr_depth += 1; } | |
1153 | fn decrease_depth(&mut self) { self.curr_depth -= 1; } | |
1154 | } | |
1155 | ||
1156 | impl<T:Named+Marked<u32>> PrePost<T> for ContextData { | |
1157 | fn pre(&mut self, t: &T) { | |
1158 | for _ in 0..self.curr_depth { | |
1159 | if PRINT { print!(" "); } | |
1160 | } | |
1161 | if PRINT { println!("prev {}", t.name()); } | |
1162 | if t.mark() == self.curr_mark { | |
1163 | for _ in 0..self.curr_depth { | |
1164 | if PRINT { print!(" "); } | |
1165 | } | |
1166 | if PRINT { println!("(probably previously marked)"); } | |
1167 | self.saw_prev_marked = true; | |
1168 | } | |
1169 | t.set_mark(self.curr_mark); | |
1170 | } | |
1171 | fn post(&mut self, t: &T) { | |
1172 | for _ in 0..self.curr_depth { | |
1173 | if PRINT { print!(" "); } | |
1174 | } | |
1175 | if PRINT { println!("post {}", t.name()); } | |
1176 | } | |
1177 | fn hit_limit(&mut self, t: &T) { | |
1178 | for _ in 0..self.curr_depth { | |
1179 | if PRINT { print!(" "); } | |
1180 | } | |
1181 | if PRINT { println!("LIMIT {}", t.name()); } | |
1182 | } | |
1183 | } |