Invocation: improve test-data repository storage

For simplified tests there is a helper function to attain a reference to some `TestFrame` data, created on-demand and maintained in a repository in heap memory.

This storage has now be switched to `std::deque`
 * provided addresses are stable
 * less memory waste

__note__: `TestFrame::reseed()` will discard this repository, and draw a new (reproducible) seed.
This commit is contained in:
Fischlurch 2024-11-20 15:32:49 +01:00
parent 3bfe8f33e0
commit 52c8445299
3 changed files with 125 additions and 159 deletions

View file

@ -2,7 +2,7 @@
TestFrame - test data frame (stub) for checking Render engine functionality
Copyright (C)
2011, Hermann Vosseler <Ichthyostega@web.de>
2011, 2024 Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
@ -41,7 +41,7 @@
#include <climits>
#include <memory>
#include <vector>
#include <deque>
@ -50,15 +50,13 @@ namespace engine{
namespace test {
namespace err = lumiera::error;
using std::deque;
using util::unConst;
using std::vector;
/** @note using a random-congruential engine to generate the payload data */
using PseudoRandom = lib::RandomSequencer<std::minstd_rand>;
namespace error = lumiera::error;
namespace { // hidden local support facilities....
/**
@ -103,16 +101,17 @@ namespace test {
: public lib::SeedNucleus
, util::MoveOnly
{
uint64_t const& fixPoint_;
uint64_t const& distinction_;
public:
DistinctNucleus(uint64_t const& anchor)
: fixPoint_{anchor}
: distinction_{anchor}
{ }
uint64_t
getSeed() override
{
return fixPoint_;
return distinction_;
}
};
@ -142,76 +141,43 @@ namespace test {
}
/**
* @internal table to hold test data frames.
/* ======= static TestFrame repository ======= */
/** @internal table to hold test data frames in heap memory.
* These frames are built on demand, but retained thereafter.
* Some tests might rely on the actual memory locations, using the
* test frames to simulate a real input frame data stream.
* @param CHA the maximum number of channels to expect
* @param FRA the maximum number of frames to expect per channel
* @warning choose the maximum number parameters wisely.
* We're allocating memory to hold a table of test frames
* e.g. sizeof(TestFrame) * 20channels * 100frames 2 MiB
* The table uses vectors, and thus will grow on demand,
* but this might cause existing frames to be relocated in memory;
* some tests might rely on fixed memory locations. Just be cautious!
* @note \ref TestFrame::reseed() also discards this storage, which
* otherwise is retained at stable location until process end.
*/
template<uint CHA, uint FRA>
struct TestFrameTable
: vector<vector<TestFrame>>
: deque<deque<TestFrame>>
{
typedef vector<vector<TestFrame>> VECT;
TestFrameTable()
: VECT(CHA)
{
for (uint i=0; i<CHA; ++i)
at(i).reserve(FRA);
}
TestFrameTable() = default;
TestFrame&
getFrame (uint seqNr, uint chanNr=0)
getFrame (uint seqNr, uint chanNr)
{
if (chanNr >= this->size())
{
WARN (test, "Growing table of test frames to %d channels, "
"which is > the default (%d)", chanNr, CHA);
resize(chanNr+1);
}
ENSURE (chanNr < this->size());
vector<TestFrame>& channel = at(chanNr);
deque<TestFrame>& channel = at(chanNr);
if (seqNr >= channel.size())
{
WARN_IF (seqNr >= FRA, test,
"Growing channel #%d of test frames to %d elements, "
"which is > the default (%d)", chanNr, seqNr, FRA);
for (uint i=channel.size(); i<=seqNr; ++i)
channel.push_back (TestFrame (i,chanNr));
INFO (test, "Growing channel #%d of test frames %d -> %d elements."
, chanNr, channel.size(), seqNr+1);
for (uint nr=channel.size(); nr<=seqNr; ++nr)
channel.emplace_back (nr, chanNr);
}
ENSURE (seqNr < channel.size());
return channel[seqNr];
}
};
const uint INITIAL_CHAN = 20;
const uint INITIAL_FRAMES = 100;
typedef TestFrameTable<INITIAL_CHAN,INITIAL_FRAMES> TestFrames;
std::unique_ptr<TestFrames> testFrames;
TestFrame&
accessTestFrame (uint seqNr, uint chanNr)
{
if (!testFrames) testFrames.reset (new TestFrames);
return testFrames->getFrame(seqNr,chanNr);
}
} // (End) hidden impl details
//
std::unique_ptr<TestFrameTable> testFrames;
//
}// (End) hidden impl details
@ -219,11 +185,12 @@ namespace test {
TestFrame&
testData (uint seqNr, uint chanNr)
{
return accessTestFrame (seqNr,chanNr);
if (not testFrames)
testFrames = std::make_unique<TestFrameTable>();
return testFrames->getFrame (seqNr, chanNr);
}
/**
* @remark this function should be invoked at the start of any test
* which requires reproducible data values in the TestFrame.
@ -236,14 +203,15 @@ namespace test {
void
TestFrame::reseed()
{
testFrames.reset();
testFrames.reset(); // discard existing test data repository
dataSeed = drawSeed (lib::defaultGen);
}
/* ===== TestFrame class ===== */
/* ======= TestFrame class ======= */
TestFrame::Meta::Meta (uint seq, uint family)
: _MARK_{stampHeader()}
@ -267,7 +235,6 @@ namespace test {
ENSURE (isPristine());
}
TestFrame::TestFrame (TestFrame const& o)
: header_{o.header_}
{
@ -294,11 +261,11 @@ namespace test {
* Sanity check on the metadata header.
* @remark Relevant to detect memory corruption or when accessing some
* arbitrary memory location, which may or may not actually hold a TestFrame.
* Based on the assumption that it is unlikely that some random memory location
* just happens to hold our [marker word](\ref stampHeader()).
* Based on the assumption that it is unlikely that any given memory location
* just happens to hold our [marker word](\ref stampHeader()) by accident.
* @note this is only the base level of verification, because in addition
* \ref isValid verifies the checksum and \ref isPristine additionally
* recomputes the data generation to see if it matches the Meta::distinction
* recomputes the data generation to see if it matches the Meta::distinction.
*/
bool
TestFrame::Meta::isPlausible() const
@ -327,14 +294,6 @@ namespace test {
: DISCARDED;
}
bool
TestFrame::operator== (void* memLocation) const
{
TestFrame& candidate (accessAsTestFrame (memLocation));
return candidate.isSane()
&& candidate == *this;
}
bool
TestFrame::Meta::operator== (Meta const&o) const
{
@ -343,6 +302,14 @@ namespace test {
and checksum == o.checksum
and distinction == o.distinction;
}
bool
TestFrame::operator== (void* memLocation) const
{
TestFrame& candidate (accessAsTestFrame (memLocation));
return candidate.isSane()
&& candidate == *this;
}
bool
TestFrame::contentEquals (TestFrame const& o) const
@ -371,8 +338,7 @@ namespace test {
/** verify the current data was not touched since initialisation
* @remark implemented by regenerating the data sequence deterministically,
* based on the Meta::distinction mark recorded in the metadata.
*/
* based on the Meta::distinction mark recorded in the metadata. */
bool
TestFrame::matchDistinction() const
{
@ -462,5 +428,4 @@ namespace test {
}
}}} // namespace steam::engine::test

View file

@ -2,7 +2,7 @@
TESTFRAME.hpp - test data frame (stub) for checking Render engine functionality
Copyright (C)
2011, Hermann Vosseler <Ichthyostega@web.de>
2011, 2024 Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
@ -20,13 +20,13 @@
** and stores a lifecycle phase and a data checksum.
**
** The contents of each TestFrame are filled on creation with pseudo-random data,
** which is created from a _discriminator seed,_ based on a »family« and a »frame-nr«
** within the family. Due to the deterministic nature of these computations, the
** _pristine state_ of any frame can be determined. But the payload data is accessible
** which is created from a _discriminator seed,_ based on a »family« and a »frameNr«
** within each family(channel). Due to the deterministic nature of these computations,
** the _pristine state_ of any frame can be determined. But the payload data is accessible
** and can be manipulated, and a new [checksum can be recorded](\ref TestFrame::markChecksum).
**
** For ease of testing, a static store of TestFrame instances is maintained internally,
** and an arbitrary memory location can be treated as TestFrame.
** For ease of testing, a static [store of TestFrame instances](\ref #testData) is built and
** retained in heap memory, and an arbitrary memory location can be treated as TestFrame.
*/
@ -132,14 +132,14 @@ namespace test {
_Arr const& data() const { return * std::launder (reinterpret_cast<_Arr const*> (&buffer_)); }
private:
bool contentEquals (TestFrame const& o) const;
bool matchDistinction() const;
void buildData();
Meta& accessHeader();
Meta& accessHeader();
Meta const& accessHeader() const;
StageOfLife currStage() const;
HashVal computeChecksum() const;
bool hasValidChecksum() const;
bool contentEquals (TestFrame const& o) const;
bool matchDistinction() const;
StageOfLife currStage() const;
HashVal computeChecksum() const;
bool hasValidChecksum() const;
};
@ -147,12 +147,12 @@ namespace test {
/** Helper to access a specific frame of test data at a fixed memory location.
* The series of test frames is generated on demand, but remains in memory thereafter,
* similar to real data accessible from some kind of source stream. Each of these generated
* test frames filled with different yet reproducible pseudo random data.
* test frames is filled with different yet reproducible pseudo random data.
* Client code is free to access and corrupt this data.
* @note TestFrame::reseed() discards this data and draws a new base seed from `defaultGen`
*/
TestFrame& testData (uint seqNr =0, uint chanNr =0);
}}} // namespace steam::engine::test
#endif

View file

@ -18037,9 +18037,7 @@
</node>
<node CREATED="1654447918320" ID="ID_518830573" MODIFIED="1654448078388" TEXT="ITEM">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Eintrag in einer Liste oder Asset in einer Sammlung;
@ -18878,9 +18876,7 @@
</node>
<node COLOR="#33565a" CREATED="1664723834064" HGAP="35" ID="ID_793769798" MODIFIED="1664727861369" TEXT="erf&#xfc;llt(cH)?" VSHIFT="26">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
BEDINUNG: cH&#160;&gt; aktuelleH&#246;he
@ -19130,9 +19126,7 @@
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
das hei&#223;t, wenn das Label schon eingeblendet ist, aber nun zus&#228;tzlicher Platz verf&#252;gbar wird; deshalb d&#252;rfen wir hier bei einem bereits eingeblendeten Label nicht pauschal aussteigen, sondern m&#252;ssen jedesmal die ganze Pr&#252;fung machen
@ -19642,9 +19636,7 @@
<arrowlink COLOR="#90c8e3" DESTINATION="ID_1759333514" ENDARROW="Default" ENDINCLINATION="44;114;" ID="Arrow_ID_1003572490" STARTARROW="None" STARTINCLINATION="-104;-18;"/>
<node CREATED="1665874929814" ID="ID_103158499" MODIFIED="1665874947504">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
und zwar wegen der <i>Separation of Concerns</i>
@ -20487,9 +20479,7 @@
</node>
<node CREATED="1541858088132" ID="ID_303565989" MODIFIED="1576282358099">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
unser <b>InteractionControl</b>&#160;ist eine Zwischenschicht
@ -22115,9 +22105,7 @@
</node>
<node CREATED="1575845569870" ID="ID_1676564226" MODIFIED="1576282358089" TEXT="es kann niemals in Ordnung sein, wenn ein ViewHooked-Widget irgendwohin verschoben wird">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
denn vern&#252;nftigerweise mu&#223; man davon ausgehen, da&#223; der Canvas (oder wo auch immer das element platziert wird) sich einen Pointer speichert, und diesen sp&#228;ter auch aktiv verwenden wird
@ -25463,9 +25451,7 @@
<node CREATED="1612019894343" ID="ID_1448053043" MODIFIED="1612019901396" TEXT="m&#xf6;gliche Workarounds...">
<node CREATED="1612019903134" ID="ID_1689432083" MODIFIED="1612020045315" TEXT="die DisplayEvaluation schon per Diff-Listener ausl&#xf6;sen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...daf&#252;r br&#228;uchte ich aber einen Diff-Listener f&#252;r alle strukturellen &#196;nderungen incl sub-Scope. Das ist nicht trivial zu implementieren, weil die sub-Scopes ja beliebig tief verschachtelt sein k&#246;nnen, und alle rekursiv delegiert werden
@ -39076,9 +39062,7 @@
<icon BUILTIN="messagebox_warning"/>
<node COLOR="#990000" CREATED="1620913903207" ID="ID_236784465" MODIFIED="1624023359388" TEXT="L&#xf6;sung time::Control (Mutator)">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
das time::Control lebt dann wohl im Observer, und dieser mu&#223; eine Schnittstelle haben, &#252;ber die das time::Control auf das eigentliche Zielfeld gesetzt wird...<br /><br />...das klingt alles gef&#228;hrlich indirekt...
@ -41358,9 +41342,7 @@
<icon BUILTIN="button_cancel"/>
<node CREATED="1667748952764" ID="ID_1863452609" MODIFIED="1667751189345">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Ansatz mit Unbekannten
@ -43050,9 +43032,7 @@
<node CREATED="1670695044386" ID="ID_1440113563" MODIFIED="1670695056972" TEXT="das kann auch entgleisen (wenn man&apos;s falsch macht)"/>
<node CREATED="1670695067366" ID="ID_1511491697" MODIFIED="1670695119208" TEXT="und w&#xe4;re effektiv genauso wie die bestehende L&#xf6;sung">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<ul>
<li>
@ -43938,9 +43918,7 @@
<icon BUILTIN="idea"/>
<node CREATED="1668474283161" ID="ID_505458679" MODIFIED="1668474406928">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
damit kann ich stets so genau wie m&#246;glich rechnen
@ -45681,9 +45659,7 @@
<node CREATED="1541775381760" ID="ID_681940327" MODIFIED="1541775392922" TEXT="denn: get sucht per Symbol"/>
<node CREATED="1541775428125" ID="ID_1569956089" MODIFIED="1576282358020" TEXT="und: einige Attribute haben notwendig eine extern definierte ID">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...n&#228;mlich diejenigen, die <i>selber </i>Modell-Elemente sind.
@ -45959,9 +45935,7 @@
<icon BUILTIN="idea"/>
<node CREATED="1523020094460" ID="ID_970478590" MODIFIED="1557498707234">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
(GlobalCtx)-&gt;InteractionDirector-&gt;<b>ViewLocator</b>
@ -46157,9 +46131,7 @@
<node CREATED="1448078268223" ID="ID_1027574047" MODIFIED="1518487921085" TEXT="Lebenszyklus">
<node CREATED="1448078450375" ID="ID_459686936" MODIFIED="1576282358017" TEXT="zeugen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
hei&#223;t: Element registriert sich am UI-Bus
@ -56710,10 +56682,10 @@
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786430299" ID="ID_257931093" LINK="#ID_594112005" MODIFIED="1729978891967" TEXT="Refactoring f&#xfc;r Node-Invocation (#1367 | #1372)">
<linktarget COLOR="#713558" DESTINATION="ID_257931093" ENDARROW="Default" ENDINCLINATION="-2466;135;" ID="Arrow_ID_121875527" SOURCE="ID_442258905" STARTARROW="None" STARTINCLINATION="-2154;-229;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1728786565516" ID="ID_1372116679" MODIFIED="1729981840076" TEXT="&#xdc;berlegungen zum notwendigen Ausbau">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#007188" CREATED="1728786430299" FOLDED="true" ID="ID_257931093" LINK="#ID_594112005" MODIFIED="1732112403457" TEXT="Refactoring f&#xfc;r Node-Invocation (#1367 | #1372)">
<linktarget COLOR="#4b3571" DESTINATION="ID_257931093" ENDARROW="Default" ENDINCLINATION="-2466;135;" ID="Arrow_ID_121875527" SOURCE="ID_442258905" STARTARROW="None" STARTINCLINATION="-2154;-229;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1728786565516" ID="ID_1372116679" MODIFIED="1732111852298" TEXT="&#xdc;berlegungen zum notwendigen Ausbau">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -56736,7 +56708,7 @@
</ul>
</body>
</html></richcontent>
<arrowlink COLOR="#943e5b" DESTINATION="ID_939285679" ENDARROW="Default" ENDINCLINATION="-1142;-205;" ID="Arrow_ID_1632825391" STARTARROW="None" STARTINCLINATION="1971;131;"/>
<arrowlink COLOR="#943e5b" DESTINATION="ID_939285679" ENDARROW="Default" ENDINCLINATION="-1142;-205;" ID="Arrow_ID_1632825391" STARTARROW="None" STARTINCLINATION="2220;153;"/>
</node>
<node COLOR="#338800" CREATED="1728786907104" ID="ID_142347061" MODIFIED="1732076967655" TEXT="Umbauten">
<icon BUILTIN="button_ok"/>
@ -56749,7 +56721,7 @@
</node>
<node COLOR="#338800" CREATED="1731900530433" ID="ID_1117088425" MODIFIED="1731900545903" TEXT="den Basis-Seed mit einem minimal-Spread aufbauen">
<icon BUILTIN="button_ok"/>
<node CREATED="1731943389399" ID="ID_39230986" MODIFIED="1731943552546">
<node CREATED="1731943389399" ID="ID_39230986" MODIFIED="1732112395129">
<richcontent TYPE="NODE"><html>
<head/>
<body>
@ -56758,6 +56730,7 @@
</p>
</body>
</html></richcontent>
<linktarget COLOR="#7e8fc5" DESTINATION="ID_39230986" ENDARROW="Default" ENDINCLINATION="-219;12;" ID="Arrow_ID_1543995286" SOURCE="ID_1738588672" STARTARROW="None" STARTINCLINATION="616;34;"/>
</node>
<node CREATED="1731943561624" ID="ID_1209671030" MODIFIED="1731943647377">
<richcontent TYPE="NODE"><html>
@ -56809,6 +56782,9 @@
<node COLOR="#338800" CREATED="1731944023419" ID="ID_799758026" MODIFIED="1732076312763" TEXT="lege diesen hinter die Nutzdaten">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1732111820577" ID="ID_1321344879" MODIFIED="1732111836734" TEXT="Testdaten-Tabelle als deque&#xb2;">
<icon BUILTIN="idea"/>
</node>
</node>
<node COLOR="#338800" CREATED="1728787025826" ID="ID_1972770219" MODIFIED="1730835694593" TEXT="Accessor und Iteration">
<icon BUILTIN="button_ok"/>
@ -56942,13 +56918,23 @@
<font color="#c00d9b" size="2">GnaGnaGna</font>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="smiley-oh"/>
</node>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1732111934377" ID="ID_1738588672" MODIFIED="1732112403463" TEXT="11/2024 Diskriminator-Berechnung deterministisch">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...essentielle Vorraussetzung f&#252;r reproduzierbare Tests: Es gibt einen statischen Basis-Hash, auf dem dann die einzelnen Frame-Serien aufbauen (indem sie ihn jeweils in den Schritt-Spread einarbeiten; dadurch haben benachbarte Frames &#228;hnliche, aber sicher unterschiedliche Diskriminator-Seeds, aus denen ein Linear-Congruential-PRNG gebaut wird, um jeweils die Daten f&#252;r einen Frame zu bef&#252;llen. Der Basis-Seed ist zwar initial komplett zuf&#228;llig (Entropie), wird aber durch TestFrame::reseed() aus dem aktuellen defaultGen neu gezogen. Und der defaultGen ist f&#252;r Tests seit <a href="https://issues.lumiera.org/ticket/1378">#1378</a>&#160;deterministisch pseudo-zuf&#228;llig und reproduzierbar
</p>
</body>
</html></richcontent>
<arrowlink COLOR="#7e8fc5" DESTINATION="ID_39230986" ENDARROW="Default" ENDINCLINATION="-219;12;" ID="Arrow_ID_1543995286" STARTARROW="None" STARTINCLINATION="616;34;"/>
</node>
</node>
<node CREATED="1729979079809" ID="ID_1106549131" MODIFIED="1729979157169" TEXT="Eigenschaften">
<icon BUILTIN="info"/>
@ -92262,11 +92248,13 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
<node CREATED="1728771335267" ID="ID_1094389177" MODIFIED="1728771344519" TEXT="insgesamt....">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728771345748" ID="ID_286542606" MODIFIED="1728772561734" TEXT="reproduzierbare pseudo-Random-Eingabedaten">
<node COLOR="#435e98" CREATED="1728771345748" ID="ID_286542606" MODIFIED="1732112583455" TEXT="reproduzierbare pseudo-Random-Eingabedaten">
<icon BUILTIN="yes"/>
<node CREATED="1728776765371" ID="ID_530339700" MODIFIED="1728776784584" TEXT="Basis: der TestFrame">
<node COLOR="#435e98" CREATED="1320146635371" ID="ID_530339700" MODIFIED="1732112572060" TEXT="Basis: der TestFrame">
<icon BUILTIN="idea"/>
<node CREATED="1728776965140" ID="ID_1948564901" MODIFIED="1728776972015" TEXT="geschaffen bereits 2011-11-01"/>
<node CREATED="1728776965140" ID="ID_1948564901" MODIFIED="1728776965140" TEXT="geschaffen bereits 2011-11-01">
<icon BUILTIN="info"/>
</node>
<node CREATED="1728777073629" ID="ID_1232418525" LINK="#ID_1098979861" MODIFIED="1729979276054">
<richcontent TYPE="NODE"><html>
<head/>
@ -92299,8 +92287,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
</node>
<node CREATED="1728778080366" ID="ID_1631642281" MODIFIED="1728778216760" TEXT="kann Konsistenz und damit Korruption erkennen"/>
<node COLOR="#435e98" CREATED="1728777587128" ID="ID_939285679" MODIFIED="1732077390669" TEXT="fehlt bisher">
<linktarget COLOR="#943e5b" DESTINATION="ID_939285679" ENDARROW="Default" ENDINCLINATION="-1142;-205;" ID="Arrow_ID_1632825391" SOURCE="ID_1372116679" STARTARROW="None" STARTINCLINATION="1971;131;"/>
<node COLOR="#435e98" CREATED="1728777587128" FOLDED="true" ID="ID_939285679" MODIFIED="1732112548625" TEXT="fehlte bisher">
<linktarget COLOR="#943e5b" DESTINATION="ID_939285679" ENDARROW="Default" ENDINCLINATION="-1142;-205;" ID="Arrow_ID_1632825391" SOURCE="ID_1372116679" STARTARROW="None" STARTINCLINATION="2220;153;"/>
<icon BUILTIN="broken-line"/>
<node COLOR="#338800" CREATED="1728778245232" ID="ID_1565084791" MODIFIED="1732077388649" TEXT="ein kontrollierbarer Seeding-Mechanismus">
<icon BUILTIN="button_ok"/>
@ -92318,7 +92306,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1728781231984" ID="ID_283829609" MODIFIED="1728781974281" TEXT="w&#xfc;nschenswert">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1728781231984" ID="ID_283829609" MODIFIED="1732112534565" TEXT="w&#xfc;nschenswert">
<icon BUILTIN="yes"/>
<node COLOR="#435e98" CREATED="1728780706437" ID="ID_1189363469" MODIFIED="1731900746368" TEXT="der Runtime-Basis-Seed sollte kontrollierbar sein">
<richcontent TYPE="NOTE"><html>
@ -92333,7 +92321,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
<icon BUILTIN="yes"/>
<node CREATED="1731892905040" ID="ID_1699520990" MODIFIED="1731892912937" TEXT="bisher ist der Seed statisch-global"/>
<node COLOR="#5b280f" CREATED="1731892905040" ID="ID_1699520990" MODIFIED="1732112520451" TEXT="bisher ist der Seed statisch-global">
<icon BUILTIN="button_cancel"/>
</node>
<node COLOR="#435e98" CREATED="1731892914045" ID="ID_1339262498" MODIFIED="1731900841736" TEXT="m&#xfc;&#xdf;te diesen vom Test-Seed her kontrollieren k&#xf6;nnen">
<icon BUILTIN="yes"/>
</node>
@ -92379,10 +92369,16 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1731894841452" ID="ID_1246150422" MODIFIED="1732077402965" TEXT="Storage besser als Deque (damit Adressen stabil bleiben)">
<icon BUILTIN="flag-pink"/>
<node COLOR="#338800" CREATED="1731894841452" ID="ID_1246150422" MODIFIED="1732111735905" TEXT="Storage nun als Deque realisiert">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1732111752793" ID="ID_1044298124" MODIFIED="1732111781055" TEXT="weniger Speicherverschwendung">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1728778765874" ID="ID_1342398369" MODIFIED="1732077408909" TEXT="der Metadatenblock sollte am Ende sein">
<node COLOR="#435e98" CREATED="1732111737183" ID="ID_1910157810" MODIFIED="1732111781054" TEXT="Adressen bleiben stabil">
<icon BUILTIN="idea"/>
</node>
</node>
<node COLOR="#338800" CREATED="1728778765874" ID="ID_1342398369" MODIFIED="1732111711933" TEXT="der Metadatenblock sollte am Ende sein">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1728778790871" ID="ID_92579679" MODIFIED="1732077410923" TEXT="Metadaten sollten optional sein">
@ -92485,8 +92481,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731890664306" ID="ID_127090859" MODIFIED="1731890736163" TEXT="wird schon f&#xfc;r erste Tests im Vorgriff ben&#xf6;tigt">
<arrowlink COLOR="#911932" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="-554;-1251;" ID="Arrow_ID_1343565956" STARTARROW="None" STARTINCLINATION="-195;12;"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1731890664306" ID="ID_127090859" MODIFIED="1732112501967" TEXT="wird schon f&#xfc;r erste Tests im Vorgriff ben&#xf6;tigt">
<arrowlink COLOR="#192c91" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="-554;-1251;" ID="Arrow_ID_1343565956" STARTARROW="None" STARTINCLINATION="-195;12;"/>
<icon BUILTIN="yes"/>
</node>
</node>
@ -92884,12 +92880,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786359782" ID="ID_525505656" MODIFIED="1728786374933" TEXT="Spec und Seed generieren und verarbeiten">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1728786385349" ID="ID_442258905" MODIFIED="1731890736163" TEXT="Umbau TestFrame">
<arrowlink COLOR="#713558" DESTINATION="ID_257931093" ENDARROW="Default" ENDINCLINATION="-2466;135;" ID="Arrow_ID_121875527" STARTARROW="None" STARTINCLINATION="-2154;-229;"/>
<linktarget COLOR="#911932" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="-554;-1251;" ID="Arrow_ID_1343565956" SOURCE="ID_127090859" STARTARROW="None" STARTINCLINATION="-195;12;"/>
<node COLOR="#338800" CREATED="1728786385349" ID="ID_442258905" MODIFIED="1732112467377" TEXT="Umbau TestFrame">
<arrowlink COLOR="#4b3571" DESTINATION="ID_257931093" ENDARROW="Default" ENDINCLINATION="-2466;135;" ID="Arrow_ID_121875527" STARTARROW="None" STARTINCLINATION="-2154;-229;"/>
<linktarget COLOR="#192c91" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="-554;-1251;" ID="Arrow_ID_1343565956" SOURCE="ID_127090859" STARTARROW="None" STARTINCLINATION="-195;12;"/>
<linktarget COLOR="#77313e" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="381;-48;" ID="Arrow_ID_1047269362" SOURCE="ID_936086670" STARTARROW="None" STARTINCLINATION="-36;80;"/>
<linktarget COLOR="#6f2328" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="366;-47;" ID="Arrow_ID_1067356199" SOURCE="ID_683548249" STARTARROW="None" STARTINCLINATION="5;52;"/>
<icon BUILTIN="pencil"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1730900637026" ID="ID_1500320757" MODIFIED="1731890421828" TEXT="brauche Einflu&#xdf; auf den PRNG">
<richcontent TYPE="NOTE"><html>
<head/>
@ -92903,7 +92899,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
<node COLOR="#474398" CREATED="1731890427683" HGAP="89" ID="ID_616909963" MODIFIED="1731890459593" TEXT="Seed f&#xfc;r Testf&#xe4;lle &#x27f9; defaultGen verwenden" VSHIFT="10"/>
</node>
<node CREATED="1730900645921" ID="ID_1469990348" MODIFIED="1730901263434" TEXT="brauche Umstellung des Headers">
<node COLOR="#338800" CREATED="1730900645921" ID="ID_1469990348" MODIFIED="1732112443499" TEXT="brauche Umstellung des Headers">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -92912,8 +92908,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1730900658104" ID="ID_1382506504" MODIFIED="1730900815598" TEXT="brauche Daten-Pr&#xfc;fsumme auch nach Manipulation">
<node COLOR="#338800" CREATED="1730900658104" ID="ID_1382506504" MODIFIED="1732112447950" TEXT="brauche Daten-Pr&#xfc;fsumme auch nach Manipulation">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -92922,6 +92919,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1732112455819" ID="ID_1055009498" MODIFIED="1732112465158" TEXT="sp&#xe4;ter nachr&#xfc;stbar: Lifecycle">
<icon BUILTIN="hourglass"/>
</node>
</node>
</node>