Dispatcher-Pipeline: switch JobTicket creation to use ExitNode directly

Up to now, a draft/mock implementation was used, relying on a »spec tuple«,
which was fabricated by MockJobTicket. But with the introduction of
NodeGraphAttachment, the MockSequence now generates a nested ExitNode structure,
and thus the JobTicket will be created through the "real" ctor, and
no longer via MockJobTicket.

Thus it is possible to skip this whole interspersed »spec tuple«,
since ExitNode *is* already this aggregated / abstracted Spec
This commit is contained in:
Fischlurch 2023-06-10 04:52:40 +02:00
parent 2c3b85a122
commit f25ec2f5ef
8 changed files with 142 additions and 87 deletions

View file

@ -100,9 +100,9 @@ using lib::LUID;
struct Prerequisite
{
Prerequisite* next{nullptr};
JobTicket& descriptor;
JobTicket const& descriptor;
Prerequisite (JobTicket& ticket)
Prerequisite (JobTicket const& ticket)
: descriptor{ticket}
{ }
};
@ -131,6 +131,8 @@ using lib::LUID;
template<class IT>
static LinkedElements<Provision> buildProvisionSpec (IT);
static LinkedElements<Provision> buildProvisionSpec (ExitNode const&);
private:
JobTicket() { } ///< @internal as NIL marker, a JobTicket can be empty
@ -141,13 +143,16 @@ using lib::LUID;
{ }
public:
class ExplorationState;
friend class ExplorationState;
JobTicket (ExitNode const& exitNode)
: provision_{buildProvisionSpec (exitNode)}
{ }
static const JobTicket NOP;
class ExplorationState;
friend class ExplorationState;
ExplorationState startExploration() const; ////////////////////////////TICKET #1276 : likely to become obsolete
ExplorationState discoverPrerequisites (uint channelNr =0) const; ////////////////////////////TICKET #1276 : likely to become obsolete
@ -250,7 +255,7 @@ using lib::LUID;
}
JobTicket*
JobTicket const *
operator->() const
{
REQUIRE (!empty() && toExplore_.top().isValid());
@ -331,6 +336,19 @@ using lib::LUID;
ENSURE (not isnil (provisionSpec));
return provisionSpec;
}
inline LinkedElements<JobTicket::Provision>
JobTicket::buildProvisionSpec (ExitNode const& exitNode)
{
REQUIRE (not isnil (exitNode)); // has valid functor
LinkedElements<Provision> provisionSpec;
HashVal invoSeed = exitNode.getPipelineIdentity();
JobFunctor& func = exitNode.getInvocationFunctor();
auto& provision = provisionSpec.emplace<Provision> (func, exitNode, invoSeed);
for (ExitNode const& preNode: exitNode.getPrerequisites())
provision.requirements.emplace(preNode); /////////////////////////////////////////////TICKET #1292 : need to pass in Allocator as argument
//////////////////////////////////////////////////////////////////////OOO : where to ALLOCATE the prerequisite JobTickets ??!!
return provisionSpec;
}

View file

