---
title: "Branch Garbage Collection - Quick Reference"
---

# Branch Garbage Collection - Quick Reference

**Feature**: Automatic garbage collection for deleted branches
**File**: `src/storage/branch.rs`

## Quick Start

### Basic Usage (Default Configuration)

```rust
use heliosdb_nano::storage::{BranchManager, BranchOptions};

// Create manager with default GC settings
let manager = BranchManager::new(db, timestamp)?;

// Create and drop a branch
manager.create_branch("feature", Some("main"), 100, BranchOptions::default())?;
manager.drop_branch("feature", false)?; // Automatic GC triggered
```

**Default Settings**:
- Mode: Deferred
- Retention: 300 seconds (5 minutes)
- Auto GC: Enabled

### Custom Configuration

```rust
use heliosdb_nano::storage::{BranchGcConfig, BranchGcMode};

// Immediate deletion (testing/development)
let gc_config = BranchGcConfig {
    min_retention_seconds: 0,
    auto_gc_enabled: true,
    gc_mode: BranchGcMode::Immediate,
};
let manager = BranchManager::with_gc_config(db, timestamp, gc_config)?;

// Production configuration (1 hour retention)
let gc_config = BranchGcConfig {
    min_retention_seconds: 3600,
    auto_gc_enabled: true,
    gc_mode: BranchGcMode::Deferred,
};
let manager = BranchManager::with_gc_config(db, timestamp, gc_config)?;
```

## GC Modes Comparison

| Mode | When to Use | Performance | Storage Reclaim |
|------|-------------|-------------|-----------------|
| **Immediate** | Testing, small branches | Blocking | Instant |
| **Deferred** | Production, large branches | Non-blocking | After retention |

## Manual GC Operations

```rust
// Trigger garbage collection manually
let gc_count = manager.run_gc()?;
println!("Cleaned up {} branches", gc_count);

// Check pending GC count
let pending = manager.pending_gc_count();
println!("{} branches waiting for GC", pending);

// Access GC configuration
let config = manager.gc_config();
println!("Retention period: {}s", config.min_retention_seconds);
```

## Configuration Options

### BranchGcConfig Fields

```rust
pub struct BranchGcConfig {
    /// Minimum time (seconds) before branch data can be deleted
    pub min_retention_seconds: u64,

    /// Enable/disable automatic GC
    pub auto_gc_enabled: bool,

    /// GC mode (Immediate or Deferred)
    pub gc_mode: BranchGcMode,
}
```

### Recommended Settings

**Development/Testing**:
```rust
BranchGcConfig {
    min_retention_seconds: 0,
    auto_gc_enabled: true,
    gc_mode: BranchGcMode::Immediate,
}
```

**Production (Fast Cleanup)**:
```rust
BranchGcConfig {
    min_retention_seconds: 300,  // 5 minutes
    auto_gc_enabled: true,
    gc_mode: BranchGcMode::Deferred,
}
```

**Production (Safe)**:
```rust
BranchGcConfig {
    min_retention_seconds: 3600,  // 1 hour
    auto_gc_enabled: true,
    gc_mode: BranchGcMode::Deferred,
}
```

**Manual GC Only**:
```rust
BranchGcConfig {
    min_retention_seconds: 86400,  // 24 hours
    auto_gc_enabled: false,
    gc_mode: BranchGcMode::Deferred,
}
```

## Common Patterns

### Periodic GC Task

```rust
use std::time::Duration;
use tokio::time::interval;

async fn gc_task(manager: Arc<BranchManager>) {
    let mut interval = interval(Duration::from_secs(300)); // Every 5 minutes

    loop {
        interval.tick().await;
        match manager.run_gc() {
            Ok(count) if count > 0 => {
                tracing::info!("GC cleaned up {} branches", count);
            }
            Ok(_) => {} // No branches to clean
            Err(e) => {
                tracing::error!("GC failed: {}", e);
            }
        }
    }
}
```

### Pre-Backup GC

```rust
fn before_backup(manager: &BranchManager) -> Result<()> {
    // Clean up all eligible branches before backup
    let gc_count = manager.run_gc()?;
    tracing::info!("Pre-backup GC: {} branches cleaned", gc_count);

    // Wait for any pending operations
    std::thread::sleep(std::time::Duration::from_secs(1));

    Ok(())
}
```

### Storage Health Check

