# SqrtSpace SpaceTime for .NET [![NuGet](https://img.shields.io/nuget/v/SqrtSpace.SpaceTime.Core.svg)](https://www.nuget.org/packages/SqrtSpace.SpaceTime.Core/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) Memory-efficient algorithms and data structures for .NET using Williams' √n space-time tradeoffs. Reduce memory usage by 90-99% with minimal performance impact. **Paper Repository**: [git.marketally.com/sqrtspace/sqrtspace-paper](https://git.marketally.com/sqrtspace/sqrtspace-paper) ## Quick Start ```bash # Core functionality dotnet add package SqrtSpace.SpaceTime.Core # LINQ extensions dotnet add package SqrtSpace.SpaceTime.Linq # Adaptive collections dotnet add package SqrtSpace.SpaceTime.Collections # Entity Framework Core integration dotnet add package SqrtSpace.SpaceTime.EntityFramework # ASP.NET Core middleware dotnet add package SqrtSpace.SpaceTime.AspNetCore # Roslyn analyzers dotnet add package SqrtSpace.SpaceTime.Analyzers # Additional packages dotnet add package SqrtSpace.SpaceTime.Caching dotnet add package SqrtSpace.SpaceTime.Distributed dotnet add package SqrtSpace.SpaceTime.Diagnostics dotnet add package SqrtSpace.SpaceTime.Scheduling dotnet add package SqrtSpace.SpaceTime.Pipeline dotnet add package SqrtSpace.SpaceTime.Configuration dotnet add package SqrtSpace.SpaceTime.Serialization dotnet add package SqrtSpace.SpaceTime.MemoryManagement ``` ## What's Included ### 1. Core Library Foundation for all SpaceTime optimizations: ```csharp using SqrtSpace.SpaceTime.Core; // Calculate optimal buffer sizes int bufferSize = SpaceTimeCalculator.CalculateSqrtInterval(dataSize); // Get memory hierarchy information var hierarchy = MemoryHierarchy.GetCurrent(); Console.WriteLine($"L1 Cache: {hierarchy.L1CacheSize:N0} bytes"); Console.WriteLine($"L2 Cache: {hierarchy.L2CacheSize:N0} bytes"); Console.WriteLine($"Available RAM: {hierarchy.AvailableMemory:N0} bytes"); // Use external storage for large data using var storage = new ExternalStorage("data.tmp"); await storage.AppendAsync(records); ``` ### 2. Memory-Aware LINQ Extensions Transform memory-hungry LINQ operations: ```csharp using SqrtSpace.SpaceTime.Linq; // Standard LINQ - loads all 10M items into memory var sorted = millionItems .OrderBy(x => x.Date) .ToList(); // 800MB memory // SpaceTime LINQ - uses √n memory var sorted = millionItems .OrderByExternal(x => x.Date) .ToList(); // 25MB memory (97% less!) // Process in optimal batches await foreach (var batch in largeQuery.BatchBySqrtNAsync()) { await ProcessBatch(batch); } // External joins for large datasets var results = customers .JoinExternal(orders, c => c.Id, o => o.CustomerId, (c, o) => new { Customer = c, Order = o }) .ToList(); ``` ### 3. Adaptive Collections Collections that automatically switch implementations based on size: ```csharp using SqrtSpace.SpaceTime.Collections; // Automatically adapts: Array → Dictionary → B-Tree → External storage var adaptiveMap = new AdaptiveDictionary(); // Starts as array (< 16 items) adaptiveMap["user1"] = customer1; // Switches to Dictionary (< 10K items) for (int i = 0; i < 5000; i++) adaptiveMap[$"user{i}"] = customers[i]; // Switches to B-Tree (< 1M items) // Then to external storage (> 1M items) with √n memory // Adaptive lists with external sorting var list = new AdaptiveList(); list.AddRange(millionOrders); list.Sort(); // Automatically uses external sort if needed ``` ### 4. Entity Framework Core Optimizations Optimize EF Core for large datasets: ```csharp services.AddDbContext(options => { options.UseSqlServer(connectionString) .UseSpaceTimeOptimizer(opt => { opt.EnableSqrtNChangeTracking = true; opt.BufferPoolStrategy = BufferPoolStrategy.SqrtN; opt.EnableQueryCheckpointing = true; }); }); // Query with √n memory usage var results = await dbContext.Orders .Where(o => o.Status == "Pending") .ToListWithSqrtNMemoryAsync(); // Process in optimal batches await foreach (var batch in dbContext.Customers.BatchBySqrtNAsync()) { await ProcessCustomerBatch(batch); } // Optimized change tracking using (dbContext.BeginSqrtNTracking()) { // Make changes to thousands of entities await dbContext.BulkUpdateAsync(entities); } ``` ### 5. ASP.NET Core Streaming Stream large responses efficiently: ```csharp [HttpGet("large-dataset")] [SpaceTimeStreaming(ChunkStrategy = ChunkStrategy.SqrtN)] public async IAsyncEnumerable GetLargeDataset() { // Automatically chunks response using √n sizing await foreach (var item in repository.GetAllAsync()) { yield return item; } } // In Program.cs builder.Services.AddSpaceTime(options => { options.EnableCheckpointing = true; options.EnableStreaming = true; options.DefaultChunkSize = SpaceTimeDefaults.SqrtN; }); app.UseSpaceTime(); app.UseSpaceTimeEndpoints(); ``` ### 6. Memory-Aware Caching Intelligent caching with hot/cold storage: ```csharp using SqrtSpace.SpaceTime.Caching; // Configure caching services.AddSpaceTimeCaching(options => { options.MaxHotMemory = 100 * 1024 * 1024; // 100MB hot cache options.EnableColdStorage = true; options.ColdStoragePath = "/tmp/cache"; options.EvictionStrategy = EvictionStrategy.SqrtN; }); // Use the cache public class ProductService { private readonly ISpaceTimeCache _cache; public async Task GetProductAsync(string id) { return await _cache.GetOrAddAsync(id, async () => { // Expensive database query return await _repository.GetProductAsync(id); }); } } ``` ### 7. Distributed Processing Coordinate work across multiple nodes: ```csharp using SqrtSpace.SpaceTime.Distributed; // Configure distributed coordinator services.AddSpaceTimeDistributed(options => { options.NodeId = Environment.MachineName; options.CoordinationEndpoint = "redis://coordinator:6379"; }); // Use distributed processing public class DataProcessor { private readonly ISpaceTimeCoordinator _coordinator; public async Task ProcessLargeDatasetAsync(string datasetId) { // Get optimal partition for this node var partition = await _coordinator.RequestPartitionAsync( datasetId, estimatedSize: 10_000_000); // Process only this node's portion await foreach (var item in GetPartitionData(partition)) { await ProcessItem(item); await _coordinator.ReportProgressAsync(partition.Id, 1); } } } ``` ### 8. Diagnostics and Monitoring Comprehensive diagnostics with OpenTelemetry: ```csharp using SqrtSpace.SpaceTime.Diagnostics; // Configure diagnostics services.AddSpaceTimeDiagnostics(options => { options.EnableMetrics = true; options.EnableTracing = true; options.EnableMemoryTracking = true; }); // Monitor operations public class ImportService { private readonly ISpaceTimeDiagnostics _diagnostics; public async Task ImportDataAsync(string filePath) { using var operation = _diagnostics.StartOperation( "DataImport", OperationType.BatchProcessing); operation.SetTag("file.path", filePath); operation.SetTag("file.size", new FileInfo(filePath).Length); try { await ProcessFile(filePath); operation.RecordSuccess(); } catch (Exception ex) { operation.RecordError(ex); throw; } } } ``` ### 9. Memory-Aware Task Scheduling Schedule tasks based on memory availability: ```csharp using SqrtSpace.SpaceTime.Scheduling; // Configure scheduler services.AddSpaceTimeScheduling(options => { options.MaxMemoryPerTask = 50 * 1024 * 1024; // 50MB per task options.EnableMemoryThrottling = true; }); // Schedule memory-intensive tasks public class BatchProcessor { private readonly ISpaceTimeTaskScheduler _scheduler; public async Task ProcessBatchesAsync(IEnumerable batches) { var tasks = batches.Select(batch => _scheduler.ScheduleAsync(async () => { await ProcessBatch(batch); }, estimatedMemory: batch.EstimatedMemoryUsage, priority: TaskPriority.Normal)); await Task.WhenAll(tasks); } } ``` ### 10. Data Pipeline Framework Build memory-efficient data pipelines: ```csharp using SqrtSpace.SpaceTime.Pipeline; // Build a pipeline var pipeline = pipelineFactory.CreatePipeline("ImportPipeline") .AddTransform("Parse", async (input, ct) => await ParseData(input)) .AddBatch("Validate", async (batch, ct) => await ValidateBatch(batch)) .AddFilter("FilterInvalid", data => data.IsValid) .AddCheckpoint("SaveProgress") .AddParallel("Enrich", async (data, ct) => await EnrichData(data), maxConcurrency: 4) .Build(); // Execute pipeline var result = await pipeline.ExecuteAsync(inputData); ``` ### 11. Configuration and Policy System Centralized configuration management: ```csharp using SqrtSpace.SpaceTime.Configuration; // Configure SpaceTime services.AddSpaceTimeConfiguration(configuration); // Define policies services.Configure(options => { options.Memory.MaxMemory = 1_073_741_824; // 1GB options.Memory.ExternalAlgorithmThreshold = 0.7; // Switch at 70% options.Algorithms.Policies["Sort"] = new AlgorithmPolicy { PreferExternal = true, SizeThreshold = 1_000_000 }; }); // Use policy engine public class DataService { private readonly IPolicyEngine _policyEngine; public async Task DetermineStrategyAsync(long dataSize) { var context = new PolicyContext { OperationType = "DataProcessing", DataSize = dataSize, AvailableMemory = GC.GetTotalMemory(false) }; var result = await _policyEngine.EvaluateAsync(context); return result.ShouldProceed ? ProcessingStrategy.Continue : ProcessingStrategy.Defer; } } ``` ### 12. Serialization Optimizers Memory-efficient serialization with streaming: ```csharp using SqrtSpace.SpaceTime.Serialization; // Configure serialization services.AddSpaceTimeSerialization(builder => { builder.UseFormat(SerializationFormat.MessagePack) .ConfigureCompression(enable: true, level: 6) .ConfigureMemoryLimits(100 * 1024 * 1024); // 100MB }); // Stream large collections public class ExportService { private readonly StreamingSerializer _serializer; public async Task ExportCustomersAsync(string filePath) { await _serializer.SerializeToFileAsync( GetCustomersAsync(), filePath, options: new SerializationOptions { EnableCheckpointing = true, BufferSize = 0 // Auto √n sizing }, progress: new Progress(p => { Console.WriteLine($"Exported {p.ItemsProcessed:N0} items"); })); } } ``` ### 13. Memory Pressure Handling Automatic response to memory pressure: ```csharp using SqrtSpace.SpaceTime.MemoryManagement; // Configure memory management services.AddSpaceTimeMemoryManagement(options => { options.EnableAutomaticHandling = true; options.CheckInterval = TimeSpan.FromSeconds(5); }); // Add custom handler services.AddMemoryPressureHandler(); // Monitor memory pressure public class MemoryAwareService { private readonly IMemoryPressureMonitor _monitor; public MemoryAwareService(IMemoryPressureMonitor monitor) { _monitor = monitor; _monitor.PressureEvents.Subscribe(OnMemoryPressure); } private void OnMemoryPressure(MemoryPressureEvent e) { if (e.CurrentLevel >= MemoryPressureLevel.High) { // Reduce memory usage TrimCaches(); ForceGarbageCollection(); } } } ``` ### 14. Checkpointing for Fault Tolerance Add automatic checkpointing to long-running operations: ```csharp [EnableCheckpoint(Strategy = CheckpointStrategy.SqrtN)] public async Task ImportLargeDataset(string filePath) { var checkpoint = HttpContext.Features.Get(); var results = new List(); await foreach (var record in ReadRecordsAsync(filePath)) { var processed = await ProcessRecord(record); results.Add(processed); // Automatically checkpoints every √n iterations if (checkpoint.ShouldCheckpoint()) { await checkpoint.SaveStateAsync(results); } } return new ImportResult(results); } ``` ### 15. Roslyn Analyzers Get compile-time suggestions for memory optimizations: ```csharp // Analyzer warning: ST001 - Large allocation detected var allOrders = await dbContext.Orders.ToListAsync(); // Warning // Quick fix applied: var allOrders = await dbContext.Orders.ToListWithSqrtNMemoryAsync(); // Fixed // Analyzer warning: ST002 - Inefficient LINQ operation var sorted = items.OrderBy(x => x.Id).ToList(); // Warning // Quick fix applied: var sorted = items.OrderByExternal(x => x.Id).ToList(); // Fixed ``` ## Real-World Performance Benchmarks on .NET 8.0: | Operation | Standard | SpaceTime | Memory Reduction | Time Overhead | |-----------|----------|-----------|------------------|---------------| | Sort 10M items | 800MB, 1.2s | 25MB, 1.8s | **97%** | 50% | | LINQ GroupBy 1M | 120MB, 0.8s | 3.5MB, 1.1s | **97%** | 38% | | EF Core Query 100K | 200MB, 2.1s | 14MB, 2.4s | **93%** | 14% | | Stream 1GB JSON | 1GB, 5s | 32MB, 5.5s | **97%** | 10% | | Cache 1M items | 400MB | 35MB hot + disk | **91%** | 5% | | Distributed sort | N/A | 50MB per node | **95%** | 20% | ## When to Use ### Perfect for: - Large dataset processing (> 100K items) - Memory-constrained environments (containers, serverless) - Reducing cloud costs (smaller instances) - Import/export operations - Batch processing - Real-time systems with predictable memory - Distributed data processing - Long-running operations requiring fault tolerance ### Not ideal for: - Small datasets (< 1000 items) - Ultra-low latency requirements (< 10ms) - Simple CRUD operations - CPU-bound calculations without memory pressure ## Configuration ### Global Configuration ```csharp // In Program.cs services.Configure(config => { // Memory settings config.Memory.MaxMemory = 1_073_741_824; // 1GB config.Memory.BufferSizeStrategy = BufferSizeStrategy.Sqrt; // Algorithm selection config.Algorithms.EnableAdaptiveSelection = true; config.Algorithms.MinExternalAlgorithmSize = 10_000_000; // 10MB // Performance tuning config.Performance.EnableParallelism = true; config.Performance.MaxDegreeOfParallelism = Environment.ProcessorCount; // Storage settings config.Storage.DefaultStorageDirectory = "/tmp/spacetime"; config.Storage.EnableCompression = true; // Features config.Features.EnableCheckpointing = true; config.Features.EnableAdaptiveDataStructures = true; }); ``` ### Environment Variables Configure via environment variables: ```bash # Memory settings SPACETIME_MAX_MEMORY=1073741824 SPACETIME_MEMORY_THRESHOLD=0.7 # Performance settings SPACETIME_ENABLE_PARALLEL=true SPACETIME_MAX_PARALLELISM=8 # Storage settings SPACETIME_STORAGE_DIR=/tmp/spacetime SPACETIME_ENABLE_COMPRESSION=true ``` ### Per-Operation Configuration ```csharp // Custom buffer size var sorted = data.OrderByExternal(x => x.Id, bufferSize: 10000); // Custom checkpoint interval var checkpoint = new CheckpointManager(strategy: CheckpointStrategy.Linear); // Force specific implementation var list = new AdaptiveList(strategy: AdaptiveStrategy.ForceExternal); // Configure pipeline var pipeline = builder.Configure(config => { config.ExpectedItemCount = 1_000_000; config.EnableCheckpointing = true; config.DefaultTimeout = TimeSpan.FromMinutes(30); }); ``` ## How It Works Based on Williams' theoretical result that TIME[t] ⊆ SPACE[√(t log t)]: 1. **Memory Reduction**: Use O(√n) memory instead of O(n) 2. **External Storage**: Spill to disk when memory limit reached 3. **Optimal Chunking**: Process data in √n-sized chunks 4. **Adaptive Strategies**: Switch algorithms based on data size 5. **Distributed Coordination**: Split work across nodes 6. **Memory Pressure Handling**: Automatic response to low memory ## Examples ### Processing Large CSV ```csharp [HttpPost("import-csv")] [EnableCheckpoint] public async Task ImportCsv(IFormFile file) { var pipeline = _pipelineFactory.CreatePipeline("CsvImport") .AddTransform("Parse", line => ParseCsvLine(line)) .AddBatch("Validate", async batch => await ValidateRecords(batch)) .AddCheckpoint("Progress") .AddTransform("Save", async record => await SaveRecord(record)) .Build(); var lines = ReadCsvLines(file.OpenReadStream()); var result = await pipeline.ExecuteAsync(lines); return Ok(new { ProcessedCount = result.ProcessedCount }); } ``` ### Optimized Data Export ```csharp [HttpGet("export")] [SpaceTimeStreaming] public async IAsyncEnumerable ExportCustomers() { // Process customers in √n batches with progress var totalCount = await dbContext.Customers.CountAsync(); var batchSize = SpaceTimeCalculator.CalculateSqrtInterval(totalCount); await foreach (var batch in dbContext.Customers .OrderBy(c => c.Id) .BatchAsync(batchSize)) { foreach (var customer in batch) { yield return new CustomerExport { Id = customer.Id, Name = customer.Name, TotalOrders = await GetOrderCount(customer.Id) }; } } } ``` ### Memory-Aware Background Job ```csharp public class DataProcessingJob : IHostedService { private readonly ISpaceTimeTaskScheduler _scheduler; private readonly IMemoryPressureMonitor _memoryMonitor; public async Task ExecuteAsync(CancellationToken cancellationToken) { // Schedule based on memory availability await _scheduler.ScheduleAsync(async () => { if (_memoryMonitor.CurrentPressureLevel > MemoryPressureLevel.Medium) { // Use external algorithms await ProcessDataExternal(); } else { // Use in-memory algorithms await ProcessDataInMemory(); } }, estimatedMemory: 100 * 1024 * 1024, // 100MB priority: TaskPriority.Low); } } ``` ## Contributing We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md). ## License Apache 2.0 - See [LICENSE](LICENSE) for details. ## Links - [NuGet Packages](https://www.nuget.org/profiles/sqrtspace) - [Git Repository](https://git.marketally.com/sqrtspace/sqrtspace-dotnet) --- *Making theoretical computer science practical for .NET developers*