param( [Parameter(Mandatory = $true)] [string]$CompareCellMedianFile, [Parameter(Mandatory = $true)] [string]$AdaptCellMedianFile ) $ErrorActionPreference = 'Stop' function Convert-ToDouble([string]$Value, [string]$Column, [string]$Path) { $number = 0.0 $style = [Globalization.NumberStyles]::Float if ([double]::TryParse($Value, $style, [Globalization.CultureInfo]::InvariantCulture, [ref]$number)) { return $number } if ([double]::TryParse($Value, $style, [Globalization.CultureInfo]::CurrentCulture, [ref]$number)) { return $number } throw "Cannot parse '$Value' as $Column in $Path" } function Test-SelectedDeferred([string]$Structure) { $base = ($Structure -split '@', 2)[0] return $base -eq 'adaptive_shape_deferred' ` -or $base -eq 'adaptive_shape_default_deferred' ` -or $base -eq 'adaptive_shape_moderate_deferred' } function Test-CellFile([string]$Path, [string]$Suite) { $resolved = (Resolve-Path -LiteralPath $Path).Path $rows = @(Import-Csv -LiteralPath $resolved | Where-Object { Test-SelectedDeferred $_.structure }) if ($rows.Count -eq 0) { throw "No selected deferred/default/moderate adaptive rows in $resolved" } $requiredWorkloads = if ($Suite -eq 'adapt') { @('short_burst_negative_control', 'phase_10_uniform_10_local_80_read') } else { @('bursty_edit', 'phase_uniform_local_read') } foreach ($workload in $requiredWorkloads) { if (-not @($rows | Where-Object { $_.workload -eq $workload }).Count) { throw "Missing selected $Suite workload '$workload' in $resolved" } } $failures = @() foreach ($row in $rows) { $switches = Convert-ToDouble $row.median_switches 'median_switches' $resolved $leafRebuilds = Convert-ToDouble ` $row.median_leaf_rebuilds 'median_leaf_rebuilds' $resolved $maxSwitches = 1.0 $maxLeafRebuilds = 1.0 $requireVector = $false $class = 'stationary' if ($row.workload -eq 'short_burst_negative_control') { $maxSwitches = 0.0 $maxLeafRebuilds = 0.0 $requireVector = $true $class = 'short-negative' } elseif ($Suite -eq 'adapt' ` -and $row.workload -eq 'phase_10_uniform_10_local_80_read') { $maxSwitches = 2.0 # The trace deliberately contains two different edit phases. One # stable shape choice per phase is useful adaptation, not churn. $maxLeafRebuilds = 2.0 # Returning to vector is optional: for wide/non-trivial values the # measured O(N) conversion can cost more than the remaining read # phase. The policy must avoid churn, not force an uneconomic # second transition. $class = 'adapt-exact-phase' } elseif ($Suite -eq 'compare' ` -and $row.workload -eq 'phase_uniform_local_read') { $maxSwitches = 2.0 $maxLeafRebuilds = 2.0 # The shorter compare phase, especially at smoke scale, may not # provide enough read evidence to amortize a return to vector. $class = 'compare-phase' } elseif ($Suite -eq 'compare' -and $row.workload -eq 'bursty_edit') { $maxSwitches = 2.0 $maxLeafRebuilds = 1.0 # As above, final tiered is valid when return conversion does not # amortize within the observed read tail. $class = 'bursty' } $modeFailure = $requireVector -and $row.final_mode -ne 'vector' if ($switches -gt $maxSwitches ` -or $leafRebuilds -gt $maxLeafRebuilds ` -or $modeFailure) { $failures += [pscustomobject]@{ suite = $Suite class = $class profile = $row.profile type = $row.type workload = $row.workload n = $row.n structure = $row.structure switches = $switches switch_limit = $maxSwitches leaf_rebuilds = $leafRebuilds leaf_rebuild_limit = $maxLeafRebuilds final_mode = $row.final_mode required_mode = if ($requireVector) { 'vector' } else { '*' } } } } [pscustomobject]@{ path = $resolved checked = $rows.Count failures = $failures } } $compare = Test-CellFile $CompareCellMedianFile 'compare' $adapt = Test-CellFile $AdaptCellMedianFile 'adapt' $failures = @($compare.failures) + @($adapt.failures) if ($failures.Count -ne 0) { foreach ($failure in $failures) { $message = ("FAIL {0}/{1}: {2} {3}/{4}/N={5}; " + "switches={6} (limit {7}), leaf_rebuilds={8} (limit {9}), " + "final_mode={10} (required {11})") -f $failure.suite, $failure.class, $failure.structure, $failure.type, $failure.workload, $failure.n, $failure.switches, $failure.switch_limit, $failure.leaf_rebuilds, $failure.leaf_rebuild_limit, $failure.final_mode, $failure.required_mode Write-Host $message } throw "Adaptation validation failed in $($failures.Count) selected cell(s)" } Write-Host "Adaptation validation passed: $($compare.checked) compare and $($adapt.checked) adapt cells."