feoxdb 0.5.2

Iron-oxide fast embedded database - nanosecond-level key-value storage
Documentation
name: Deploy to GitHub Pages

on:
  workflow_dispatch:
  workflow_run:
    workflows: ["Benchmark"]
    types:
      - completed
    branches: [ main, master ]

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    # Only run if triggered manually, by push, or if benchmark workflow succeeded
    if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success'
    steps:
      - uses: actions/checkout@v5

      - name: Install Rust stable
        uses: dtolnay/rust-toolchain@stable
        with:
          components: llvm-tools-preview

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y jq

      - name: Cache cargo registry
        uses: actions/cache@v5
        with:
          path: ~/.cargo/registry
          key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}

      - name: Cache cargo index
        uses: actions/cache@v5
        with:
          path: ~/.cargo/git
          key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }}

      - name: Build documentation
        run: |
          cargo doc --no-deps --all-features
          echo '<meta http-equiv="refresh" content="0; url=feoxdb/index.html">' > target/doc/index.html

      - name: Install cargo-llvm-cov
        run: cargo install cargo-llvm-cov || true

      - name: Generate code coverage
        run: |
          cargo llvm-cov --all-features --workspace --html
          echo "Coverage report generated"
        timeout-minutes: 10
      
      - name: Setup benchmark baseline
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
        run: |
          echo "Setting up benchmark baseline for comparison..."
          
          # Download previous benchmark results to use as baseline
          if curl -sfL https://mehrantsi.github.io/FeOxDB/benchmarks.tar.gz -o /tmp/benchmarks.tar.gz 2>/dev/null; then
            echo "Found previous benchmark results"
            mkdir -p target
            tar -xzf /tmp/benchmarks.tar.gz -C target/
            
            # Debug: show what we extracted
            echo "Extracted structure:"
            ls -la target/criterion/ | head -10 || echo "No criterion directory"
            
            # Rename all "new" directories to "base" for comparison
            find target/criterion -type d -name "new" | while read new_dir; do
              base_dir="${new_dir%/new}/base"
              echo "Moving $new_dir to $base_dir"
              rm -rf "$base_dir" 2>/dev/null || true
              mv "$new_dir" "$base_dir"
            done
            echo "Baseline setup complete"
          else
            echo "No previous benchmarks found (this is normal for first run)"
          fi
      
      - name: Run benchmarks
        run: |
          # Run benchmarks normally to generate Criterion HTML reports
          cargo bench --bench latency || true
          cargo bench --bench throughput || true
          
          # Extract benchmark results for historical tracking
          # Parse the Criterion output to create bencher format
          echo "Extracting benchmark results..."
          # Extract results from all criterion benchmarks that exist
          if test -d "target/criterion"; then
            find "target/criterion" -name "estimates.json" | while read f; do
              name=$(echo "$f" | sed 's|.*/criterion/||' | sed 's|/estimates.json||' | tr '/' '_')
              if test -f "$f"; then
                mean=$(jq -r '.mean.point_estimate' "$f" 2>/dev/null || echo "")
                if test -n "$mean"; then
                  # Convert nanoseconds to appropriate unit and output in bencher format
                  echo "test ${name} ... bench: ${mean} ns/iter (+/- 0)" >> benchmark-output.txt
                fi
              fi
            done
          fi
          
          # If no results were extracted, create a dummy file
          if test ! -s benchmark-output.txt; then
            echo "test dummy ... bench: 1 ns/iter (+/- 0)" > benchmark-output.txt
          fi
          
          echo "=== Benchmark output ==="
          cat benchmark-output.txt || echo "No benchmark output"
        timeout-minutes: 15
      
      - name: Debug benchmark output
        run: |
          echo "=== Checking benchmark output ==="
          ls -la target/ || echo "No target directory"
          ls -la target/criterion/ || echo "No criterion directory"
          find target/criterion -name "*.html" 2>/dev/null | head -20 || echo "No HTML files found"
          
      - name: Generate benchmark summary
        if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' 
        run: |
          echo "## Benchmark Results" > benchmark-summary.md
          echo "" >> benchmark-summary.md
          echo "### Latest Performance Metrics" >> benchmark-summary.md
          echo "" >> benchmark-summary.md
          
          if test -s benchmark-output.txt; then
            echo '```' >> benchmark-summary.md
            cat benchmark-output.txt >> benchmark-summary.md
            echo '```' >> benchmark-summary.md
          else
            echo "No benchmark results to display" >> benchmark-summary.md
          fi
          
          echo "" >> benchmark-summary.md
          echo "[View detailed reports](https://mehrantsi.github.io/FeOxDB/benchmarks.html)" >> benchmark-summary.md
      
      - name: Prepare GitHub Pages
        run: |
          mkdir -p public
          
          # Copy documentation
          cp -r target/doc/* public/
          
          # Copy code coverage report
          if [ -d "target/llvm-cov/html" ]; then
            mkdir -p public/coverage
            cp -r target/llvm-cov/html/* public/coverage/
            echo "Code coverage report copied"
          fi
          
          # Copy benchmark results if they exist
          if [ -d "target/criterion" ]; then
            mkdir -p public/benchmarks
            cp -r target/criterion/* public/benchmarks/
            
            # Archive only the "new" results for next run's baseline
            echo "Creating benchmark archive for future comparisons..."
            # First, remove all "base" directories to avoid accumulating old baselines
            find target/criterion -type d -name "base" -exec rm -rf {} + 2>/dev/null || true
            # Now archive the criterion directory (which only has "new" results)
            tar -czf public/benchmarks.tar.gz -C target criterion
            
            # Copy logo to public directory
            cp logo.svg public/logo.svg 2>/dev/null || true
            
            # Create benchmarks index
            cat > public/benchmarks.html << 'EOF'
          <!DOCTYPE html>
          <html>
          <head>
              <title>FeOxDB Benchmarks</title>
              <style>
                  body { 
                      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif;
                      margin: 40px;
                      line-height: 1.6;
                  }
                  h1 { color: #333; border-bottom: 2px solid #e1e4e8; padding-bottom: 10px; }
                  h2 { color: #586069; margin-top: 30px; }
                  ul { list-style-type: none; padding: 0; }
                  li { 
                      margin: 15px 0; 
                      padding: 10px;
                      background: #f6f8fa;
                      border-radius: 6px;
                  }
                  a { 
                      color: #0366d6; 
                      text-decoration: none; 
                      font-weight: 500;
                  }
                  a:hover { text-decoration: underline; }
                  .nav { 
                      background: #24292e; 
                      color: white; 
                      padding: 15px; 
                      margin: -40px -40px 40px -40px;
                      display: flex;
                      align-items: center;
                      justify-content: space-between;
                  }
                  .nav-links a { color: white; margin-right: 20px; }
                  .logo { height: 50px; }
              </style>
          </head>
          <body>
              <div class="nav">
                  <img src="logo.svg" alt="FeOxDB" class="logo">
                  <div class="nav-links">
                      <a href="index.html">Documentation</a>
                      <a href="benchmarks.html">Benchmarks</a>
                      <a href="coverage/index.html">Coverage</a>
                      <a href="https://github.com/mehrantsi/feoxdb">GitHub</a>
                  </div>
              </div>
              
              <h1>FeOxDB Performance Benchmarks</h1>
              <p>Comprehensive performance metrics for FeOxDB operations.</p>
              
              <h2>Latency Benchmarks</h2>
              <ul>
                  <li><a href="benchmarks/get_latency/report/index.html">📊 Get Operations</a></li>
                  <li><a href="benchmarks/insert_latency/report/index.html">📊 Insert Operations</a></li>
                  <li><a href="benchmarks/delete_latency/memory/report/index.html">📊 Delete Operations</a></li>
                  <li><a href="benchmarks/mixed_latency/80_read_15_write_5_delete/report/index.html">📊 Mixed Operations</a></li>
              </ul>
              
              <h2>Throughput Benchmarks</h2>
              <ul>
                  <li><a href="benchmarks/insert/report/index.html">📊 Insert Operations</a></li>
                  <li><a href="benchmarks/get/report/index.html">📊 Get Operations</a></li>
                  <li><a href="benchmarks/mixed_operations/80_20_read_write/report/index.html">📊 Mixed Operations</a></li>
              </ul>
              
              <h2>Individual Latency Reports</h2>
              <ul>
                  <li><a href="benchmarks/get_latency/get_sequential/report/index.html">Get - Sequential Access</a></li>
                  <li><a href="benchmarks/get_latency/get_random/report/index.html">Get - Random Access</a></li>
                  <li><a href="benchmarks/get_latency/get_hot_key/report/index.html">Get - Hot Key Access</a></li>
                  <li><a href="benchmarks/insert_latency/size_64/report/index.html">Insert - 64 byte values</a></li>
                  <li><a href="benchmarks/insert_latency/size_1024/report/index.html">Insert - 1KB values</a></li>
                  <li><a href="benchmarks/insert_latency/size_4096/report/index.html">Insert - 4KB values</a></li>
                  <li><a href="benchmarks/delete_latency/memory/report/index.html">Delete - Memory Mode</a></li>
                  <li><a href="benchmarks/mixed_latency/80_read_15_write_5_delete/report/index.html">Mixed - 80/15/5 Read/Write/Delete</a></li>
              </ul>
              
              <h2>Individual Throughput Reports</h2>
              <ul>
                  <li><a href="benchmarks/insert/1000/report/index.html">Insert - 1,000 ops</a></li>
                  <li><a href="benchmarks/insert/10000/report/index.html">Insert - 10,000 ops</a></li>
                  <li><a href="benchmarks/insert/100000/report/index.html">Insert - 100,000 ops</a></li>
                  <li><a href="benchmarks/insert/1000000/report/index.html">Insert - 1,000,000 ops</a></li>
                  <li><a href="benchmarks/get/1000/report/index.html">Get - 1,000 ops</a></li>
                  <li><a href="benchmarks/get/10000/report/index.html">Get - 10,000 ops</a></li>
                  <li><a href="benchmarks/get/100000/report/index.html">Get - 100,000 ops</a></li>
                  <li><a href="benchmarks/get/1000000/report/index.html">Get - 1,000,000 ops</a></li>
                  <li><a href="benchmarks/mixed_operations/80_20_read_write/report/index.html">Mixed - 80/20 Read/Write</a></li>
              </ul>
              
              <h2>About the Benchmarks</h2>
              <p>These benchmarks are automatically generated using Criterion.rs and represent real-world performance characteristics of FeOxDB.</p>
          </body>
          </html>
          EOF
          fi
          
          # Create main index with navigation
          cat > public/index.html << 'EOF'
          <!DOCTYPE html>
          <html>
          <head>
              <title>FeOxDB Documentation</title>
              <meta http-equiv="refresh" content="0; url=feoxdb/index.html">
              <style>
                  body { font-family: sans-serif; padding: 40px; }
                  a { color: #0366d6; }
              </style>
          </head>
          <body>
              <p>Redirecting to <a href="feoxdb/index.html">FeOxDB Documentation</a>...</p>
              <p>Also available:</p>
              <ul>
                  <li><a href="benchmarks.html">Performance Benchmarks</a></li>
                  <li><a href="coverage/index.html">Code Coverage Report</a></li>
              </ul>
          </body>
          </html>
          EOF
      
      - name: Setup Pages
        uses: actions/configure-pages@v6
      
      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v5
        with:
          path: ./public
  
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v5