206 lines
5.5 KiB
Rust
206 lines
5.5 KiB
Rust
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
#![allow(non_snake_case)]
|
|
|
|
extern crate test;
|
|
use self::test::Bencher;
|
|
use unify::{UnifyKey, UnificationTable};
|
|
|
|
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
|
struct UnitKey(u32);
|
|
|
|
impl UnifyKey for UnitKey {
|
|
type Value = ();
|
|
fn index(&self) -> u32 {
|
|
self.0
|
|
}
|
|
fn from_index(u: u32) -> UnitKey {
|
|
UnitKey(u)
|
|
}
|
|
fn tag(_: Option<UnitKey>) -> &'static str {
|
|
"UnitKey"
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn basic() {
|
|
let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
|
|
let k1 = ut.new_key(());
|
|
let k2 = ut.new_key(());
|
|
assert_eq!(ut.unioned(k1, k2), false);
|
|
ut.union(k1, k2);
|
|
assert_eq!(ut.unioned(k1, k2), true);
|
|
}
|
|
|
|
#[test]
|
|
fn big_array() {
|
|
let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
|
|
let mut keys = Vec::new();
|
|
const MAX: usize = 1 << 15;
|
|
|
|
for _ in 0..MAX {
|
|
keys.push(ut.new_key(()));
|
|
}
|
|
|
|
for i in 1..MAX {
|
|
let l = keys[i - 1];
|
|
let r = keys[i];
|
|
ut.union(l, r);
|
|
}
|
|
|
|
for i in 0..MAX {
|
|
assert!(ut.unioned(keys[0], keys[i]));
|
|
}
|
|
}
|
|
|
|
#[bench]
|
|
fn big_array_bench(b: &mut Bencher) {
|
|
let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
|
|
let mut keys = Vec::new();
|
|
const MAX: usize = 1 << 15;
|
|
|
|
for _ in 0..MAX {
|
|
keys.push(ut.new_key(()));
|
|
}
|
|
|
|
|
|
b.iter(|| {
|
|
for i in 1..MAX {
|
|
let l = keys[i - 1];
|
|
let r = keys[i];
|
|
ut.union(l, r);
|
|
}
|
|
|
|
for i in 0..MAX {
|
|
assert!(ut.unioned(keys[0], keys[i]));
|
|
}
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn even_odd() {
|
|
let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
|
|
let mut keys = Vec::new();
|
|
const MAX: usize = 1 << 10;
|
|
|
|
for i in 0..MAX {
|
|
let key = ut.new_key(());
|
|
keys.push(key);
|
|
|
|
if i >= 2 {
|
|
ut.union(key, keys[i - 2]);
|
|
}
|
|
}
|
|
|
|
for i in 1..MAX {
|
|
assert!(!ut.unioned(keys[i - 1], keys[i]));
|
|
}
|
|
|
|
for i in 2..MAX {
|
|
assert!(ut.unioned(keys[i - 2], keys[i]));
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
|
struct IntKey(u32);
|
|
|
|
impl UnifyKey for IntKey {
|
|
type Value = Option<i32>;
|
|
fn index(&self) -> u32 {
|
|
self.0
|
|
}
|
|
fn from_index(u: u32) -> IntKey {
|
|
IntKey(u)
|
|
}
|
|
fn tag(_: Option<IntKey>) -> &'static str {
|
|
"IntKey"
|
|
}
|
|
}
|
|
|
|
/// Test unifying a key whose value is `Some(_)` with a key whose value is `None`.
|
|
/// Afterwards both should be `Some(_)`.
|
|
#[test]
|
|
fn unify_key_Some_key_None() {
|
|
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
|
|
let k1 = ut.new_key(Some(22));
|
|
let k2 = ut.new_key(None);
|
|
assert!(ut.unify_var_var(k1, k2).is_ok());
|
|
assert_eq!(ut.probe(k2), Some(22));
|
|
assert_eq!(ut.probe(k1), Some(22));
|
|
}
|
|
|
|
/// Test unifying a key whose value is `None` with a key whose value is `Some(_)`.
|
|
/// Afterwards both should be `Some(_)`.
|
|
#[test]
|
|
fn unify_key_None_key_Some() {
|
|
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
|
|
let k1 = ut.new_key(Some(22));
|
|
let k2 = ut.new_key(None);
|
|
assert!(ut.unify_var_var(k2, k1).is_ok());
|
|
assert_eq!(ut.probe(k2), Some(22));
|
|
assert_eq!(ut.probe(k1), Some(22));
|
|
}
|
|
|
|
/// Test unifying a key whose value is `Some(x)` with a key whose value is `Some(y)`.
|
|
/// This should yield an error.
|
|
#[test]
|
|
fn unify_key_Some_x_key_Some_y() {
|
|
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
|
|
let k1 = ut.new_key(Some(22));
|
|
let k2 = ut.new_key(Some(23));
|
|
assert_eq!(ut.unify_var_var(k1, k2), Err((22, 23)));
|
|
assert_eq!(ut.unify_var_var(k2, k1), Err((23, 22)));
|
|
assert_eq!(ut.probe(k1), Some(22));
|
|
assert_eq!(ut.probe(k2), Some(23));
|
|
}
|
|
|
|
/// Test unifying a key whose value is `Some(x)` with a key whose value is `Some(x)`.
|
|
/// This should be ok.
|
|
#[test]
|
|
fn unify_key_Some_x_key_Some_x() {
|
|
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
|
|
let k1 = ut.new_key(Some(22));
|
|
let k2 = ut.new_key(Some(22));
|
|
assert!(ut.unify_var_var(k1, k2).is_ok());
|
|
assert_eq!(ut.probe(k1), Some(22));
|
|
assert_eq!(ut.probe(k2), Some(22));
|
|
}
|
|
|
|
/// Test unifying a key whose value is `None` with a value is `x`.
|
|
/// Afterwards key should be `x`.
|
|
#[test]
|
|
fn unify_key_None_val() {
|
|
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
|
|
let k1 = ut.new_key(None);
|
|
assert!(ut.unify_var_value(k1, 22).is_ok());
|
|
assert_eq!(ut.probe(k1), Some(22));
|
|
}
|
|
|
|
/// Test unifying a key whose value is `Some(x)` with the value `y`.
|
|
/// This should yield an error.
|
|
#[test]
|
|
fn unify_key_Some_x_val_y() {
|
|
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
|
|
let k1 = ut.new_key(Some(22));
|
|
assert_eq!(ut.unify_var_value(k1, 23), Err((22, 23)));
|
|
assert_eq!(ut.probe(k1), Some(22));
|
|
}
|
|
|
|
/// Test unifying a key whose value is `Some(x)` with the value `x`.
|
|
/// This should be ok.
|
|
#[test]
|
|
fn unify_key_Some_x_val_x() {
|
|
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
|
|
let k1 = ut.new_key(Some(22));
|
|
assert!(ut.unify_var_value(k1, 22).is_ok());
|
|
assert_eq!(ut.probe(k1), Some(22));
|
|
}
|