feat(scheduler-allocation): implement the shared host-candidate iterator

Adds host_iter.c: the one shared xce_host_iter_t implementation,
lazily filtering sched->core.workers by select expression
(sched_meet_host_selection, unchanged) and resource availability
(sched_check_host_satisfy, unchanged), with a real cancellation
point per candidate visited. xce_alloc_plan_t gains a ctx field
(xce_sched_ctx_t*) so the iterator can reach the scheduler/select
expression/staged resource-want -- additive to task 1.1's approved
interface, NULL-guarded at init(). Test proves the core design
property this spec exists to establish: a host too small for one
search remains a valid candidate for a later, smaller search via a
fresh iterator instance over the same worker set.

Task 2.1 (scheduler-allocation spec). Requirements 3.1-3.6.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYdtrEWWZfKRRGED7raEYg
This commit is contained in:
Rongsong Shen 2026-09-04 16:46:03 +00:00
parent d0024eb7e8
commit d9831b0bc8
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
5 changed files with 872 additions and 2 deletions

View file

@ -49,7 +49,24 @@ typedef struct {
* availability -- consumed by xce_host_iter_t (Req 3), not exposed as
* a separate field here. This interface does not mandate a
* representation for it; each concrete plan-iterator implementation
* carries whatever it needs to reconstruct the filter. */
* carries whatever it needs to reconstruct the filter.
*
* Added by task 2.1 (host_iter.c, the real implementation): `ctx` is
* exactly that carrier. xce_host_iter_t.init()'s own three declared
* parameters (iter, plan, workers) cannot, on their own, reach the
* select expression or the currently-staged resource want -- `workers`
* is a bare RTTI var with no back-pointer to the owning
* xce_scheduler_t (confirmed against sched_collect_workers()'s own
* iter_make(&it, sched->core.workers) body, scheduler.c), and this
* struct's other two fields (nbuckets/bucket_slots) carry only the
* partition shape. `ctx` (already carrying ->sched, ->primary->select,
* and ->alloc_req.host -- the resource want staged by whichever
* allocator's prepare_allocation_hook ran) supplies everything
* sched_meet_host_selection()/sched_check_host_satisfy() need, without
* widening init()'s own parameter list. Not owned by the plan; the
* caller (allocate_primary(), a later task) retains ownership for the
* duration of one job's allocation attempt. */
xce_sched_ctx_t* ctx;
} xce_alloc_plan_t;
typedef struct xce_alloc_plan_iter_s xce_alloc_plan_iter_t;
@ -137,4 +154,30 @@ struct xce_host_iter_s {
void* private;
};
/*
* sched_host_iter_init/next/fini - the one shared xce_host_iter_t
* implementation (host_iter.c, task 2.1, Req 3). Callers wire these onto a
* stack-allocated, caller-owned xce_host_iter_t before calling init(),
* following the exact same manual-vtable-assignment convention task 1.1's
* own reference stubs established (see testsuite/test_alloc_plan_iter.c):
*
* xce_host_iter_t host_iter_storage;
* xce_host_iter_t* host_iter = &host_iter_storage;
*
* host_iter->init = sched_host_iter_init;
* host_iter->next = sched_host_iter_next;
* host_iter->fini = sched_host_iter_fini;
*
* if (host_iter->init(host_iter, plan, sched->core.workers) == 0) { ... }
*
* plan->ctx (see xce_alloc_plan_t above) must be non-NULL: it supplies the
* xce_scheduler_t/select-expression/resource-want state this
* implementation needs but init()'s own (iter, plan, workers) parameters
* cannot reach on their own.
*/
extern int sched_host_iter_init(xce_host_iter_t* iter, xce_alloc_plan_t* plan,
var workers);
extern xce_sched_worker_t* sched_host_iter_next(xce_host_iter_t* iter);
extern void sched_host_iter_fini(xce_host_iter_t* iter);
#endif