use yufmath::core::{
Expression, Number, MathConstant, BinaryOperator, UnaryOperator,
SharedExpression, CowExpression, MemoryManager, MemoryMonitor,
ExpressionBuilder, ExpressionFactory, ExpressionComparator
};
use num_bigint::BigInt;
use std::time::Duration;
#[test]
fn test_shared_expression_basic() {
let expr = Expression::Number(Number::Integer(BigInt::from(42)));
let shared = SharedExpression::new(expr.clone());
assert_eq!(shared.as_ref(), &expr);
assert_eq!(shared.ref_count(), 1);
assert!(shared.is_unique());
}
#[test]
fn test_shared_expression_cloning() {
let expr = Expression::Number(Number::Integer(BigInt::from(42)));
let shared1 = SharedExpression::new(expr.clone());
let shared2 = shared1.clone_shared();
assert_eq!(shared1.ref_count(), 2);
assert_eq!(shared2.ref_count(), 2);
assert!(!shared1.is_unique());
assert!(!shared2.is_unique());
assert_eq!(shared1, shared2);
}
#[test]
fn test_cow_write_on_copy() {
let expr = Expression::Number(Number::Integer(BigInt::from(42)));
let mut shared = SharedExpression::new(expr.clone());
let shared_clone = shared.clone_shared();
assert_eq!(shared.ref_count(), 2);
let mutable_ref = shared.make_mut();
*mutable_ref = Expression::Number(Number::Integer(BigInt::from(43)));
assert_eq!(shared.ref_count(), 1);
assert_eq!(shared_clone.ref_count(), 1);
assert_ne!(shared, shared_clone);
}
#[test]
fn test_expression_hashing_consistency() {
let expr1 = Expression::Number(Number::Integer(BigInt::from(42)));
let expr2 = Expression::Number(Number::Integer(BigInt::from(42)));
let expr3 = Expression::Number(Number::Integer(BigInt::from(43)));
let hash1 = yufmath::core::memory::calculate_expression_hash(&expr1);
let hash2 = yufmath::core::memory::calculate_expression_hash(&expr2);
let hash3 = yufmath::core::memory::calculate_expression_hash(&expr3);
assert_eq!(hash1, hash2);
assert_ne!(hash1, hash3);
}
#[test]
fn test_complex_expression_hashing() {
let x = Expression::Variable("x".to_string());
let two = Expression::Number(Number::Integer(BigInt::from(2)));
let expr1 = Expression::BinaryOp {
op: BinaryOperator::Multiply,
left: Box::new(two.clone()),
right: Box::new(x.clone()),
};
let expr2 = Expression::BinaryOp {
op: BinaryOperator::Multiply,
left: Box::new(two.clone()),
right: Box::new(x.clone()),
};
let hash1 = yufmath::core::memory::calculate_expression_hash(&expr1);
let hash2 = yufmath::core::memory::calculate_expression_hash(&expr2);
assert_eq!(hash1, hash2);
}
#[test]
fn test_memory_manager_sharing() {
let mut manager = MemoryManager::new();
let expr1 = Expression::Number(Number::Integer(BigInt::from(42)));
let expr2 = Expression::Number(Number::Integer(BigInt::from(42)));
let shared1 = manager.create_shared(expr1);
let shared2 = manager.create_shared(expr2);
let stats = manager.get_stats();
assert!(stats.cache_hits > 0 || stats.cache_misses > 0);
}
#[test]
fn test_memory_manager_cleanup() {
let mut manager = MemoryManager::new();
let mut shared_expressions = Vec::new();
for i in 0..100 {
let expr = Expression::Number(Number::Integer(BigInt::from(i)));
let shared = manager.create_shared(expr);
shared_expressions.push(shared);
}
let stats_before = manager.get_stats().clone();
shared_expressions.truncate(50);
manager.cleanup();
let stats_after = manager.get_stats().clone();
println!("清理前: 共享表达式 {}", stats_before.shared_expressions);
println!("清理后: 共享表达式 {}", stats_after.shared_expressions);
}
#[test]
fn test_expression_comparator() {
let mut comparator = ExpressionComparator::new();
let expr1 = Expression::Number(Number::Integer(BigInt::from(42)));
let expr2 = Expression::Number(Number::Integer(BigInt::from(42)));
let expr3 = Expression::Number(Number::Integer(BigInt::from(43)));
assert!(comparator.fast_eq(&expr1, &expr2));
assert!(!comparator.fast_eq(&expr1, &expr3));
assert!(comparator.fast_eq(&expr1, &expr1));
}
#[test]
fn test_cow_expression() {
let expr = Expression::Number(Number::Integer(BigInt::from(42)));
let mut cow = CowExpression::new(expr.clone());
assert!(!cow.is_modified());
assert_eq!(cow.ref_count(), 1);
let mutable_ref = cow.as_mut();
*mutable_ref = Expression::Number(Number::Integer(BigInt::from(43)));
assert!(cow.is_modified());
assert_ne!(cow.as_ref(), &expr);
}
#[test]
fn test_memory_monitor() {
let mut monitor = MemoryMonitor::new();
let manager = monitor.manager();
for i in 0..50 {
let expr = Expression::Number(Number::Integer(BigInt::from(i)));
let _shared = manager.create_shared(expr);
}
let stats = monitor.stats();
assert!(stats.active_expressions > 0);
monitor.cleanup();
}
#[test]
fn test_expression_builder_optimization() {
let mut builder = ExpressionBuilder::new();
let x = builder.variable("x");
let zero = builder.number(Number::integer(0));
let one = builder.number(Number::integer(1));
let x_plus_zero = builder.add(x.clone_shared(), zero.clone_shared());
assert_eq!(x_plus_zero.as_ref(), x.as_ref());
let one_times_x = builder.multiply(one.clone_shared(), x.clone_shared());
assert_eq!(one_times_x.as_ref(), x.as_ref());
let x_minus_x = builder.subtract(x.clone_shared(), x.clone_shared());
assert_eq!(x_minus_x.as_ref(), zero.as_ref());
}
#[test]
fn test_expression_builder_caching() {
let mut builder = ExpressionBuilder::new();
let x1 = builder.variable("x");
let x2 = builder.variable("x");
assert_eq!(x1, x2);
let one1 = builder.number(Number::integer(1));
let one2 = builder.number(Number::integer(1));
assert_eq!(one1, one2);
}
#[test]
fn test_expression_factory() {
let mut factory = ExpressionFactory::new();
let x = factory.var("x");
let two = factory.int(2);
let pi = factory.pi();
let sum = factory.add(x, pi);
let product = factory.mul(two, sum);
match product.as_ref() {
Expression::BinaryOp { op: BinaryOperator::Multiply, left, right } => {
assert!(matches!(left.as_ref(), Expression::Number(Number::Integer(_))));
assert!(matches!(right.as_ref(), Expression::BinaryOp { op: BinaryOperator::Add, .. }));
}
_ => panic!("期望乘法表达式"),
}
}
#[test]
fn test_nested_expression_sharing() {
let mut builder = ExpressionBuilder::new();
let x = builder.variable("x");
let y = builder.variable("y");
let sum1 = builder.add(x.clone_shared(), y.clone_shared());
let sum2 = builder.add(x.clone_shared(), y.clone_shared());
let product = builder.multiply(sum1.clone_shared(), sum2.clone_shared());
assert_eq!(sum1, sum2);
match product.as_ref() {
Expression::BinaryOp { op: BinaryOperator::Multiply, left, right } => {
println!("产品表达式: {:?}", product.as_ref());
}
_ => {}
}
}
#[test]
fn test_memory_usage_estimation() {
let mut manager = MemoryManager::new();
let expressions = vec![
Expression::Number(Number::Integer(BigInt::from(42))),
Expression::Variable("x".to_string()),
Expression::Constant(MathConstant::Pi),
Expression::BinaryOp {
op: BinaryOperator::Add,
left: Box::new(Expression::Variable("x".to_string())),
right: Box::new(Expression::Number(Number::Integer(BigInt::from(1)))),
},
];
for expr in expressions {
let _shared = manager.create_shared(expr);
}
let stats = manager.get_stats();
assert!(stats.estimated_memory_usage > 0);
println!("估计内存使用: {} 字节", stats.estimated_memory_usage);
}
#[test]
fn test_large_expression_performance() {
let mut builder = ExpressionBuilder::new();
let start = std::time::Instant::now();
let mut expr = builder.variable("x");
for i in 1..=100 {
let num = builder.number(Number::integer(i));
expr = builder.add(expr, num);
}
let duration = start.elapsed();
println!("创建100项加法表达式用时: {:?}", duration);
let stats = builder.memory_stats();
println!("内存统计: {:?}", stats);
assert!(duration < Duration::from_millis(100));
}
#[test]
fn test_expression_equality_optimization() {
let mut comparator = ExpressionComparator::new();
let create_expr = || {
Expression::BinaryOp {
op: BinaryOperator::Add,
left: Box::new(Expression::BinaryOp {
op: BinaryOperator::Multiply,
left: Box::new(Expression::Variable("x".to_string())),
right: Box::new(Expression::Number(Number::Integer(BigInt::from(2)))),
}),
right: Box::new(Expression::Number(Number::Integer(BigInt::from(1)))),
}
};
let expr1 = create_expr();
let expr2 = create_expr();
let start = std::time::Instant::now();
let is_equal = comparator.fast_eq(&expr1, &expr2);
let duration = start.elapsed();
assert!(is_equal);
println!("复杂表达式比较用时: {:?}", duration);
let start = std::time::Instant::now();
let is_equal = comparator.fast_eq(&expr1, &expr2);
let duration2 = start.elapsed();
assert!(is_equal);
println!("缓存哈希比较用时: {:?}", duration2);
assert!(duration2 <= duration);
}
#[test]
fn test_memory_config_effects() {
use yufmath::core::memory::MemoryConfig;
let mut config = MemoryConfig::default();
config.enable_sharing = false;
let mut manager = MemoryManager::with_config(config);
let expr1 = Expression::Number(Number::Integer(BigInt::from(42)));
let expr2 = Expression::Number(Number::Integer(BigInt::from(42)));
let shared1 = manager.create_shared(expr1);
let shared2 = manager.create_shared(expr2);
let stats = manager.get_stats();
println!("禁用共享时的统计: {:?}", stats);
}
#[test]
fn test_cow_with_multiple_references() {
let expr = Expression::Number(Number::Integer(BigInt::from(42)));
let shared = SharedExpression::new(expr.clone());
let mut cow1 = CowExpression::from_shared(shared.clone_shared());
let mut cow2 = CowExpression::from_shared(shared.clone_shared());
assert_eq!(cow1.ref_count(), 3); assert_eq!(cow2.ref_count(), 3);
let mutable_ref = cow1.as_mut();
*mutable_ref = Expression::Number(Number::Integer(BigInt::from(43)));
assert!(cow1.is_modified());
assert!(!cow2.is_modified());
assert_eq!(cow1.ref_count(), 1); assert_eq!(cow2.ref_count(), 2); }