use s_zip::{AsyncStreamingZipWriter, Result};
use tempfile::NamedTempFile;
#[tokio::main]
async fn main() -> Result<()> {
println!("đ s-zip Optimization Examples\n");
example_adaptive_buffers().await?;
example_no_hints().await?;
#[cfg(feature = "cloud-s3")]
{
println!("\nđĄ For S3 concurrent uploads example, see examples/cloud_s3.rs");
println!(" Use .max_concurrent_uploads(8) for 3-5x faster uploads!");
}
Ok(())
}
async fn example_adaptive_buffers() -> Result<()> {
println!("đ Example 1: Adaptive Buffer Sizing with Size Hints");
println!(" â
Optimizes memory allocation based on file sizes");
println!(" â
15-25% faster for large files (>1MB)\n");
let temp = NamedTempFile::new()?;
let mut writer = AsyncStreamingZipWriter::new(temp.path()).await?;
let small_data = b"This is a small file";
writer
.start_entry_with_hint("small.txt", Some(small_data.len() as u64))
.await?;
writer.write_data(small_data).await?;
println!(" â Small file (20 bytes): 8KB buffer, 256KB threshold");
let medium_data = vec![b'M'; 500_000]; writer
.start_entry_with_hint("medium.bin", Some(medium_data.len() as u64))
.await?;
writer.write_data(&medium_data).await?;
println!(" â Medium file (500KB): 128KB buffer, 2MB threshold");
let large_data = vec![b'L'; 5_000_000]; writer
.start_entry_with_hint("large.bin", Some(large_data.len() as u64))
.await?;
writer.write_data(&large_data).await?;
println!(" â Large file (5MB): 256KB buffer, 4MB threshold");
let huge_data = vec![b'H'; 50_000_000]; writer
.start_entry_with_hint("huge.bin", Some(huge_data.len() as u64))
.await?;
writer.write_data(&huge_data).await?;
println!(" â Very large file (50MB): 512KB buffer, 8MB threshold");
writer.finish().await?;
println!("\n đ Performance Impact:");
println!(" âĸ Small files: Minimal overhead, optimal memory usage");
println!(" âĸ Large files: +15-25% throughput improvement");
println!(" âĸ Memory usage: Still constant 2-5MB regardless of size!\n");
Ok(())
}
async fn example_no_hints() -> Result<()> {
println!("đ Example 2: Usage without Size Hints (Backward Compatible)");
println!(" â
Uses smart defaults (512KB buffer, 8MB threshold)");
println!(" â
Zero breaking changes - existing code still works!\n");
let temp = NamedTempFile::new()?;
let mut writer = AsyncStreamingZipWriter::new(temp.path()).await?;
writer.start_entry("file1.txt").await?;
writer.write_data(b"Hello, World!").await?;
writer.start_entry("file2.txt").await?;
writer.write_data(b"More data here...").await?;
writer.finish().await?;
println!(" â Created ZIP with 2 files");
println!(" âšī¸ Add .start_entry_with_hint() for optimal performance\n");
Ok(())
}
#[cfg(feature = "cloud-s3")]
#[allow(dead_code)]
async fn example_s3_concurrent() -> Result<()> {
println!("âī¸ Example 3: S3 Concurrent Multipart Upload");
println!(" â
Upload 4-8 parts in parallel (configurable)");
println!(" â
3-5x faster than sequential uploads");
println!(" â
Automatic retry with exponential backoff\n");
println!(" Configuration example:");
println!(" ```rust");
println!(" let writer = S3ZipWriter::builder()");
println!(" .bucket(\"my-bucket\")");
println!(" .key(\"large-archive.zip\")");
println!(" .max_concurrent_uploads(8) // 8 parallel uploads!");
println!(" .part_size(10 * 1024 * 1024) // 10MB parts");
println!(" .build()");
println!(" .await?;");
println!(" ```\n");
println!(" đ Performance Impact:");
println!(" âĸ Default (4 concurrent): ~3x faster");
println!(" âĸ Aggressive (8 concurrent): ~5x faster");
println!(" âĸ Automatic retry on transient failures");
println!(" âĸ Exponential backoff (100ms â 200ms â 400ms)\n");
Ok(())
}
#[allow(dead_code)]
async fn example_performance_comparison() -> Result<()> {
use std::time::Instant;
println!("⥠Performance Comparison\n");
let data = vec![b'X'; 10_000_000];
let temp1 = NamedTempFile::new()?;
let start = Instant::now();
let mut writer1 = AsyncStreamingZipWriter::new(temp1.path()).await?;
writer1.start_entry("data.bin").await?;
writer1.write_data(&data).await?;
writer1.finish().await?;
let time_no_hint = start.elapsed();
let temp2 = NamedTempFile::new()?;
let start = Instant::now();
let mut writer2 = AsyncStreamingZipWriter::new(temp2.path()).await?;
writer2
.start_entry_with_hint("data.bin", Some(data.len() as u64))
.await?;
writer2.write_data(&data).await?;
writer2.finish().await?;
let time_with_hint = start.elapsed();
println!(" Results (10MB file):");
println!(" âĸ Without hint: {:?}", time_no_hint);
println!(" âĸ With hint: {:?}", time_with_hint);
println!(
" âĸ Improvement: {:.1}%\n",
((time_no_hint.as_secs_f64() - time_with_hint.as_secs_f64()) / time_no_hint.as_secs_f64()
* 100.0)
);
Ok(())
}
#[allow(dead_code)]
fn example_memory_usage() {
println!("đž Memory Usage (Constant Regardless of File Size)\n");
println!(" Configuration | Initial Cap | Flush Threshold | Total RAM");
println!(" -----------------------|-------------|-----------------|----------");
println!(" Tiny (<10KB) | 8KB | 256KB | ~2MB");
println!(" Small (<100KB) | 32KB | 512KB | ~3MB");
println!(" Medium (<1MB) | 128KB | 2MB | ~4MB");
println!(" Large (1-10MB) | 256KB | 4MB | ~5MB");
println!(" Very Large (>10MB) | 512KB | 8MB | ~6MB");
println!("\n â
Memory usage remains constant - perfect for containers!");
println!(" â
Larger files just flush more frequently\n");
}