; Phase 3 — Plan: topological batches under a parallelism cap, incremental plan. ; diamond: a -> b, a -> c, (b,c) -> d (define pl-D (artdag/build (list (list "a" "load" (list) {}) (list "b" "f" (list "a") {}) (list "c" "g" (list "a") {}) (list "d" "add" (list "b" "c") {} true)))) (define pl-a (artdag/dag-id pl-D "a")) (define pl-b (artdag/dag-id pl-D "b")) (define pl-c (artdag/dag-id pl-D "c")) (define pl-d (artdag/dag-id pl-D "d")) ; wide: a -> b, c, e, f (four independent dependents) (define pl-W (artdag/build (list (list "a" "load" (list) {}) (list "b" "f" (list "a") {}) (list "c" "g" (list "a") {}) (list "e" "h" (list "a") {}) (list "f" "k" (list "a") {})))) ; ---- full plan, unlimited width ---- (artdag-test "full plan: batch count" (artdag/plan-batches (artdag/plan pl-D 0)) 3) (artdag-test "full plan: schedules every node" (artdag/plan-size (artdag/plan pl-D 0)) 4) (artdag-test "full plan: first batch is the leaf" (first (artdag/plan pl-D 0)) (list pl-a)) (artdag-test "full plan: middle batch runs b,c in parallel" (first (rest (artdag/plan pl-D 0))) (artdag/sort-strings (list pl-b pl-c))) (artdag-test "full plan: last batch is the sink" (first (rest (rest (artdag/plan pl-D 0)))) (list pl-d)) (artdag-test "full plan: max width is 2" (artdag/plan-width (artdag/plan pl-D 0)) 2) ; ---- parallelism cap ---- (artdag-test "cap 1: width never exceeds 1" (artdag/plan-width (artdag/plan pl-D 1)) 1) (artdag-test "cap 1: serializes into one node per batch" (artdag/plan-batches (artdag/plan pl-D 1)) 4) (artdag-test "cap larger than widest wave is a no-op" (artdag/plan pl-D 10) (artdag/plan pl-D 0)) (artdag-test "wide cap 2: width capped at 2" (artdag/plan-width (artdag/plan pl-W 2)) 2) (artdag-test "wide cap 2: leaf wave then two capped sub-batches" (artdag/plan-batches (artdag/plan pl-W 2)) 3) (artdag-test "wide cap 2: still schedules all five nodes" (artdag/plan-size (artdag/plan pl-W 2)) 5) (artdag-test "wide unlimited: single wave of four after leaf" (artdag/plan-width (artdag/plan pl-W 0)) 4) ; ---- incremental (dirty-only) plan ---- (artdag-test "dirty plan: schedules only the dirty closure" (artdag/plan-size (artdag/plan-dirty pl-D (list pl-b) 0)) 2) (artdag-test "dirty plan: b then d" (artdag/plan-dirty pl-D (list pl-b) 0) (list (list pl-b) (list pl-d))) (artdag-test "dirty plan: clean deps treated as satisfied" (first (artdag/plan-dirty pl-D (list pl-b) 0)) (list pl-b)) (artdag-test "dirty plan: leaf change replans whole graph" (artdag/plan-size (artdag/plan-dirty pl-D (list pl-a) 0)) 4) (artdag-test "dirty plan: sink change is a single batch" (artdag/plan-dirty pl-D (list pl-d) 0) (list (list pl-d)))