OutputSlot: skeleton for a lightweight new tracking implementation

- can now throw away the old convoluted `TrackingInMemoryBlockSequence`
- instead use a simplistic implementation of the Connection interface
- do not perform any kind of validation, allocate new buffer for each frame
- use the `NaiveBufferSetup` (`BufferProvider`) as implementation backend.
This commit is contained in:
Fischlurch 2026-03-23 23:19:09 +01:00
parent bd09d9fbbb
commit ec9b73d418
3 changed files with 215 additions and 360 deletions

View file

@ -18,45 +18,110 @@
*/
#include "lib/error.hpp"
#include "lib/integral.hpp"
#include "lib/nocopy.hpp"
#include "vault/out/diagnostic-output-slot.hpp"
//#include "vault/out/output-slot-connection.hpp"
#include "vault/mem/buffhandle.hpp"
#include "vault/mem/naive-buffer-setup.hpp"
#include "vault/real-clock.hpp"
#include "lib/util.hpp"
//#include <vector>
#include <utility>
#include <algorithm>
#include <functional>
#include <map>
using util::contains;
// using std::vector;
// using Config = DiagnosticOutputSlot::Config;
using std::byte;
using std::move;
using std::make_unique;
using std::make_shared;
using std::function;
using vault::mem::NaiveBufferSetup;
using vault::mem::BuffHandle;
using vault::mem::BuffDescr;
namespace vault {
namespace out {
namespace err = lumiera::error;
// using std::vector;
// using Config = DiagnosticOutputSlot::Config;
using std::move;
using std::make_unique;
namespace { // Implementation details of tracking
inline void
zeroFill (void* buf, size_t siz)
{
auto begin = static_cast<byte*> (buf);
std::fill (begin, begin+siz, byte(0));
}
}//(End)Impl details
class DiagnosticOutputSlot::OutputTracker
: public Config
, util::NonCopyable
{
std::vector<diagn::FeedLog> feed_;
NaiveBufferSetup buffProvider_;
BuffDescr bufferType_;
public:
OutputTracker (Config&& config)
: Config{move (config)}
, feed_{config.numDataFeeds}
, buffProvider_{}
, bufferType_{buffProvider_.getDescriptorFor (bufferSize
,mem::TypeHandler{[siz=bufferSize](void* buff){ zeroFill (buff, siz);}
,[](void*){ /* do nothing on release */ }
})}
{ }
/** configurable functor: what is used as _current time_
* @remark allows the test framework to mark "now" as some
* specific fixed time; default is to return system time
*/
function<Time()> currentTime{[]{ return RealClock::now(); }};
BuffHandle
getNewBuffer()
{
return bufferType_.lockBuffer();
}
diagn::FeedLog const&
getFeed (uint feedNr)
{
REQUIRE (feedNr < feed_.size());
return feed_[feedNr];
}
};
/**
* Front-end for access by test code.
* @note tolerates access to arbitrary feeds
*/
diagn::FeedLog const&
OutputDiagnostic::feed (uint feedNr)
{
if (feedNr < dos_.tracker_->numDataFeeds)
return dos_.tracker_->getFeed (feedNr);
else
return lib::NullValue<diagn::FeedLog>::get();
}
class DiagnosticOutputSlot::DummyConnection
: public OutputSlot::Connection
, util::NonCopyable
{
OutputTracker& tracker_;
std::map<Buff*, BuffHandle> buffIdx_;
/* === Connection API === */
@ -69,19 +134,31 @@ namespace out {
Buff*
claimBufferFor(FrameID frame) override
{
UNIMPLEMENTED ("lock new buffer");
BuffHandle handle = tracker_.getNewBuffer();
REQUIRE (handle.isValid());
Buff* buff = handle.rawStorage();
ENSURE (not contains (buffIdx_, buff));
buffIdx_.insert ({buff, handle});
UNIMPLEMENTED ("track new buffer");
return buff;
}
void
publish (Buff* buff) override
{
UNIMPLEMENTED ("publish buffer");
REQUIRE (contains (buffIdx_,buff));
auto handle = buffIdx_.find(buff)->second;
handle.emit();
UNIMPLEMENTED ("track publish buffer");
}
void
release (Buff* buff) override
{
UNIMPLEMENTED ("release buffer");
REQUIRE (contains (buffIdx_,buff));
auto handle = buffIdx_.find(buff)->second;
handle.release();
UNIMPLEMENTED ("track release buffer");
}
void
@ -130,7 +207,7 @@ namespace out {
shared_ptr<DiagnosticOutputSlot::OutputTracker>
DiagnosticOutputSlot::setupOutputTracker (Config&& config)
{
return make_shared<OutputTracker> (move (config));
}
unique_ptr<OutputSlot::Allocation>
@ -143,11 +220,6 @@ namespace out {
,[&](ConStorage& storage){ storage.create<DummyConnection> (outputTracker); }
);
}
/** */

View file

@ -70,188 +70,8 @@ namespace out {
namespace { // diagnostics & internals....
const uint DEFAULT_DATAFEEDS = 5;
inline PGrid
getTestTimeGrid()
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
Symbol gridID("DiagnosticOutputSlot-buffer-grid");
vessel::advice::Request<PGrid> query4grid(gridID) ;
PGrid testGrid25 = query4grid.getAdvice();
if (!testGrid25)
testGrid25 = TimeGrid::build (gridID, FrameRate::PAL);
ENSURE (testGrid25);
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
PGrid testGrid; ////////OOO Kaboooom!
return testGrid;
}
}
/**
* Diagnostic output connection for a single channel,
* allowing to track generated frames and verify
* the processing protocol for output buffers.
*/
class TrackingInMemoryBlockSequence
: public OutputSlot::Connection
, util::NonCopyable
{
typedef std::unordered_set<FrameID> FrameTrackingInfo;
NaiveBufferSetup buffProvider_;
BuffDescr bufferType_;
FrameTrackingInfo frameTrackingIndex_;
PGrid frameGrid_;
bool closed_;
BuffHandle
trackFrame (FrameID frameNr, BuffHandle const& newBuffer)
{
TRACE (test, "Con=%p : track buffer %zu for frame-#%lu"
, this, HashVal(newBuffer), frameNr);
REQUIRE (!contains (frameTrackingIndex_,frameNr),
"attempt to lock already used frame %lu", frameNr);
frameTrackingIndex_.insert (frameNr);
return newBuffer;
}
TimeValue
deadlineFor (FrameID frameNr)
{
// a real world implementation
// would offset by a latency here
return frameGrid_->timeOf (frameNr);
}
/* === Connection API === */
size_t
getBufferSize() const override
{
UNIMPLEMENTED ("wtf buff?");
}
Buff*
claimBufferFor (FrameID frameNr) override
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code due to OutputSlot refactoring
TRACE (test, "Con=%p : lock buffer for frame-#%lu", this, frameNr);
REQUIRE (!closed_);
return trackFrame (frameNr,
buffProvider_.lockBuffer (bufferType_));
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
}
void
publish (Buff* filledBuffer) override
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code due to OutputSlot refactoring
TRACE (test, "Con=%p : transfer buffer %zu"
, this, HashVal(filledBuffer));
REQUIRE (!closed_);
pushout (filledBuffer);
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
}
void
release (Buff* data4output) override
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code due to OutputSlot refactoring
REQUIRE (!closed_);
buffProvider_.emitBuffer (data4output);
buffProvider_.releaseBuffer(data4output);
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
}
void
shutDown() override
{
closed_ = true;
}
public:
TrackingInMemoryBlockSequence()
: buffProvider_()
, bufferType_(buffProvider_.getDescriptor<TestFrame>())
, frameTrackingIndex_()
, frameGrid_(getTestTimeGrid()) /////////////TODO should rather pass that in as part of a "timings" definition
, closed_(false)
{
INFO (engine_dbg, "building in-memory diagnostic output sequence (at %p)", this);
}
virtual
~TrackingInMemoryBlockSequence()
{
INFO (engine_dbg, "releasing diagnostic output sequence (at %p)", this);
}
/* === Diagnostic API === */
TestFrame const *
accessEmittedFrame (uint frameNr) const
{
UNIMPLEMENTED ("suitable diagnostic API");
// if (frameNr < buffProvider_.emittedCnt()) ///////////////////////////////OOO provide suitable diagnostic API!
// return & accessFrame(frameNr);
// else
// return 0; ////////////////////////////////TICKET #856
}
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
diagn::Block const *
accessEmittedBuffer (uint bufferNr) const
{
UNIMPLEMENTED ("suitable diagnostic API");
// if (bufferNr < buffProvider_.emittedCnt()) ///////////////////////////////OOO provide suitable diagnostic API!
// return & accessBlock(bufferNr);
// else
// return 0;
}
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
bool
wasAllocated (uint frameNr) const
{
TRACE (test, "query wasAllocated. Con=%p", this);
return contains (frameTrackingIndex_, frameNr);
}
private:
TestFrame const&
accessFrame (uint frameNr) const
{
UNIMPLEMENTED ("suitable diagnostic API");
// return unConst(this)->buffProvider_.accessAs<TestFrame> (frameNr); ///////////////////////////////OOO provide suitable diagnostic API!
}
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
diagn::Block const&
accessBlock (uint bufferNr) const
{
UNIMPLEMENTED ("suitable diagnostic API");
// return unConst(this)->buffProvider_.access_emitted (bufferNr); ///////////////////////////////OOO provide suitable diagnostic API!
}
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
};
///////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1395 : draft compatible Tracking-API
@ -338,67 +158,6 @@ namespace out {
class DiagnosticOutputSlot
: public OutputSlot
{
static const uint MAX_CHANNELS = 5; ///////////////////////////////OOO Build heap-based implementation with arbitrary number of feeds!!
/** @note a real OutputSlot implementation
* would rely on some kind of embedded
* configuration here */
uint
getOutputChannelCount()
{
return MAX_CHANNELS; /////////////OOO No!
}
/**
* Special diagnostic connection state implementation,
* establishing diagnostic output connections for each channel,
* thus allowing to verify the handling of individual buffers
*/
class SimulatedOutputSequences
: public AllocState<TrackingInMemoryBlockSequence>
{
using _Base = AllocState<TrackingInMemoryBlockSequence>;
public:
SimulatedOutputSequences (uint numChannels)
: _Base{ numChannels
,[](ConnectionStorage& storage)
{
UNIMPLEMENTED ("new Tracking implementation for DiagnosticOutputSlot");
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
storage.create<TrackingInMemoryBlockSequence>();
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
}}
{ }
};
/** hook into the OutputSlot frontend */
unique_ptr<Allocation>
buildState()
{
return make_unique<SimulatedOutputSequences> (
getOutputChannelCount());
}
/** @internal access the implementation object
* representing a single stream connection
*/
TrackingInMemoryBlockSequence const&
accessSequence (uint channel)
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
REQUIRE (!isFree(), "diagnostic OutputSlot not (yet) connected");
REQUIRE (channel <= getOutputChannelCount());
// return static_cast<TrackingInMemoryBlockSequence&> (state_->access (channel));
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
UNIMPLEMENTED ("the old tracking API is abandoned, the new one not yet implemented");
}
class OutputTracker;
shared_ptr<OutputTracker> tracker_;
@ -446,95 +205,6 @@ namespace out {
static shared_ptr<OutputTracker> setupOutputTracker(Config&&);
static unique_ptr<Allocation> setupTrackingConnections(OutputTracker&);
/* === diagnostics API === */
/**
* diagnostic facility to verify test data frames
* written to this Test/Dummy "output". It exposes
* the emitted Data as a sequence of TestFrame objects.
*/
class OutputFramesLog
: public lib::IterSource<const TestFrame>
, util::NonCopyable
{
TrackingInMemoryBlockSequence const& outSeq_;
uint currentFrame_;
virtual Pos //////////////////////////////////////////////TICKET #1125 : this API should use three control functions, similar to IterStateWrapper
firstResult () override
{
REQUIRE (0 == currentFrame_);
return outSeq_.accessEmittedFrame (currentFrame_);
}
virtual void
nextResult (Pos& pos) override
{
++currentFrame_;
pos = outSeq_.accessEmittedFrame(currentFrame_);
}
public:
OutputFramesLog (TrackingInMemoryBlockSequence const& bs)
: outSeq_(bs)
, currentFrame_(0)
{ }
};
typedef OutputFramesLog::iterator OutFrames;
OutFrames
getChannel (uint channel)
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
REQUIRE (channel < MAX_CHANNELS);
return OutputFramesLog::build(
new OutputFramesLog (
accessSequence(channel)));
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
}
bool
frame_was_allocated (uint channel, FrameID nominalFrame)
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
return accessSequence(channel)
.wasAllocated(nominalFrame);
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
}
bool
output_was_emitted (uint channel, FrameID outputFrame)
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
diagn::Block const *block = accessSequence(channel)
.accessEmittedBuffer(outputFrame);
return block
and block->was_used();
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
}
bool
output_was_closed (uint channel, FrameID outputFrame)
{
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
diagn::Block const *block = accessSequence(channel)
.accessEmittedBuffer(outputFrame);
return block
and block->was_closed();
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
}
///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1395 : draft compatible Tracking-API
std::vector<diagn::FeedLog> feed_;
private:
/// „backdoor“ to watch instrumentation from tests
friend class OutputDiagnostic;
@ -556,14 +226,8 @@ namespace out {
uint cntEmitted() { return 0; }
uint cntReleased() { return 0; }
auto const&
feed (uint feedNr)
{
if (feedNr < dos_.feed_.size())
return dos_.feed_[feedNr];
else
return lib::NullValue<diagn::FeedLog>::get();
}
diagn::FeedLog const&
feed (uint feedNr);
auto
getFeed (uint feedNr)

View file

@ -138012,7 +138012,9 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</body>
</html></richcontent>
</node>
<node CREATED="1773156516269" ID="ID_1341134692" MODIFIED="1773156541757" TEXT="die Test-Implementierung sehe ich als Prototyp bez&#xfc;glich der Konsistenz-Limits"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1773156516269" ID="ID_1341134692" MODIFIED="1774313455147" TEXT="die Test-Implementierung sehe ich als Prototyp bez&#xfc;glich der Konsistenz-Limits">
<icon BUILTIN="hourglass"/>
</node>
<node CREATED="1773156543145" ID="ID_364217869" MODIFIED="1773156636849" TEXT="wenn ich sie &#xfc;berhaupt jetzt entwickle....">
<richcontent TYPE="NOTE"><html>
<head/>
@ -138023,9 +138025,11 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</body>
</html></richcontent>
</node>
<node CREATED="1773156642079" ID="ID_1747459491" MODIFIED="1773156658302" TEXT="zun&#xe4;chst wird nur die unlimitierte H&#xfc;lle ben&#xf6;tigt, um das Protokoll zu testen"/>
<node CREATED="1773156642079" ID="ID_1747459491" MODIFIED="1774313466273" TEXT="zun&#xe4;chst wird nur die unlimitierte H&#xfc;lle ben&#xf6;tigt, um das Protokoll zu testen">
<icon BUILTIN="forward"/>
</node>
<node CREATED="1773156927734" ID="ID_1001788653" MODIFIED="1773156986131">
</node>
<node CREATED="1773156927734" ID="ID_1001788653" MODIFIED="1774313715117">
<richcontent TYPE="NODE"><html>
<head/>
<body>
@ -138034,8 +138038,22 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</p>
</body>
</html></richcontent>
<linktarget COLOR="#5d70c1" DESTINATION="ID_1001788653" ENDARROW="Default" ENDINCLINATION="-43;224;" ID="Arrow_ID_1160346481" SOURCE="ID_904888776" STARTARROW="None" STARTINCLINATION="-252;22;"/>
<node CREATED="1773157002897" ID="ID_365322825" MODIFIED="1773157028020" TEXT="also analog zum Baumuster des DiagnostricBufferProviders"/>
<node CREATED="1773157051468" ID="ID_241171757" MODIFIED="1773157072045" TEXT="Zugriffs-Koordinaten hier: (Feed, Frame-#)"/>
<node CREATED="1774313511825" ID="ID_1418663316" MODIFIED="1774313523997" TEXT="&#xbb;aktuelle Zeit&#xab;">
<node CREATED="1774313531713" ID="ID_207817399" MODIFIED="1774313544434" TEXT="wenn man nichts tut &#x27f9; Systemzeit"/>
<node CREATED="1774313545590" ID="ID_795095840" MODIFIED="1774313663235" TEXT="man kann &#xfc;ber das front-End (DiagnosticBufferProvider) eine explizite Zeit setzen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Diese Zeit ist dann fest &#10233; hei&#223;t, wir brauchen einen Funktor, der entweder die Systemzeit holt (&#8793;default) oder eben eine feste Zeit liefert. &#187;Zeit&#171; &#8801; Lumiera <font face="Monospaced" color="#2717bc">Time</font>
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
</node>
</node>
@ -139349,16 +139367,117 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<node BACKGROUND_COLOR="#f6b3ac" COLOR="#de0131" CREATED="1774301911034" ID="ID_401388335" MODIFIED="1774301965608" TEXT="&#x21af; Widerspruch: mu&#xdf; das 2.Sub-Objekt vor der 1.Sub-Objekt initialisieren"/>
</node>
<node CREATED="1774302051343" ID="ID_697693360" MODIFIED="1774302068409" TEXT="L&#xf6;sung durch einen &#xbb;Kniff&#xab; : Setup-Kontext verwenden">
<node CREATED="1774302073970" ID="ID_143320134" MODIFIED="1774302113870">
<node CREATED="1774302073970" ID="ID_143320134" MODIFIED="1774309955517">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
dieser wird <b>transient</b>&#160;als Konstruktor-Argument gebaut
dieser wird <b><font color="#af0444">transient</font></b>&#160;als Konstruktor-Argument gebaut
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1774309961821" ID="ID_1353442544" MODIFIED="1774309978978" TEXT="sch&#xf6;n ist das nicht.... (aber wei&#xdf; mir nicht anders zu helfen)"/>
<node CREATED="1774309988668" ID="ID_1524302929" MODIFIED="1774310010050" TEXT="versuche es wenigstens kompakt und direkt beieinander, im CPP-File zu implementieren"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774310011821" ID="ID_704173608" MODIFIED="1774310448640" TEXT="AUA: da renne ich in einen Compiler-Bug">
<icon BUILTIN="broken-line"/>
<node CREATED="1774310037582" ID="ID_47223426" LINK="https://stackoverflow.com/q/53408962/444796" MODIFIED="1774310068787" TEXT="Stackoverflow: default member initializer required before the end of its enclosing class"/>
<node CREATED="1774310070042" ID="ID_1247531069" MODIFIED="1774310076413" TEXT="das verweist auf GCC-Bugs">
<node CREATED="1774310094678" ID="ID_628309521" LINK="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165" MODIFIED="1774310181375" TEXT="#88165"/>
<node CREATED="1774310176164" ID="ID_77624999" LINK="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96645" MODIFIED="1774310185071" TEXT="#96645"/>
</node>
<node CREATED="1774310190403" ID="ID_1966511111" MODIFIED="1774310209939" TEXT="tats&#xe4;chlich ist es eine unerwartete Komplexit&#xe4;t in der Sprachdefinition"/>
<node CREATED="1774310210990" ID="ID_959033974" MODIFIED="1774310227896" TEXT="Konsens it da&#xdf; sich normale und getemplatete Klassen gleich verhalten sollten"/>
<node CREATED="1774310228884" ID="ID_1971950950" MODIFIED="1774310258180" TEXT="das bedeutet: der Compiler mu&#xdf; w&#xe4;hrend der Instantiierung &#xbb;on demand&#xab; parsen"/>
<node CREATED="1774310283474" ID="ID_1683437341" LINK="https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2335" MODIFIED="1774310305820" TEXT="Thema f&#xfc;r die Core-Working-Group (#2335)"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1774310309818" ID="ID_1429216112" MODIFIED="1774310317331" TEXT="auch Ende 2025 noch nicht gel&#xf6;st">
<icon BUILTIN="hourglass"/>
</node>
<node CREATED="1774310329862" ID="ID_106696939" MODIFIED="1774310364545" TEXT="konkret ist hier das default-Argument f&#xfc;r den Konstruktor der Ausl&#xf6;ser">
<icon BUILTIN="idea"/>
<node CREATED="1774310367348" ID="ID_1876437770" MODIFIED="1774310392930" TEXT="wir haben einen offiziellen Konstruktor, der eine Config nimmt"/>
<node CREATED="1774310393702" ID="ID_529684221" MODIFIED="1774310410166" TEXT="wir wollen aber auch default-Konstruktion gestatten"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1774310416603" ID="ID_828591057" MODIFIED="1774310444303" TEXT="&#x27f9; Workaround: statische Funktion Config::defaults()">
<icon BUILTIN="idea"/>
</node>
</node>
</node>
</node>
</node>
<node CREATED="1774313226716" ID="ID_1611061420" MODIFIED="1774313232907" TEXT="Connection verschalten">
<node CREATED="1774313235118" ID="ID_80195731" MODIFIED="1774313392812">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
Beschlu&#223;: zun&#228;chst Basis-Funktionalit&#228;t <i>ohne jedwede Konsistenzchecks</i>
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Das war vermutlich die Stelle, an der ich <i>damals falsch abgebogen bin:</i>&#160; Ich wollte, test-getrieben, das ganze Thema der &#187;Konsistenz-Checks und Timings&#171; ausloten. Dazu habe ich dann <i>fantasiert, was denn &#187;Konsistenz&#171; meinen k&#246;nnte.</i>
</p>
<p>
</p>
<p>
Dem entsprechend werde ich dieses mal versuchen, die d&#228;mlichst-m&#246;gliche Implementierung zu bauen: wer einen Buffer will, bekommt ihn. Wir zeichnen lediglich diesen Umstand auf
</p>
</body>
</html></richcontent>
<icon BUILTIN="yes"/>
</node>
<node CREATED="1774313938386" ID="ID_1806140175" MODIFIED="1774317911805" TEXT="der BufferProvider bleibt dieses mal ein reines Implementation-detail">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Konsequenz: sogar &#252;ber das interne Tracking-API schicken wir nur Buff*
</p>
</body>
</html></richcontent>
<icon BUILTIN="yes"/>
<node CREATED="1774313956016" ID="ID_1633203630" MODIFIED="1774314011532" TEXT="lokale Instanz verwenden">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Kein Zugriff auf irgend einen Service hier. Das ist Konsequenz daraus, da&#223; wir diese Komponente in die Vault verlegt haben
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1774313971742" ID="ID_1459227613" MODIFIED="1774313980329" TEXT="NaiveBufferSetup (fix eingebaut)"/>
</node>
<node CREATED="1774315799899" ID="ID_8599109" MODIFIED="1774315854340" TEXT="&#x27f9; braucht einen Index (bufferAdr &#x27fc; Buffhandle)">
<node CREATED="1774315909451" ID="ID_339790699" MODIFIED="1774315916581" TEXT="da reicht eine ganz banale std::map"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#4a0f69" CREATED="1774317846000" ID="ID_572836039" MODIFIED="1774317868679" TEXT="aber aufpassen: BuffHandle hat keinen default-ctor">
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
</node>
<node CREATED="1774313219258" ID="ID_1837524398" MODIFIED="1774313225581" TEXT="Tracking-Implementierung">
<node CREATED="1774313683158" ID="ID_904888776" MODIFIED="1774313720723" TEXT="was aufgezeichnert werden soll">
<arrowlink COLOR="#5d70c1" DESTINATION="ID_1001788653" ENDARROW="Default" ENDINCLINATION="-43;224;" ID="Arrow_ID_1160346481" STARTARROW="None" STARTINCLINATION="-252;22;"/>
<icon BUILTIN="yes"/>
<node CREATED="1774313743804" ID="ID_334644227" MODIFIED="1774313749151" TEXT="feed-#"/>
<node CREATED="1774313749971" ID="ID_1776230198" MODIFIED="1774313752919" TEXT="frame-#"/>
<node CREATED="1774313754547" ID="ID_797609217" MODIFIED="1774313760862" TEXT="&#xbb;current time&#xab;">
<node COLOR="#338800" CREATED="1774318367123" ID="ID_1073212702" MODIFIED="1774318394316" TEXT="als konfigurierbarer Funktor implementiert">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1774318378178" ID="ID_85517080" MODIFIED="1774318391616" TEXT="default: RealClock::now()">
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1774313793926" ID="ID_561878743" MODIFIED="1774313798232" TEXT="storage-Pointer"/>
</node>
<node CREATED="1774313840079" ID="ID_120795235" MODIFIED="1774313850029" TEXT="l&#xe4;uft auf eine einfache, zweistufige Storage hinaus">
<node CREATED="1774313851211" ID="ID_1742918623" MODIFIED="1774313860168" TEXT="Ebene-1 : Vector aller Feeds"/>
<node CREATED="1774313884113" ID="ID_483675708" MODIFIED="1774313922576" TEXT="Ebene-2 : Hashtable mit frameNr als Key"/>
</node>
</node>
</node>