@ -68,7 +68,7 @@ namespace fixture {
class Segment
{
using TicketAlloc = std::deque<engine::JobTicket>;
using PortTable = std::deque<std::reference_wrapper<engine::JobTicket>>;
using PortTable = std::deque<std::reference_wrapper<const engine::JobTicket>>;
protected:
@ -134,36 +134,6 @@ namespace fixture {
private:
/** @internal Generate sequence of prerequisite JobTicket */
auto
assemblePrerequisites (ExitNode const& exitNode)
{
return lib::transformIterator (exitNode.getPrerequisites()
,[this](ExitNode const& prereq) -> engine::JobTicket&
{
tickets_.emplace_back(
assembleTicketSpec (prereq));
return tickets_.back();
});
}
/** @internal Traverse ExitNode structure and prepare JobTicket */
auto
assembleTicketSpec (ExitNode const& exitNode)
{
REQUIRE (not isnil (exitNode)); // has valid functor
using vault::engine::JobFunctor;
using Prereqs = decltype(assemblePrerequisites (exitNode));
using SpecTuple = std::tuple<ExitNode const&, HashVal, JobFunctor&, Prereqs>;
return lib::singleValIterator( /////////////////////////////////////////TICKET #1297 : multiplicity per channel will be removed here
SpecTuple(exitNode
,exitNode.getPipelineIdentity()
,exitNode.getInvocationFunctor()
,assemblePrerequisites (exitNode)
));
}
void
generateTickets_onDemand (size_t portNr)
{
@ -172,8 +142,8 @@ namespace fixture {
portTab_.emplace_back (engine::JobTicket::NOP); // disable this slot
else
{// Ticket was not generated yet...
tickets_.emplace_back (assembleTicketSpec (exitNode[portNr]));
portTab_.emplace_back (tickets_.back()); // ref to new ticket ‣ slot
tickets_.emplace_back (exitNode[portNr]);
portTab_.emplace_back (tickets_.back()); // ref to new ticket ‣ slot
}
}
};

View file

@ -29,7 +29,6 @@
#include "lib/error.hpp"
#include "steam/fixture/segmentation.hpp"
//#include "steam/mobject/builder/fixture-change-detector.hpp" ///////////TODO
#include "lib/time/timevalue.hpp"
#include "lib/split-splice.hpp"
@ -75,14 +74,14 @@ namespace fixture {
* @see SplitSplice_test
*/
Segment const&
Segmentation::splitSplice (OptTime start, OptTime after, const engine::JobTicket* jobTicket)
Segmentation::splitSplice (OptTime start, OptTime after, engine::ExitNodes&& modelLink)
{
ASSERT (!start or !after or start != after);
using Iter = typename list<Segment>::iterator;
auto getStart = [](Iter elm) -> Time { return elm->start(); };
auto getAfter = [](Iter elm) -> Time { return elm->after(); };
auto createSeg= [&](Iter pos, Time start, Time after) -> Iter { return segments_.emplace (pos, TimeSpan{start, after}, jobTicket); };
auto createSeg= [&](Iter pos, Time start, Time after) -> Iter { return segments_.emplace (pos, TimeSpan{start, after}, move(modelLink)); };
auto emptySeg = [&](Iter pos, Time start, Time after) -> Iter { return segments_.emplace (pos, TimeSpan{start, after}); };
auto cloneSeg = [&](Iter pos, Time start, Time after, Iter src) -> Iter { return segments_.emplace (pos, *src, TimeSpan{start, after}); };
auto discard = [&](Iter pos, Iter after) -> Iter { return segments_.erase (pos,after); };

View file

@ -121,7 +121,7 @@ namespace fixture {
/** rework the existing Segmentation to include a new Segment as specified */
Segment const&
splitSplice (OptTime start, OptTime after, const engine::JobTicket* =nullptr);
splitSplice (OptTime start, OptTime after, engine::ExitNodes&& modelLink =ExitNodes{});
};

View file

@ -93,22 +93,12 @@ namespace test {
/* ===== specify a mock JobTicket setup for tests ===== */
template<class IT>
inline auto
defineSpec (HashVal seed, IT&& prereq)
{
using SpecTuple = std::tuple<ExitNode const&, JobFunctor&, HashVal, IT>;
return lib::singleValIterator( /////////////////////////////////////////////TICKET #1297 : multiplicity per channel will be removed here
SpecTuple(ExitNode::NIL
,DummyJob::getFunctor()
, seed
, std::forward<IT> (prereq)));
}
inline auto
inline ExitNode
defineSimpleSpec (HashVal seed =0)
{
return defineSpec (seed, lib::nilIterator<JobTicket&>());
return ExitNode{seed
,ExitNodes{}
,& DummyJob::getFunctor()};
}
}//(End)internal test helpers....
@ -140,10 +130,10 @@ namespace test {
: JobTicket{defineSimpleSpec (seed)}
{ }
template<class IT>
MockJobTicket (HashVal seed, IT&& prereq)
: JobTicket{defineSpec (seed, std::forward<IT> (prereq))}
{ }
// template<class IT>
// MockJobTicket (HashVal seed, IT&& prereq)
// : JobTicket{defineSpec (seed, std::forward<IT> (prereq))}
// { }
/* ===== Diagnostics ===== */
@ -191,11 +181,11 @@ namespace test {
{
for (auto& spec : specs)
{
JobTicket& newTicket = buildTicketFromSpec (spec);
auto start = spec.retrieveAttribute<Time> ("start");
auto after = spec.retrieveAttribute<Time> ("after");
Segmentation::splitSplice (start, after, &newTicket);
Segmentation::splitSplice (start, after
,ExitNodes{buildExitNodeFromSpec (spec)}
);
}
}
@ -204,8 +194,9 @@ namespace test {
buildExitNodeFromSpec (GenNode const& spec)
{
return ExitNode{buildSeed (spec)
,buildPrerequisites (spec)};
} // Warning: re-entrant invocation of emplace_back
,buildPrerequisites (spec)
,& DummyJob::getFunctor()};
}
private: /* ======== Implementation: build fake ExitNodes from test specification ==== */
@ -220,24 +211,12 @@ namespace test {
ExitNodes
buildPrerequisites (GenNode const& spec)
{
// return lib::transformIterator (spec.getChildren()
// ,[this](GenNode const& childSpec) -> JobTicket&
// {
// return buildTicketFromSpec (childSpec);
// });
ExitNodes prerequisites;
for (auto& child : spec.getChildren())
prerequisites.emplace_back (
buildExitNodeFromSpec (child));
return prerequisites;
}
JobTicket&
buildTicketFromSpec (GenNode const& spec)
{
// return tickets_.emplace_back (buildSeed(spec)
// ,buildPrerequisites(spec));
} // Warning: re-entrant invocation of emplace_back
};

View file

@ -247,7 +247,7 @@ namespace test {
CHECK (Time(0,20) == s3.start());
CHECK (Time::MAX == s3.after());
Job job = s2.jobTicket().createJobFor(coord);
Job job = s2.jobTicket(0).createJobFor(coord);
job.triggerJob();
CHECK (marker == DummyJob::invocationAdditionalKey (job));
}

View file

@ -28,6 +28,7 @@
#include "lib/test/run.hpp"
#include "steam/fixture/node-graph-attachment.hpp"
#include "steam/engine/mock-dispatcher.hpp"
#include "steam/engine/frame-coord.hpp"
#include "steam/engine/exit-node.hpp"
#include "lib/util.hpp"
@ -110,7 +111,7 @@ namespace test {
// verify mapped JobTicket is assembled according to above spec...
auto getMarker = [](JobTicket const& ticket)
{
FrameCoord dummyFrame;
engine::FrameCoord dummyFrame;
Job job = ticket.createJobFor(dummyFrame);
return job.parameter.invoKey.part.a;
};

View file

@ -74283,6 +74283,16 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1686364650603" ID="ID_1148029855" MODIFIED="1686364718576" TEXT="Allozieren der prerequisite-JobTickets">
<linktarget COLOR="#fa197d" DESTINATION="ID_1148029855" ENDARROW="Default" ENDINCLINATION="599;43;" ID="Arrow_ID_433931878" SOURCE="ID_812723541" STARTARROW="None" STARTINCLINATION="205;12;"/>
<icon BUILTIN="clanbomber"/>
<icon BUILTIN="flag-pink"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1686365033392" HGAP="42" ID="ID_73811690" MODIFIED="1686365051620" TEXT="zwei M&#xf6;glichkeiten?" VSHIFT="-2">
<icon BUILTIN="help"/>
<node CREATED="1686365053474" ID="ID_1746219617" MODIFIED="1686365061592" TEXT="wie das Haupt-Ticket im Segment"/>
<node CREATED="1686365062469" ID="ID_1687391140" MODIFIED="1686365089197" TEXT="direkt in der Prerequisite-Struktur im Haupt-Ticket"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1686186370164" ID="ID_1270139229" MODIFIED="1686186389790" TEXT="Problem: Klon-Segmente wegen Split-Splice">
<icon BUILTIN="messagebox_warning"/>
@ -74330,14 +74340,14 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="broken-line"/>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1686270678269" ID="ID_1696777369" MODIFIED="1686271185355" TEXT="Spec-Erzeugung durch ExitNode ersetzen">
<node COLOR="#338800" CREATED="1686270678269" ID="ID_1696777369" MODIFIED="1686361087711" TEXT="Spec-Erzeugung durch ExitNode ersetzen">
<linktarget COLOR="#bf3856" DESTINATION="ID_1696777369" ENDARROW="Default" ENDINCLINATION="47;-15;" ID="Arrow_ID_1288742892" SOURCE="ID_116441332" STARTARROW="None" STARTINCLINATION="-91;7;"/>
<icon BUILTIN="flag-pink"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1686270700679" ID="ID_1172741628" MODIFIED="1686270720719" TEXT="JobTIcket-ctor akzeptiert ExitNode const&amp;">
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1686270700679" ID="ID_1172741628" MODIFIED="1686361068947" TEXT="JobTIcket-ctor akzeptiert ExitNode const&amp;">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1686270722814" ID="ID_1222081090" MODIFIED="1686270750251" TEXT="bisherige Traversierungs-Logik sinngem&#xe4;&#xdf; hier &#xfc;bersetzen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1686270722814" ID="ID_1222081090" MODIFIED="1686361081278" TEXT="bisherige Traversierungs-Logik sinngem&#xe4;&#xdf; hier &#xfc;bersetzen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1686271328534" ID="ID_601604800" MODIFIED="1686271349144" TEXT="MockSegmentation baut jetzt ohnehin bereits eine ExitNode-Struktur">
<icon BUILTIN="idea"/>
@ -74361,8 +74371,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1686090113552" HGAP="35" ID="ID_1222153026" MODIFIED="1686090132027" TEXT="Spec (wie bisher) an JobTicket-ctor weitergeben" VSHIFT="43">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1686090113552" HGAP="35" ID="ID_1222153026" MODIFIED="1686361148882" TEXT="ExitNode (wie bisher die Spec) an JobTicket-ctor weitergeben" VSHIFT="43">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1686090919949" HGAP="27" ID="ID_929102409" MODIFIED="1686091184043" VSHIFT="10">
<richcontent TYPE="NODE"><html>
<head>
@ -74390,6 +74400,84 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1686092906718" HGAP="35" ID="ID_1605426517" MODIFIED="1686184589923" TEXT="FixtureSegment_test" VSHIFT="-3">
<linktarget COLOR="#5aec6d" DESTINATION="ID_1605426517" ENDARROW="Default" ENDINCLINATION="-104;-6;" ID="Arrow_ID_658388334" SOURCE="ID_31746915" STARTARROW="None" STARTINCLINATION="570;-91;"/>
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1686361157528" ID="ID_565360581" MODIFIED="1686361167333" TEXT="SEGFAULT">
<icon BUILTIN="broken-line"/>
<node CREATED="1686361493991" ID="ID_423058577" MODIFIED="1686361526825" TEXT="tritt nicht bei jedem Lauf auf &#x27f9; vermutlich dangling pointer"/>
<node CREATED="1686361820600" ID="ID_780766515" MODIFIED="1686361835540">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Testfall: <b>retrieve_JobTicket</b>
</p>
</body>
</html></richcontent>
<icon BUILTIN="info"/>
<node CREATED="1686361839323" ID="ID_1748696798" MODIFIED="1686361869554" TEXT="nur ein Segment"/>
<node CREATED="1686361870451" ID="ID_833560905" MODIFIED="1686361907327" TEXT="aber zwei Prerequisites">
<linktarget COLOR="#ed2958" DESTINATION="ID_833560905" ENDARROW="Default" ENDINCLINATION="57;0;" ID="Arrow_ID_1523772194" SOURCE="ID_113479512" STARTARROW="None" STARTINCLINATION="60;-2;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1686361606310" ID="ID_288594511" MODIFIED="1686361716351" TEXT="requirements_ Linked-List is corruped">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
head_ steam::engine::JobTicket::Provision * 0x2525252525252525
</p>
</body>
</html></richcontent>
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1686361720232" ID="ID_113479512" MODIFIED="1686362543033" TEXT="auff&#xe4;llig: Sement::tickets_ enth&#xe4;lt nur ein Element">
<arrowlink COLOR="#ed2958" DESTINATION="ID_833560905" ENDARROW="Default" ENDINCLINATION="57;0;" ID="Arrow_ID_1523772194" STARTARROW="None" STARTINCLINATION="60;-2;"/>
<icon BUILTIN="idea"/>
<node CREATED="1686362546700" HGAP="31" ID="ID_1149307734" MODIFIED="1686362563929" TEXT="sollten das nicht drei sein??" VSHIFT="2"/>
<node CREATED="1686362575818" ID="ID_193094920" MODIFIED="1686362598693" TEXT="nein: die prereq-JobTickets werden von LinkedElements alloziert">
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1686364368098" ID="ID_1576782710" MODIFIED="1686364421501" TEXT="prereq-JobTickets werden nirgends alloziert/gespeichert">
<icon BUILTIN="broken-line"/>
<node CREATED="1686364436691" ID="ID_462388515" MODIFIED="1686364452584">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<font face="Monospaced">provision.requirements.emplace(</font><font face="Monospaced" color="#e61919">preNode</font><font face="Monospaced">)</font>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1686364460397" ID="ID_956048441" MODIFIED="1686364472840" TEXT="das alloziert eine struct Prerequisite"/>
<node CREATED="1686364475066" ID="ID_353638422" MODIFIED="1686364538445">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
und die nimmt im ctor ein <font face="Monospaced" color="#ef331d"><b>JobTicket const&amp;</b></font>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1686364486502" ID="ID_1943162539" MODIFIED="1686364548847" TEXT="der neue JobTicket-ctor ist nicht explicit &#x27f9; automatische Konversion">
<icon BUILTIN="messagebox_warning"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1686364557872" ID="ID_812723541" MODIFIED="1686365118116" TEXT="im Prerequisite wird nur ein Pointer gespeichert">
<arrowlink COLOR="#fa197d" DESTINATION="ID_1148029855" ENDARROW="Default" ENDINCLINATION="599;43;" ID="Arrow_ID_433931878" STARTARROW="None" STARTINCLINATION="205;12;"/>
<icon BUILTIN="clanbomber"/>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1686014291202" ID="ID_252150549" MODIFIED="1686014413608" TEXT="Problem: wie kommt man an die portNum?">