]> git.proxmox.com Git - rustc.git/blame - vendor/ena-0.13.1/src/unify/tests.rs
New upstream version 1.45.0+dfsg1
[rustc.git] / vendor / ena-0.13.1 / src / unify / tests.rs
CommitLineData
f9f354fc
XL
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.
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// Naming the benchmarks using uppercase letters helps them sort
12// better.
13#![allow(non_snake_case)]
14
15#[cfg(feature = "bench")]
16extern crate test;
17#[cfg(feature = "bench")]
18use self::test::Bencher;
19use std::cmp;
20use unify::{NoError, InPlace, InPlaceUnificationTable, UnifyKey, EqUnifyValue, UnifyValue};
21use unify::{UnificationStore, UnificationTable};
22#[cfg(feature = "persistent")]
23use unify::Persistent;
24
25#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
26struct UnitKey(u32);
27
28impl UnifyKey for UnitKey {
29 type Value = ();
30 fn index(&self) -> u32 {
31 self.0
32 }
33 fn from_index(u: u32) -> UnitKey {
34 UnitKey(u)
35 }
36 fn tag() -> &'static str {
37 "UnitKey"
38 }
39}
40
41macro_rules! all_modes {
42 ($name:ident for $t:ty => $body:tt) => {
43 fn test_body<$name: UnificationStore<Key = $t, Value = <$t as UnifyKey>::Value>>() {
44 $body
45 }
46
47 test_body::<InPlace<$t>>();
48
49 #[cfg(feature = "persistent")]
50 test_body::<Persistent<$t>>();
51 }
52}
53
54#[test]
55fn basic() {
56 all_modes! {
57 S for UnitKey => {
58 let mut ut: UnificationTable<S> = UnificationTable::new();
59 let k1 = ut.new_key(());
60 let k2 = ut.new_key(());
61 assert_eq!(ut.unioned(k1, k2), false);
62 ut.union(k1, k2);
63 assert_eq!(ut.unioned(k1, k2), true);
64 }
65 }
66}
67
68#[test]
69fn big_array() {
70 all_modes! {
71 S for UnitKey => {
72 let mut ut: UnificationTable<S> = UnificationTable::new();
73 let mut keys = Vec::new();
74 const MAX: usize = 1 << 15;
75
76 for _ in 0..MAX {
77 keys.push(ut.new_key(()));
78 }
79
80 for i in 1..MAX {
81 let l = keys[i - 1];
82 let r = keys[i];
83 ut.union(l, r);
84 }
85
86 for i in 0..MAX {
87 assert!(ut.unioned(keys[0], keys[i]));
88 }
89 }
90 }
91}
92
93#[cfg(feature = "bench")]
94fn big_array_bench_generic<S: UnificationStore<Key=UnitKey, Value=()>>(b: &mut Bencher) {
95 let mut ut: UnificationTable<S> = UnificationTable::new();
96 let mut keys = Vec::new();
97 const MAX: usize = 1 << 15;
98
99 for _ in 0..MAX {
100 keys.push(ut.new_key(()));
101 }
102
103 b.iter(|| {
104 for i in 1..MAX {
105 let l = keys[i - 1];
106 let r = keys[i];
107 ut.union(l, r);
108 }
109
110 for i in 0..MAX {
111 assert!(ut.unioned(keys[0], keys[i]));
112 }
113 })
114}
115
116#[cfg(feature = "bench")]
117#[bench]
118fn big_array_bench_InPlace(b: &mut Bencher) {
119 big_array_bench_generic::<InPlace<UnitKey>>(b);
120}
121
122#[cfg(all(feature = "bench", feature = "persistent"))]
123#[bench]
124fn big_array_bench_Persistent(b: &mut Bencher) {
125 big_array_bench_generic::<Persistent<UnitKey>>(b);
126}
127
128#[cfg(feature = "bench")]
129fn big_array_bench_in_snapshot_generic<S: UnificationStore<Key=UnitKey, Value=()>>(b: &mut Bencher) {
130 let mut ut: UnificationTable<S> = UnificationTable::new();
131 let mut keys = Vec::new();
132 const MAX: usize = 1 << 15;
133
134 for _ in 0..MAX {
135 keys.push(ut.new_key(()));
136 }
137
138 b.iter(|| {
139 let snapshot = ut.snapshot();
140
141 for i in 1..MAX {
142 let l = keys[i - 1];
143 let r = keys[i];
144 ut.union(l, r);
145 }
146
147 for i in 0..MAX {
148 assert!(ut.unioned(keys[0], keys[i]));
149 }
150
151 ut.rollback_to(snapshot);
152 })
153}
154
155#[cfg(feature = "bench")]
156#[bench]
157fn big_array_bench_in_snapshot_InPlace(b: &mut Bencher) {
158 big_array_bench_in_snapshot_generic::<InPlace<UnitKey>>(b);
159}
160
161#[cfg(all(feature = "bench", feature = "persistent"))]
162#[bench]
163fn big_array_bench_in_snapshot_Persistent(b: &mut Bencher) {
164 big_array_bench_in_snapshot_generic::<Persistent<UnitKey>>(b);
165}
166
167#[cfg(feature = "bench")]
168fn big_array_bench_clone_generic<S: UnificationStore<Key=UnitKey, Value=()>>(b: &mut Bencher) {
169 let mut ut: UnificationTable<S> = UnificationTable::new();
170 let mut keys = Vec::new();
171 const MAX: usize = 1 << 15;
172
173 for _ in 0..MAX {
174 keys.push(ut.new_key(()));
175 }
176
177 b.iter(|| {
178 let saved_table = ut.clone();
179
180 for i in 1..MAX {
181 let l = keys[i - 1];
182 let r = keys[i];
183 ut.union(l, r);
184 }
185
186 for i in 0..MAX {
187 assert!(ut.unioned(keys[0], keys[i]));
188 }
189
190 ut = saved_table;
191 })
192}
193
194#[cfg(feature = "bench")]
195#[bench]
196fn big_array_bench_clone_InPlace(b: &mut Bencher) {
197 big_array_bench_clone_generic::<InPlace<UnitKey>>(b);
198}
199
200#[cfg(all(feature = "bench", feature = "persistent"))]
201#[bench]
202fn big_array_bench_clone_Persistent(b: &mut Bencher) {
203 big_array_bench_clone_generic::<Persistent<UnitKey>>(b);
204}
205
206#[test]
207fn even_odd() {
208 all_modes! {
209 S for UnitKey => {
210 let mut ut: UnificationTable<S> = UnificationTable::new();
211 let mut keys = Vec::new();
212 const MAX: usize = 1 << 10;
213
214 for i in 0..MAX {
215 let key = ut.new_key(());
216 keys.push(key);
217
218 if i >= 2 {
219 ut.union(key, keys[i - 2]);
220 }
221 }
222
223 for i in 1..MAX {
224 assert!(!ut.unioned(keys[i - 1], keys[i]));
225 }
226
227 for i in 2..MAX {
228 assert!(ut.unioned(keys[i - 2], keys[i]));
229 }
230 }
231 }
232}
233
234#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
235struct IntKey(u32);
236
237impl UnifyKey for IntKey {
238 type Value = Option<i32>;
239 fn index(&self) -> u32 {
240 self.0
241 }
242 fn from_index(u: u32) -> IntKey {
243 IntKey(u)
244 }
245 fn tag() -> &'static str {
246 "IntKey"
247 }
248}
249
250impl EqUnifyValue for i32 {}
251
252#[test]
253fn unify_same_int_twice() {
254 all_modes! {
255 S for IntKey => {
256 let mut ut: UnificationTable<S> = UnificationTable::new();
257 let k1 = ut.new_key(None);
258 let k2 = ut.new_key(None);
259 assert!(ut.unify_var_value(k1, Some(22)).is_ok());
260 assert!(ut.unify_var_value(k2, Some(22)).is_ok());
261 assert!(ut.unify_var_var(k1, k2).is_ok());
262 assert_eq!(ut.probe_value(k1), Some(22));
263 }
264 }
265}
266
267#[test]
268fn unify_vars_then_int_indirect() {
269 all_modes! {
270 S for IntKey => {
271 let mut ut: UnificationTable<S> = UnificationTable::new();
272 let k1 = ut.new_key(None);
273 let k2 = ut.new_key(None);
274 assert!(ut.unify_var_var(k1, k2).is_ok());
275 assert!(ut.unify_var_value(k1, Some(22)).is_ok());
276 assert_eq!(ut.probe_value(k2), Some(22));
277 }
278 }
279}
280
281#[test]
282fn unify_vars_different_ints_1() {
283 all_modes! {
284 S for IntKey => {
285 let mut ut: UnificationTable<S> = UnificationTable::new();
286 let k1 = ut.new_key(None);
287 let k2 = ut.new_key(None);
288 assert!(ut.unify_var_var(k1, k2).is_ok());
289 assert!(ut.unify_var_value(k1, Some(22)).is_ok());
290 assert!(ut.unify_var_value(k2, Some(23)).is_err());
291 }
292 }
293}
294
295#[test]
296fn unify_vars_different_ints_2() {
297 all_modes! {
298 S for IntKey => {
299 let mut ut: UnificationTable<S> = UnificationTable::new();
300 let k1 = ut.new_key(None);
301 let k2 = ut.new_key(None);
302 assert!(ut.unify_var_var(k2, k1).is_ok());
303 assert!(ut.unify_var_value(k1, Some(22)).is_ok());
304 assert!(ut.unify_var_value(k2, Some(23)).is_err());
305 }
306 }
307}
308
309#[test]
310fn unify_distinct_ints_then_vars() {
311 all_modes! {
312 S for IntKey => {
313 let mut ut: UnificationTable<S> = UnificationTable::new();
314 let k1 = ut.new_key(None);
315 let k2 = ut.new_key(None);
316 assert!(ut.unify_var_value(k1, Some(22)).is_ok());
317 assert!(ut.unify_var_value(k2, Some(23)).is_ok());
318 assert!(ut.unify_var_var(k2, k1).is_err());
319 }
320 }
321}
322
323#[test]
324fn unify_root_value_1() {
325 all_modes! {
326 S for IntKey => {
327 let mut ut: UnificationTable<S> = UnificationTable::new();
328 let k1 = ut.new_key(None);
329 let k2 = ut.new_key(None);
330 let k3 = ut.new_key(None);
331 assert!(ut.unify_var_value(k1, Some(22)).is_ok());
332 assert!(ut.unify_var_var(k1, k2).is_ok());
333 assert!(ut.unify_var_value(k3, Some(23)).is_ok());
334 assert!(ut.unify_var_var(k1, k3).is_err());
335 }
336 }
337}
338
339#[test]
340fn unify_root_value_2() {
341 all_modes! {
342 S for IntKey => {
343 let mut ut: UnificationTable<S> = UnificationTable::new();
344 let k1 = ut.new_key(None);
345 let k2 = ut.new_key(None);
346 let k3 = ut.new_key(None);
347 assert!(ut.unify_var_value(k1, Some(22)).is_ok());
348 assert!(ut.unify_var_var(k2, k1).is_ok());
349 assert!(ut.unify_var_value(k3, Some(23)).is_ok());
350 assert!(ut.unify_var_var(k1, k3).is_err());
351 }
352 }
353}
354
355#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
356struct OrderedKey(u32);
357
358#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
359struct OrderedRank(u32);
360
361impl UnifyKey for OrderedKey {
362 type Value = OrderedRank;
363 fn index(&self) -> u32 {
364 self.0
365 }
366 fn from_index(u: u32) -> OrderedKey {
367 OrderedKey(u)
368 }
369 fn tag() -> &'static str {
370 "OrderedKey"
371 }
372 fn order_roots(
373 a: OrderedKey,
374 a_rank: &OrderedRank,
375 b: OrderedKey,
376 b_rank: &OrderedRank,
377 ) -> Option<(OrderedKey, OrderedKey)> {
378 println!("{:?} vs {:?}", a_rank, b_rank);
379 if a_rank > b_rank {
380 Some((a, b))
381 } else if b_rank > a_rank {
382 Some((b, a))
383 } else {
384 None
385 }
386 }
387}
388
389impl UnifyValue for OrderedRank {
390 type Error = NoError;
391
392 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> {
393 Ok(OrderedRank(cmp::max(value1.0, value2.0)))
394 }
395}
396
397#[test]
398fn ordered_key() {
399 all_modes! {
400 S for OrderedKey => {
401 let mut ut: UnificationTable<S> = UnificationTable::new();
402
403 let k0_1 = ut.new_key(OrderedRank(0));
404 let k0_2 = ut.new_key(OrderedRank(0));
405 let k0_3 = ut.new_key(OrderedRank(0));
406 let k0_4 = ut.new_key(OrderedRank(0));
407
408 ut.union(k0_1, k0_2); // rank of one of those will now be 1
409 ut.union(k0_3, k0_4); // rank of new root also 1
410 ut.union(k0_1, k0_3); // rank of new root now 2
411
412 let k0_5 = ut.new_key(OrderedRank(0));
413 let k0_6 = ut.new_key(OrderedRank(0));
414 ut.union(k0_5, k0_6); // rank of new root now 1
415
416 ut.union(k0_1, k0_5); // new root rank 2, should not be k0_5 or k0_6
417 assert!(vec![k0_1, k0_2, k0_3, k0_4].contains(&ut.find(k0_1)));
418 }
419 }
420}
421
422#[test]
423fn ordered_key_k1() {
424 all_modes! {
425 S for UnitKey => {
426 let mut ut: InPlaceUnificationTable<OrderedKey> = UnificationTable::new();
427
428 let k0_1 = ut.new_key(OrderedRank(0));
429 let k0_2 = ut.new_key(OrderedRank(0));
430 let k0_3 = ut.new_key(OrderedRank(0));
431 let k0_4 = ut.new_key(OrderedRank(0));
432
433 ut.union(k0_1, k0_2); // rank of one of those will now be 1
434 ut.union(k0_3, k0_4); // rank of new root also 1
435 ut.union(k0_1, k0_3); // rank of new root now 2
436
437 let k1_5 = ut.new_key(OrderedRank(1));
438 let k1_6 = ut.new_key(OrderedRank(1));
439 ut.union(k1_5, k1_6); // rank of new root now 1
440
441 ut.union(k0_1, k1_5); // even though k1 has lower rank, it wins
442 assert!(
443 vec![k1_5, k1_6].contains(&ut.find(k0_1)),
444 "unexpected choice for root: {:?}",
445 ut.find(k0_1)
446 );
447 }
448 }
449}
450
451/// Test that we *can* clone.
452#[test]
453fn clone_table() {
454 all_modes! {
455 S for IntKey => {
456 let mut ut: UnificationTable<S> = UnificationTable::new();
457 let k1 = ut.new_key(None);
458 let k2 = ut.new_key(None);
459 let k3 = ut.new_key(None);
460 assert!(ut.unify_var_value(k1, Some(22)).is_ok());
461 assert!(ut.unify_var_value(k2, Some(22)).is_ok());
462 assert!(ut.unify_var_var(k1, k2).is_ok());
463 assert_eq!(ut.probe_value(k3), None);
464
465 let mut ut1 = ut.clone();
466 assert_eq!(ut1.probe_value(k1), Some(22));
467 assert_eq!(ut1.probe_value(k3), None);
468
469 assert!(ut.unify_var_value(k3, Some(44)).is_ok());
470
471 assert_eq!(ut1.probe_value(k1), Some(22));
472 assert_eq!(ut1.probe_value(k3), None);
473 assert_eq!(ut.probe_value(k3), Some(44));
474 }
475 }
476}