diff --git a/tests/vault/gear/test-chain-load-test.cpp b/tests/vault/gear/test-chain-load-test.cpp
index caf785e78..5601a596d 100644
--- a/tests/vault/gear/test-chain-load-test.cpp
+++ b/tests/vault/gear/test-chain-load-test.cpp
@@ -927,10 +927,16 @@ namespace test {
- /** @test TODO setup for running a chain-load as scheduled task
+ /** @test setup for running a chain-load as scheduled task
* - running an isolated Node recalculation
* - dispatch of this recalculation packaged as render job
- * @todo WIP 12/23 🔁 define ⟶ 🔁 implement
+ * - verify the planning job, which processes nodes in batches;
+ * for the test, the callback-λ will not invoke the Scheduler,
+ * but rather use the instructions to create clone nodes;
+ * if all nodes are processed and all dependency connections
+ * properly reported through the callback-λ, then calculating
+ * this clone network should reproduce the original hash.
+ * @todo WIP 12/23 ✔ define ⟶ ✔ implement
*/
void
verify_scheduling_setup()
@@ -986,6 +992,73 @@ namespace test {
job3.triggerJob(); // Hash calculations are *not* idempotent
CHECK (e.hash != 0x6A5924BA3389D7C);
+
+
+ // use the »planing job« to organise the calculations:
+ // Let the callbacks create a clone — which at the end should generate the same hash
+ array clone;
+ size_t lastTouched(-1);
+ size_t lastLevel(-1);
+ bool shallContinue{false};
+ auto getNodeIdx = [&](Node* n) { return n - &nodes[0]; };
+
+ // callback-λ rigged for test....
+ // Instead of invoking the Scheduler, here we replicate the node structure
+ auto disposeStep = [&](size_t idx, size_t level)
+ {
+ Node& n = clone[idx];
+ n.clear();
+ n.level = level;
+ lastTouched = idx;
+ };
+ auto setDependency = [&](Node* pred, Node* succ)
+ {
+ size_t predIdx = getNodeIdx(pred);
+ size_t succIdx = getNodeIdx(succ);
+ // replicate this relation into the clone array
+ clone[predIdx].addSucc(clone[succIdx]);
+ };
+ auto continuation = [&](size_t levelDone, bool work_left)
+ {
+ lastLevel = levelDone;
+ shallContinue = work_left;
+ };
+ // build a JobFunctor for the planning step(s)
+ RandomChainPlanFunctor<16> planJob{nodes.front(), nodes.size()
+ ,disposeStep
+ ,setDependency
+ ,continuation};
+ Job jobP1{planJob
+ ,InvocationInstanceID()
+ ,planJob.encodeLevel(1)};
+ Job jobP2{planJob
+ ,InvocationInstanceID()
+ ,planJob.encodeLevel(3)};
+
+ jobP1.triggerJob();
+ CHECK (lastTouched = 2);
+ CHECK (lastLevel = 1);
+ Node* lastN = &clone[lastTouched];
+ CHECK (lastN->level == lastLevel);
+ CHECK ( isnil (lastN->succ));
+ CHECK (not isnil (lastN->pred));
+ CHECK (shallContinue);
+
+ jobP2.triggerJob();
+ CHECK (lastTouched = 3);
+ CHECK (lastLevel = 3);
+ lastN = &clone[lastTouched];
+ CHECK (lastN->level == 2);
+ CHECK (lastN->level < lastLevel);
+ CHECK ( isnil (lastN->succ));
+ CHECK (not isnil (lastN->pred));
+ CHECK (not shallContinue);
+
+ // all clone nodes should be wired properly now
+ CHECK (lastN->hash == 0);
+ for (Node& n : clone)
+ n.calculate();
+ CHECK (lastN->hash == 0x6A5924BA3389D7C);
}
};
diff --git a/tests/vault/gear/test-chain-load.hpp b/tests/vault/gear/test-chain-load.hpp
index 764a5921a..ed4ac2e67 100644
--- a/tests/vault/gear/test-chain-load.hpp
+++ b/tests/vault/gear/test-chain-load.hpp
@@ -1136,31 +1136,31 @@ namespace test {
using Node = typename TestChainLoad::Node;
function scheduleCalcJob_;
- function markDependency_;
+ function markDependency_;
function continuation_;
- size_t chunkSize_;
size_t maxCnt_;
-
Node* nodes_;
- size_t currIdx_{0};
+
+ size_t currIdx_{0}; // Note: this test-JobFunctor is statefull
public:
template
- RandomChainPlanFunctor(size_t chunkSize, size_t maxLevel,
- Node& nodeArray,
+ RandomChainPlanFunctor(Node& nodeArray, size_t nodeCnt,
CAL&& schedule, DEP&& markDepend,
CON&& continuation)
: scheduleCalcJob_{forward (schedule)}
- , markDependency_{forward (markDepend)}
- , continuation_{continuation}
- , chunkSize_{chunkSize}
- , maxCnt_{maxLevel}
+ , markDependency_{forward (markDepend)}
+ , continuation_{forward (continuation)}
+ , maxCnt_{nodeCnt}
, nodes_{&nodeArray}
{ }
- /** render job invocation to trigger one Node recalculation */
+ /** render job invocation to trigger one batch of scheduling;
+ * the installed callback-λ should actually place a job with
+ * RandomChainCalcFunctor for each node, and also inform the
+ * Scheduler about dependency relations between jobs. */
void
invokeJobOperation (JobParameter param) override
{
@@ -1171,7 +1171,7 @@ namespace test {
if (n->level > targetLevel)
break;
scheduleCalcJob_(currIdx_, n->level);
- for (Node* pred: n.pred)
+ for (Node* pred: n->pred)
markDependency_(pred,n);
}
continuation_(targetLevel, currIdx_ < maxCnt_);
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index 2ae04b792..9a23f9eba 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -57667,8 +57667,7 @@
-
+
@@ -100610,13 +100609,18 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
-
-
+
+
@@ -100635,7 +100639,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -100675,8 +100679,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
@@ -100892,16 +100896,17 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
-
+
-
+
+
@@ -100935,9 +100940,9 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
-
+
@@ -100953,8 +100958,20 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+