Adds sel_const_fold_pass() — a single-pass bottom-up const-fold that
runs after the Phase 4c flatten loop in parse_select():
4d-1 EQ/NE with either operand SEL_ANY → SEL_TRUE / SEL_FALSE
(checks both child slots — commutativity sort makes SEL_ANY
position non-deterministic after makeSelectNode interning)
4d-2 Identity laws: TRUE&&X→X, X&&TRUE→X, FALSE||X→X, X||FALSE→X
4d-3 Annihilation laws: FALSE&&X→FALSE, TRUE||X→TRUE (symmetric)
4d-4 Complement laws: !TRUE→FALSE, !FALSE→TRUE
Memory semantics:
level==0 (API server): frees orphaned nodes via free_select_node /
sel_free_tree; OOM from makeSelectNode returns original node safely
level>0 (CSE/scheduler): never manually frees; annihilation folds
return the already-interned left/right singleton directly (no
redundant makeSelectNode call); OOM guard unconditional so CSE
mode also degrades gracefully instead of returning NULL
9 new TDD tests added to test_select.c (RED→GREEN verified).
All 166 tests pass (157 prior + 9 Phase 4d).
3.3 KiB
3.3 KiB
P1-2: Host Resource Requirement Select — Investigation
Status
- [>] Under investigation (moved from apiserver-backend-tasks.md)
Background
The select field in an LSF-style resource requirement string (e.g. select[mem>4096 && type==X86_64])
filters candidate hosts before slot allocation. Currently EvalSelectForHost is a no-CGO stub that
always returns errNoCGO.
The full feature requires two layers:
- C parser + evaluator — parse the boolean select expression into an AST and evaluate it against a host's resource values.
- Go bridge — call the C evaluator via CGO and wire it into
FilterHostByResReqSelectin the controllers layer.
Sub-tasks
#11 P1-2a: C select expression parser (PEG + eval)
Files to touch:
include/resreq.h— Replace emptyxce_resreq_select_stub with expression-tree types, enums, andexterndeclarations forparse_select,eval_select,free_select.lib/xce_select.peg— New PEG grammar for select boolean expressions (right-recursive, handles&&,||,!, comparison operators, numeric literals, string literals, resource names).lib/resreq.c— Implementparse_select(),eval_select(),free_select(); updatekill_primary_resreq()to callfree_select().lib/meson.build— Addxce_select.pegto explicit source list so the PEG tool generates C.lib/testsuite/— TDD tests for parse/eval before implementing.
Open questions:
- Which PEG library is already available in the Nix/Meson build? (
peg,lemon,re2c?) - Exact grammar for comparison operators — LSF allows
mem > 4096,type == X86_64,swp >= 0. Need to confirm all supported operators and value types. - Does
eval_selectreceive a flat key-value map of resource values, or a pointer to the fullxce_host_tstruct? - Error reporting strategy — return a bool+error-string, or a tri-state (true/false/parse-error)?
#12 P1-2b: Go EvalSelectForHost + FilterHostByResReqSelect (blocked by #11)
Files to touch:
backend/clib.go— ImplementEvalSelectForHost(hostname, selectExpr string) errorusingcgo.Handlefor callback context; add#include "resreq.h", extern C declarations,xce_select_destroyhelper.controllers/hosts.go— ImplementFilterHostByResReqSelect(hosts []models.HostInfo, expr string), updatepreCheckHostRequest()limit from 4094 → 1024 bytes.
Open questions:
- Does
EvalSelectForHostneed to look up live resource values from the in-memory store, or are values passed in directly by the C layer? cgo.Handleusage pattern — confirm whether a per-call handle or a session-level handle is needed.- Input validation: max expression length (1024 bytes), allowed characters.
Investigation Checklist
- Survey existing PEG tooling in the Meson/Nix build environment.
- Read
include/resreq.hcurrent state to understandxce_resreq_select_stub. - Trace how
kill_primary_resreq()works today and wherefree_select()must be called. - Confirm resource value structure passed to
eval_select. - Confirm LSF select grammar spec (operators, value types, nesting depth).
- Prototype PEG grammar for a subset (numeric comparisons only) and get it compiling.
- Decide error propagation strategy across the CGO boundary.
- Write TDD tests for C parser before any implementation.