use crate::error::Result;
use std::time::Instant;
pub mod compression;
pub mod memory_pool;
pub mod metrics;
pub mod parallel_generation;
pub mod resource_pool;
pub mod streaming_writer;
pub use compression::{CompressionStats, CompressionStrategy, ContentType, IntelligentCompressor};
pub use memory_pool::{MemoryPool, MemoryPoolStats, PooledBuffer};
pub use metrics::{Operation, OperationStats, PerformanceMetrics, PerformanceMonitor};
pub use parallel_generation::{PageProcessor, ParallelGenerationOptions, ParallelPageGenerator};
pub use resource_pool::{FontResource, ImageResource, PatternResource, ResourceKey, ResourcePool};
pub use streaming_writer::{StreamingOptions, StreamingPdfWriter, StreamingStats, WriteStrategy};
pub struct HighPerformanceDocument {
options: PerformanceOptions,
resource_pool: ResourcePool,
memory_pool: MemoryPool,
#[allow(dead_code)]
metrics: PerformanceMonitor,
pages: Vec<PerformancePage>,
}
#[derive(Debug, Clone)]
pub struct PerformancePage {
pub index: u32,
pub width: f64,
pub height: f64,
pub content_refs: Vec<ResourceKey>,
pub estimated_size: usize,
}
#[derive(Debug, Clone)]
pub struct PerformanceOptions {
pub parallel_generation: bool,
pub max_threads: usize,
pub resource_deduplication: bool,
pub streaming_writer: bool,
pub stream_buffer_size: usize,
pub intelligent_compression: bool,
pub memory_pooling: bool,
pub memory_pool_size: usize,
pub collect_metrics: bool,
}
impl Default for PerformanceOptions {
fn default() -> Self {
Self {
parallel_generation: true,
max_threads: num_cpus::get().min(8),
resource_deduplication: true,
streaming_writer: true,
stream_buffer_size: 1024 * 1024, intelligent_compression: true,
memory_pooling: true,
memory_pool_size: 16 * 1024 * 1024, collect_metrics: true,
}
}
}
impl PerformanceOptions {
pub fn max_speed() -> Self {
Self {
parallel_generation: true,
max_threads: num_cpus::get(),
resource_deduplication: true,
streaming_writer: false, stream_buffer_size: 4 * 1024 * 1024, intelligent_compression: false, memory_pooling: true,
memory_pool_size: 64 * 1024 * 1024, collect_metrics: false, }
}
pub fn min_memory() -> Self {
Self {
parallel_generation: false, max_threads: 2,
resource_deduplication: true,
streaming_writer: true,
stream_buffer_size: 64 * 1024, intelligent_compression: true,
memory_pooling: false, memory_pool_size: 0,
collect_metrics: false,
}
}
pub fn balanced() -> Self {
Self::default()
}
pub fn with_parallel_generation(mut self, enabled: bool) -> Self {
self.parallel_generation = enabled;
self
}
pub fn with_resource_deduplication(mut self, enabled: bool) -> Self {
self.resource_deduplication = enabled;
self
}
pub fn with_streaming_writer(mut self, enabled: bool) -> Self {
self.streaming_writer = enabled;
self
}
pub fn with_max_threads(mut self, threads: usize) -> Self {
self.max_threads = threads.max(1);
self
}
pub fn with_stream_buffer_size(mut self, size: usize) -> Self {
self.stream_buffer_size = size;
self
}
pub fn with_memory_pool_size(mut self, size: usize) -> Self {
self.memory_pool_size = size;
self
}
}
impl HighPerformanceDocument {
pub fn new(options: PerformanceOptions) -> Result<Self> {
let resource_pool = ResourcePool::new();
let memory_pool = if options.memory_pooling {
MemoryPool::new(options.memory_pool_size)
} else {
MemoryPool::disabled()
};
let metrics = if options.collect_metrics {
PerformanceMonitor::new()
} else {
PerformanceMonitor::disabled()
};
Ok(Self {
options,
resource_pool,
memory_pool,
metrics,
pages: Vec::new(),
})
}
pub fn add_page(&mut self, page: PerformancePage) -> Result<()> {
self.pages.push(page);
Ok(())
}
pub fn performance_stats(&self) -> PerformanceStats {
PerformanceStats {
total_pages: self.pages.len(),
resource_pool_stats: self.resource_pool.stats(),
memory_pool_stats: self.memory_pool.stats(),
compression_stats: CompressionStats::default(),
operation_stats: Vec::new(), }
}
pub fn save<P: AsRef<std::path::Path>>(&self, path: P) -> Result<()> {
let start = Instant::now();
if self.options.streaming_writer {
self.save_streaming(path)?;
} else {
self.save_buffered(path)?;
}
let duration = start.elapsed();
tracing::debug!(
"Performance: Saved {} pages in {:.2}ms",
self.pages.len(),
duration.as_secs_f64() * 1000.0
);
Ok(())
}
fn save_streaming<P: AsRef<std::path::Path>>(&self, _path: P) -> Result<()> {
Ok(())
}
fn save_buffered<P: AsRef<std::path::Path>>(&self, _path: P) -> Result<()> {
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct PerformanceStats {
pub total_pages: usize,
pub resource_pool_stats: resource_pool::ResourcePoolStats,
pub memory_pool_stats: MemoryPoolStats,
pub compression_stats: CompressionStats,
pub operation_stats: Vec<OperationStats>,
}
impl PerformanceStats {
pub fn performance_score(&self) -> f64 {
let mut score = 100.0;
let dedup_ratio = self.resource_pool_stats.deduplication_ratio();
if dedup_ratio < 0.3 {
score -= (0.3 - dedup_ratio) * 50.0;
}
let compression_ratio = self.compression_stats.compression_ratio();
if compression_ratio > 0.5 {
score += (compression_ratio - 0.5) * 20.0;
}
let memory_efficiency = self.memory_pool_stats.efficiency();
if memory_efficiency < 0.8 {
score -= (0.8 - memory_efficiency) * 30.0;
}
score.max(0.0).min(100.0)
}
pub fn summary(&self) -> String {
format!(
"Performance Summary:\n\
- Total Pages: {}\n\
- Resource Deduplication: {:.1}%\n\
- Compression Ratio: {:.1}%\n\
- Memory Pool Efficiency: {:.1}%\n\
- Overall Score: {:.1}/100",
self.total_pages,
self.resource_pool_stats.deduplication_ratio() * 100.0,
self.compression_stats.compression_ratio() * 100.0,
self.memory_pool_stats.efficiency() * 100.0,
self.performance_score()
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_performance_options_default() {
let options = PerformanceOptions::default();
assert!(options.parallel_generation);
assert!(options.resource_deduplication);
assert!(options.streaming_writer);
assert!(options.intelligent_compression);
assert!(options.memory_pooling);
}
#[test]
fn test_performance_options_max_speed() {
let options = PerformanceOptions::max_speed();
assert!(options.parallel_generation);
assert!(!options.streaming_writer); assert!(!options.intelligent_compression); assert!(!options.collect_metrics); }
#[test]
fn test_performance_options_min_memory() {
let options = PerformanceOptions::min_memory();
assert!(!options.parallel_generation);
assert!(options.streaming_writer);
assert!(options.intelligent_compression);
assert!(!options.memory_pooling);
}
#[test]
fn test_performance_options_builder() {
let options = PerformanceOptions::default()
.with_parallel_generation(false)
.with_max_threads(4)
.with_stream_buffer_size(512 * 1024);
assert!(!options.parallel_generation);
assert_eq!(options.max_threads, 4);
assert_eq!(options.stream_buffer_size, 512 * 1024);
}
#[test]
fn test_high_performance_document_creation() {
let options = PerformanceOptions::default();
let doc = HighPerformanceDocument::new(options);
assert!(doc.is_ok());
}
#[test]
fn test_performance_page() {
let page = PerformancePage {
index: 0,
width: 595.0,
height: 842.0,
content_refs: vec![],
estimated_size: 1024,
};
assert_eq!(page.index, 0);
assert_eq!(page.width, 595.0);
assert_eq!(page.height, 842.0);
assert_eq!(page.estimated_size, 1024);
}
#[test]
fn test_add_page() {
let options = PerformanceOptions::default();
let mut doc = HighPerformanceDocument::new(options).unwrap();
let page = PerformancePage {
index: 0,
width: 595.0,
height: 842.0,
content_refs: vec![],
estimated_size: 1024,
};
let result = doc.add_page(page);
assert!(result.is_ok());
assert_eq!(doc.pages.len(), 1);
}
}