```rust
fn check_storage_health(manager: &BranchManager) {
    let pending = manager.pending_gc_count();
    let config = manager.gc_config();

    if pending > 100 {
        tracing::warn!("High GC queue: {} branches pending", pending);
    }

    if !config.auto_gc_enabled {
        tracing::warn!("Auto GC is disabled - manual cleanup required");
    }
}
```

## Troubleshooting

### Problem: Storage not being reclaimed

**Check**:
1. Is auto GC enabled? `manager.gc_config().auto_gc_enabled`
2. Has retention period passed? Check `pending_gc_count()`
3. Run manual GC: `manager.run_gc()?`

### Problem: High pending GC count

**Solutions**:
- Reduce retention period
- Run manual GC more frequently
- Switch to Immediate mode for cleanup
- Check for GC errors in logs

### Problem: Drop operation is slow

**Cause**: Immediate GC mode with large branches

**Solution**: Switch to Deferred mode
```rust
let gc_config = BranchGcConfig {
    gc_mode: BranchGcMode::Deferred,
    ..Default::default()
};
```

## Monitoring

### Key Metrics

Track these in production:

```rust
// Pending branches
let pending = manager.pending_gc_count();

// Run GC and measure
let start = Instant::now();
let count = manager.run_gc()?;
let duration = start.elapsed();

// Log metrics
tracing::info!(
    "GC: {} branches cleaned in {:?} (pending: {})",
    count, duration, manager.pending_gc_count()
);
```

### Log Messages

**Info Level**:
- "Branch GC deleted N data keys for branch ID X"
- "Successfully GC'd branch ID X"
- "Branch GC completed: N branches cleaned up"

**Debug Level**:
- "Scheduling deferred GC for branch 'X' (ID: Y)"
- "Branch ID X eligible for GC (age: As >= Bs)"

**Warn Level**:
- "Failed to GC branch ID X: error. Will retry later."
- "Branch GC disabled, skipping cleanup for branch X"

## Testing

### Running GC Tests

```bash
# All GC tests
cargo test --lib storage::branch::tests::test_gc

# Specific test
cargo test --lib test_branch_gc_immediate_mode

# With logging
RUST_LOG=debug cargo test --lib storage::branch::tests -- --nocapture
```

### Test Coverage

- Immediate mode behavior
- Deferred mode with retention
- Disabled GC
- Multiple branches
- Retention period enforcement
- Queue persistence
- Large branch cleanup (100+ keys)

## Performance

### Immediate Mode

- **Latency**: High (synchronous delete)
- **Throughput**: Lower (blocks drop operation)
- **Best for**: Small branches, testing

### Deferred Mode

- **Latency**: Low (async queue)
- **Throughput**: Higher (non-blocking)
- **Best for**: Large branches, production

### Batch Performance

- 1 branch, 100 keys: ~10ms (Immediate)
- 5 branches, 500 keys: ~50ms (Deferred batch)
- 100 branches: Processes in background

## API Summary

### Public Methods

```rust
// Configuration
BranchManager::new(db, timestamp) -> Result<Self>
BranchManager::with_gc_config(db, timestamp, config) -> Result<Self>

// Manual GC
manager.run_gc() -> Result<usize>
manager.gc_eligible_branches() -> Result<usize>

// Monitoring
manager.pending_gc_count() -> usize
manager.gc_config() -> &BranchGcConfig

// Branch operations (trigger auto GC)
manager.drop_branch(name, if_exists) -> Result<()>
```

### Internal Methods

```rust
// Private GC operations
schedule_branch_gc(branch_id, name) -> Result<()>
gc_branch_data(branch_id) -> Result<()>
load_pending_gc(db) -> Result<HashMap<BranchId, u64>>
save_pending_gc() -> Result<()>
```

## Safety Guarantees

1. **Crash Recovery**: Pending GC queue persisted to disk
2. **No Data Loss**: Retention period enforced
3. **Reference Safety**: Cannot drop branches with children
4. **Error Handling**: Failures logged, retried later
5. **Transaction Safety**: GC operations are atomic

## Related Documentation

- Full Implementation: `docs/implementation/BRANCH_GC_IMPLEMENTATION.md`
- Branch Storage Guide: `docs/BRANCH_STORAGE_GUIDE.md`
- Code Completion Tasks: `CODE_COMPLETION_TASKS.md`

## Implementation Notes

- **File**: `src/storage/branch.rs:419`
- **Completion Date**: 2025-11-21
- **Test Coverage**: 10 tests

## Support

For issues or questions:
1. Check logs for error messages
2. Verify GC configuration
3. Run manual GC and check results
4. Review pending GC count
