null, 'suite' => null, 'level' => null, 'model' => null, 'result' => null, ]; private const SORTABLE = [ 'ran_at', 'model_id', 'suite', 'task', 'level', 'ok', 'decode', 'user_tps', 'ttft', 't_answer', 'wall', 'total', ]; public function resetFilters(): void { $this->filters = [ 'search' => null, 'suite' => null, 'level' => null, 'model' => null, 'result' => null, ]; $this->resetPage(); } #[Computed] public function results(): LengthAwarePaginator { $ttl = (int) config('festbench.home_cache_ttl', 300); $user = auth()->user(); // Guest + public-only views are cacheable; any logged-in view may // embed private rows, so it gets a user-scoped key instead. $cacheKey = 'home:'.($user?->id ?? 'guest').':'.md5(json_encode([$this->filters, $this->sortBy, $this->sortDirection, $this->getPage()])); return Cache::remember($cacheKey, $ttl, function () use ($user) { // Default guest view (no filters, no custom sort): the flat // precomputed snapshot — no UNION runs at request time. if ($user === null && $this->isDefaultView()) { return DB::table('home_snapshot')->orderBy('sequence')->paginate(25); } $query = $this->baseQuery($user) ->tap(fn ($q) => $this->applySorting($q)) ->tap(fn ($q) => $this->applyFilters($q)); return $query->paginate(25); }); } private function isDefaultView(): bool { return ($this->sortBy === null || $this->sortBy === 'ran_at') && $this->sortDirection === 'desc' && collect($this->filters)->filter(fn ($v) => $v !== null && $v !== '')->isEmpty() && $this->getPage() === 1; } /** * The combined query. Suite filter unset → the all_results view (one * UNION plan for everything); suite filter set → the concrete suite * table directly (full indexes, no union). */ private function baseQuery($user) { $suite = $this->filters['suite']; $model = $suite !== null && $suite !== '' ? Suites::modelFor($suite) : null; $source = $model !== null ? $model::query()->getModel()->getTable() : 'all_results'; // The concrete suite tables have no suite column; promote it so the // view renders identically for both query paths. $select = $model !== null ? "{$source}.*, '{$suite}' AS suite" : "{$source}.*"; return DB::table($source) ->join('benchmark_runs', 'benchmark_runs.id', '=', "{$source}.benchmark_run_id") ->selectRaw($select) ->addSelect( 'benchmark_runs.model_id', 'benchmark_runs.model_quant', 'benchmark_runs.engine', 'benchmark_runs.run_id', 'benchmark_runs.visibility', 'benchmark_runs.user_id as run_user_id') ->where(BenchmarkRun::visibleClause($user)); } #[Computed] public function suites(): array { return Cache::remember('home:suites', 300, fn () => Suites::active()->all()); } #[Computed] public function models(): array { return Cache::remember('home:models', 300, function () { return BenchmarkRun::visibleTo(auth()->user()) ->distinct()->orderBy('model_id')->pluck('model_id')->all(); }); } private function applySorting($query) { $column = in_array($this->sortBy, self::SORTABLE, true) ? $this->sortBy : 'ran_at'; $source = $this->filters['suite'] !== null && $this->filters['suite'] !== '' ? Suites::modelFor($this->filters['suite'])::make()->getTable() : 'all_results'; return $query->orderBy($column, $this->sortDirection === 'asc' ? 'asc' : 'desc') ->orderBy("{$source}.id", 'desc'); } private function applyFilters($query) { $source = $this->filters['suite'] !== null && $this->filters['suite'] !== '' ? Suites::modelFor($this->filters['suite'])::make()->getTable() : 'all_results'; return $query ->when($this->filters['search'], fn ($q, string $search) => $q->where(function ($q) use ($search, $source) { $q->where("{$source}.task", 'like', "%{$search}%") ->orWhere('benchmark_runs.model_id', 'like', "%{$search}%") ->orWhere('benchmark_runs.label', 'like', "%{$search}%"); })) ->when($this->filters['level'], fn ($q, string $level) => $q->where("{$source}.level", $level)) ->when($this->filters['model'], fn ($q, string $model) => $q->where('benchmark_runs.model_id', $model)) ->when($this->filters['result'] !== null && $this->filters['result'] !== '', fn ($q) => $q->where("{$source}.ok", (bool) $this->filters['result'])); } }; ?>