2 using System
.Collections
;
3 using System
.Collections
.Generic
;
4 using System
.Threading
;
8 public List
<object> Links
= new List
<object> ();
9 public static int fin_count
;
16 public class NonBridge
22 const int OBJ_COUNT
= 200 * 1000;
23 const int LINK_COUNT
= 2;
24 const int EXTRAS_COUNT
= 0;
25 const double survival_rate
= 0.6;
28 * Pathological case for the original old algorithm. Goes
29 * away when merging is replaced by appending with flag
32 static void SetupLinks () {
33 var list
= new List
<Bridge
> ();
34 for (int i
= 0; i
< OBJ_COUNT
; ++i
) {
35 var bridge
= new Bridge ();
39 var r
= new Random (100);
40 for (int i
= 0; i
< OBJ_COUNT
; ++i
) {
42 for (int j
= 0; j
< LINK_COUNT
; ++j
)
43 n
.Links
.Add (list
[r
.Next (OBJ_COUNT
)]);
44 for (int j
= 0; j
< EXTRAS_COUNT
; ++j
)
46 if (r
.NextDouble () <= survival_rate
)
49 Console
.WriteLine ("-setup done-");
52 const int LIST_LENGTH
= 20000;
53 const int FAN_OUT
= 20000;
56 * Pathological case for the new algorithm. Goes away with
57 * the single-node elimination optimization, but will still
58 * persist if modified by using a ladder instead of the single
61 static void SetupLinkedFan ()
63 var head
= new Bridge ();
64 var tail
= new NonBridge ();
65 head
.Links
.Add (tail
);
66 for (int i
= 0; i
< LIST_LENGTH
; ++i
)
68 var obj
= new NonBridge ();
72 var list
= new List
<Bridge
> ();
74 for (int i
= 0; i
< FAN_OUT
; ++i
)
75 list
.Add (new Bridge ());
76 Console
.WriteLine ("-linked fan done-");
80 * Pathological case for the improved old algorithm. Goes
81 * away with copy-on-write DynArrays, but will still persist
82 * if modified by using a ladder instead of the single list.
84 static void SetupInverseFan ()
86 var tail
= new Bridge ();
88 for (int i
= 0; i
< LIST_LENGTH
; ++i
)
90 var obj
= new NonBridge ();
94 var heads
= new Bridge
[FAN_OUT
];
95 for (int i
= 0; i
< FAN_OUT
; ++i
)
97 var obj
= new Bridge ();
101 Console
.WriteLine ("-inverse fan done-");
105 * Pathological case for the bridge in general. We generate
106 * 2*FAN_OUT bridge objects here, but the output of the bridge
107 * is a graph with FAN_OUT^2 edges.
109 static void SetupDoubleFan ()
111 var heads
= new Bridge
[FAN_OUT
];
112 for (int i
= 0; i
< FAN_OUT
; ++i
)
113 heads
[i
] = new Bridge ();
115 // We make five identical multiplexers to verify Tarjan-bridge can merge them together correctly.
116 var MULTIPLEXER_COUNT
= 5;
117 Bridge
[] multiplexer0
= null;
118 for(int m
= 0; m
< MULTIPLEXER_COUNT
; m
++) {
119 var multiplexer
= new Bridge
[FAN_OUT
];
121 multiplexer0
= multiplexer
;
122 for (int i
= 0; i
< FAN_OUT
; ++i
)
124 heads
[i
].Links
.Add (multiplexer
);
125 multiplexer
[i
] = new Bridge ();
128 for (int i
= 0; i
< FAN_OUT
; ++i
)
130 heads
[i
].Links
.Add (multiplexer
);
131 multiplexer
[i
] = multiplexer0
[i
];
136 Console
.WriteLine ("-double fan x5 done-");
140 * Not necessarily a pathology, but a special case of where we
141 * generate lots of "dead" SCCs. A non-bridge object that
142 * can't reach a bridge object can safely be removed from the
143 * graph. In this special case it's a linked list hanging off
144 * a bridge object. We can handle this by "forwarding" edges
145 * going to non-bridge nodes that have only a single outgoing
146 * edge. That collapses the whole list into a single node.
147 * We could remove that node, too, by removing non-bridge
148 * nodes with no outgoing edges.
150 static void SetupDeadList ()
152 var head
= new Bridge ();
153 var tail
= new NonBridge ();
154 head
.Links
.Add (tail
);
155 for (int i
= 0; i
< LIST_LENGTH
; ++i
)
157 var obj
= new NonBridge ();
164 * Triggered a bug in the forwarding mechanic.
166 static void SetupSelfLinks ()
168 var head
= new Bridge ();
169 var tail
= new NonBridge ();
170 head
.Links
.Add (tail
);
174 const int L0_COUNT
= 100000;
175 const int L1_COUNT
= 100000;
176 const int EXTRA_LEVELS
= 4;
179 Set a complex graph from one bridge to a couple.
180 The graph is designed to expose naive coloring on
181 tarjan and SCC explosion on classic.
183 static void Spider () {
184 Bridge a
= new Bridge ();
185 Bridge b
= new Bridge ();
187 var l1
= new List
<object> ();
188 for (int i
= 0; i
< L0_COUNT
; ++i
) {
189 var l0
= new List
<object> ();
195 for (int l
= 0; l
< EXTRA_LEVELS
; ++l
) {
197 var l2
= new List
<object> ();
198 for (int i
= 0; i
< L1_COUNT
; ++i
) {
199 var tmp
= new List
<object> ();
200 tmp
.Add (last_level
[j
++ % last_level
.Count
]);
201 tmp
.Add (last_level
[j
++ % last_level
.Count
]);
206 Bridge c
= new Bridge ();
207 c
.Links
.Add (last_level
);
210 static void RunTest (ThreadStart setup
)
212 var t
= new Thread (setup
);
216 for (int i
= 0; i
< 5; ++i
) {
217 Console
.WriteLine("-GC {0}/5-", i
);
219 GC
.WaitForPendingFinalizers ();
222 Console
.WriteLine ("-GCs done- {0}", Bridge
.fin_count
);
227 RunTest (SetupLinks
);
228 RunTest (SetupLinkedFan
);
229 RunTest (SetupInverseFan
);
230 RunTest (SetupDoubleFan
);
231 RunTest (SetupDeadList
);
232 RunTest (SetupSelfLinks
);
235 for (int i
= 0; i
< 0; ++i
) {
237 GC
.WaitForPendingFinalizers ();
238 Console
.WriteLine ("-Cleanup GC- {0}", Bridge
.fin_count
);