Library: observe allocator limits on exponential expansion

The `SeveralBuilder` employs the same tactic as `std::vector`,
by over-allocating a reserve buffer, which grows in exponential
increments, to amortise better the costs of re-allocation.

This tactic does not play well with space limited allocators
like `AllocationCluster` however; it is thus necessary to provide
an extension point where the actuall allocator's limitation can be
queried, allowing to use what is available as reserve, but not more.

With these adaptations, a full usage cycle backed by `AllocationCluster`
can be demonstrated, including variations of dynamic allocation adjustment.
This commit is contained in:
Fischlurch 2024-06-19 17:35:46 +02:00
parent 39e9ecd90e
commit cf6abf6a3b
4 changed files with 141 additions and 70 deletions

View file

@ -352,7 +352,11 @@ namespace lib {
{
using Base = AllocationPolicy<I,E,Adapter>;
using Bucket = typename Base::Bucket;
/** @warning allocation size is severely limited in AllocationCluster. */
size_t static constexpr ALLOC_LIMIT = AllocationCluster::max_size();
Policy (AllocationCluster& clu)
: AllocationPolicy<I,E,Adapter> (clu.getAllocator<std::byte>())
{ }

View file

@ -166,6 +166,12 @@ namespace lib {
return req;
}
size_t inline constexpr
alignRes (size_t alignment)
{
return positiveDiff (alignment, alignof(void*));
}
template<class I, template<typename> class ALO>
class ElementFactory
@ -200,8 +206,7 @@ namespace lib {
REQUIRE (cnt);
REQUIRE (spread);
size_t storageBytes = Bucket::storageOffset + cnt*spread;
if (alignment > alignof(void*)) // over-aligned data => reserve for alignment padding
storageBytes += (alignment - alignof(void*));
storageBytes += alignRes (alignment); // over-aligned data => reserve for alignment padding
// Step-1 : acquire the raw storage buffer
std::byte* loc = AlloT::allocate (baseAllocator(), storageBytes);
ENSURE (0 == size_t(loc) % alignof(void*));
@ -278,6 +283,9 @@ namespace lib {
using Fac::Fac; // pass-through ctor
/** by default assume that memory is practically unlimited... */
size_t static constexpr ALLOC_LIMIT = size_t(-1) / sizeof(E);
bool canExpand(Bucket*, size_t){ return false; }
Bucket*
@ -533,16 +541,20 @@ namespace lib {
{// grow into exponentially expanded new allocation
if (spread > Coll::spread())
cnt = max (cnt, buffSiz / Coll::spread()); // retain reserve
size_t overhead = sizeof(Bucket) + alignRes(alignof(E));
size_t safetyLim = LUMIERA_MAX_ORDINAL_NUMBER * Coll::spread();
size_t expandAlloc = min (safetyLim
size_t expandAlloc = min (positiveDiff (min (safetyLim
,POL::ALLOC_LIMIT)
,overhead)
,max (2*buffSiz, cnt*spread));
// round down to an even number of elements
size_t newCnt = expandAlloc / spread;
expandAlloc = newCnt * spread;
if (expandAlloc < demand)
throw err::State{_Fmt{"Storage expansion for Several-collection "
"exceeds safety limit of %d bytes"} % safetyLim
,LERR_(SAFETY_LIMIT)};
// allocate new storage block...
size_t newCnt = expandAlloc / spread;
if (newCnt * spread < expandAlloc) ++newCnt;
Coll::data_ = POL::realloc (Coll::data_, newCnt,spread);
}
ENSURE (Coll::data_);

View file

@ -556,7 +556,8 @@ namespace test{
/** @test TODO demonstrate integration with a custom allocator
* - use the TrackingAllocator to verify balanced handling
* of the underlying raw memory allocations
* @todo WIP 6/24 🔁 define 🔁 implement
* - use an AllocationCluster instance to manage the storage
* @todo WIP 6/24 🔁 define implement
*/
void
check_CustomAllocator()
@ -610,38 +611,67 @@ namespace test{
{
auto builder = makeSeveral<Dummy>()
.withAllocator(clu)
.reserve(4)
.fillElm(4);
.reserve(4) // use a limited pre-reservation
.fillElm(4); // fill all the allocated space with 4 new elements
size_t buffSiz = sizeof(Dummy) * builder.capacity();
size_t headerSiz = sizeof(ArrayBucket<Dummy>);
expectedAlloc = headerSiz + buffSiz;
SHOW_EXPR(expectedAlloc)
SHOW_EXPR(builder.size())
CHECK (4 == builder.size());
SHOW_EXPR(builder.capacity())
CHECK (4 == builder.capacity());
SHOW_EXPR(clu.numExtents())
CHECK (1 == clu.numExtents()); // AllocationCluster has only opened one extent thus far
SHOW_EXPR(clu.numBytes())
builder.append (Dummy{23});
CHECK (expectedAlloc == clu.numBytes()); // and the allocated space matches the demand precisely
builder.append (Dummy{23}); // now request to add just one further element
SHOW_EXPR(builder.capacity())
CHECK (8 == builder.capacity()); // ...which causes the builder to double up the reserve capacity
buffSiz = sizeof(Dummy) * builder.capacity();
expectedAlloc = headerSiz + buffSiz;
SHOW_EXPR(buffSiz)
SHOW_EXPR(buffSiz + expectedAlloc)
SHOW_EXPR(buffSiz + headerSiz)
SHOW_EXPR(builder.size())
SHOW_EXPR(builder.capacity())
SHOW_EXPR(clu.numExtents())
CHECK (1 == clu.numExtents()); // However, AllocationCluster was able to adjust allocation in-place
SHOW_EXPR(clu.numBytes())
CHECK (expectedAlloc == clu.numBytes()); // and thus the new increased buffer is still placed in the first extent
// now perform another unrelated allocation
Dummy& extraDummy = clu.create<Dummy>(55);
SHOW_EXPR(clu.numExtents())
CHECK (1 == clu.numExtents());
SHOW_EXPR(clu.numBytes())
builder.reserve(9);
CHECK (clu.numBytes() > expectedAlloc + sizeof(Dummy)); // but now we've used some further space behind that point
builder.reserve(9); // ...which means that the AllocationCluster can no longer adjust dynamically
SHOW_EXPR(builder.size())
CHECK (5 == builder.size()); // .....because this is only possible on the latest allocation opened
SHOW_EXPR(builder.capacity())
CHECK (9 <= builder.capacity()); // And while we still got out increased capacity,
SHOW_EXPR(clu.numExtents())
CHECK (2 == clu.numExtents()); // this was only possible by wasting space and copying into a new extent
SHOW_EXPR(clu.numBytes())
}
buffSiz = sizeof(Dummy) * builder.capacity();
expectedAlloc = headerSiz + buffSiz;
CHECK (expectedAlloc <= AllocationCluster::max_size());
CHECK (clu.numBytes() == AllocationCluster::max_size()
+ expectedAlloc);
elms = builder.build(); // Note: assigning to the existing front-end (which is storage agnostic)
CHECK (5 == elms.size());
CHECK (23 == elms.back().getVal());
CHECK (55 == extraDummy.getVal());
} // Now the Builder and the ExtraDummy is gone...
CHECK (5 == elms.size()); // while all created elements are still there, sitting in the Allocationcluster
CHECK (23 == elms.back().getVal());
CHECK (2 == clu.numExtents());
}
};

View file

@ -83011,6 +83011,42 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#338800" CREATED="1717776981387" ID="ID_631542593" MODIFIED="1717776987939" TEXT="safety-Limit einbauen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1718807497816" ID="ID_1980443647" MODIFIED="1718807994990" TEXT="hier m&#xf6;gliche Beschr&#xe4;nkung des Allokators ber&#xfc;cksichtigen">
<linktarget COLOR="#313f5b" DESTINATION="ID_1980443647" ENDARROW="Default" ENDINCLINATION="364;849;" ID="Arrow_ID_1834035862" SOURCE="ID_1147918184" STARTARROW="None" STARTINCLINATION="411;-39;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1718807514255" ID="ID_1358531504" MODIFIED="1718807523426" TEXT="Heap-Allokator">
<node CREATED="1718807524400" ID="ID_217027432" MODIFIED="1718807533072" TEXT="man tut so als w&#xe4;re der Speicher unlimitiert"/>
<node CREATED="1718807533792" ID="ID_997139807" MODIFIED="1718807576331" TEXT="Trick: size_t(-1) / sizeof(_Tp);">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
gefunden in: new_allocator.h, Line 130
</p>
</body>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1718807578126" ID="ID_1117957272" MODIFIED="1718807581505" TEXT="Allocation-Cluster">
<node CREATED="1718807582629" ID="ID_1988432026" MODIFIED="1718807590482" TEXT="die Policy kann hier direkt anfragen"/>
<node CREATED="1718807591156" ID="ID_431366288" MODIFIED="1718807636644" TEXT="AllocationCluster::max_size()">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
zieht noch einen internen Admin-Overhead ab von der Extent-Size
</p>
</body>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1718807639230" ID="ID_1297078784" MODIFIED="1718810185655" TEXT="Achtung: zus&#xe4;tzclihen Admin-Overhead in der lib::Several-Storage beachten">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1718807680712" ID="ID_1019078083" MODIFIED="1718807687755" TEXT="zum einen die Gr&#xf6;&#xdf;e des ArrayBucket"/>
<node CREATED="1718807690167" ID="ID_915812333" LINK="#ID_728519799" MODIFIED="1718807743585" TEXT="au&#xdf;erdem: brauche Puffer f&#xfc;r over-alligned-types"/>
</node>
</node>
<node COLOR="#338800" CREATED="1717893927188" ID="ID_407717086" MODIFIED="1717893962751" TEXT="leeren Container gleich mit einer gr&#xf6;&#xdf;eren Allokation starten">
<icon BUILTIN="button_ok"/>
</node>
@ -83419,8 +83455,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node COLOR="#338800" CREATED="1718118079617" ID="ID_786279389" LINK="#ID_748929457" MODIFIED="1718147534164" TEXT="Testen mit allen Schikanen"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716936138265" ID="ID_344813639" MODIFIED="1716936143886" TEXT="Allokations-Policies">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1716936138265" ID="ID_344813639" MODIFIED="1718810203166" TEXT="Allokations-Policies">
<icon BUILTIN="button_ok"/>
<node CREATED="1716936150419" ID="ID_442325434" MODIFIED="1716936174356" TEXT="HeapOwn">
<node CREATED="1716936175678" ID="ID_1766388404" MODIFIED="1718320002038" TEXT="verwendet die Standard-AllocationPolicy"/>
<node CREATED="1718320003314" ID="ID_1600782840" MODIFIED="1718320016768" TEXT="setzt in diese den std::allocator&lt;byte&gt; ein"/>
@ -83430,6 +83466,11 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1718320162597" ID="ID_1683490945" MODIFIED="1718320193995" TEXT="sondern nur noch die low-level Storage f&#xfc;r den Array-Datenpuffer freigegeben"/>
</node>
</node>
<node CREATED="1718807409474" ID="ID_1070956232" MODIFIED="1718807413448" TEXT="AllocationCluster">
<node CREATED="1718807416292" ID="ID_1773734100" MODIFIED="1718807425270" TEXT="spezialisiert die Standard-Policy"/>
<node CREATED="1718807425931" ID="ID_726007931" MODIFIED="1718807449132" TEXT="fragt den Cluster vor Gr&#xf6;&#xdf;en&#xe4;nderung, ob diese &#xbb;in-place&#xab; gemacht werden kann"/>
<node CREATED="1718807449857" ID="ID_1496143411" MODIFIED="1718807467730" TEXT="beachtet die starke Gr&#xf6;&#xdf;en-Limitierung f&#xfc;r Allokationen im Cluster"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718147554244" ID="ID_1260306723" MODIFIED="1718147566635" TEXT="convenience-Functions">
<icon BUILTIN="flag-yellow"/>
@ -83631,8 +83672,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="ksmiletris"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718412437319" ID="ID_947832201" MODIFIED="1718412481457" TEXT="dann Spezialisierung f&#xfc;r AllocationCluster">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1718412437319" ID="ID_947832201" MODIFIED="1718810209984" TEXT="dann Spezialisierung f&#xfc;r AllocationCluster">
<icon BUILTIN="button_ok"/>
<node CREATED="1718412486764" ID="ID_1577108455" MODIFIED="1718412502863" TEXT="Vorbereitung: Forward-Deklarationen">
<node CREATED="1718412503850" ID="ID_1754798061" MODIFIED="1718412512686" TEXT="in lib/allocation-cluster.hpp"/>
<node CREATED="1718412516780" ID="ID_1342390871" MODIFIED="1718412531679" TEXT="anonymer Namespace">
@ -83695,9 +83736,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#3a0f69" CREATED="1718759712439" ID="ID_374387139" MODIFIED="1718759803731" TEXT="AllocationCluster braucht mehr Infos">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...ich hab diese Mechanik ganz bewu&#223;t <i>janz domm </i>implementiert &#8212; also mu&#223; praktisch alle Info von oben kommen
@ -84181,9 +84220,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
<node COLOR="#5b280f" CREATED="1718759951537" HGAP="33" ID="ID_235987237" MODIFIED="1718759979363" TEXT="geht nicht 100% gleich" VSHIFT="9">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...da AllocationCluster eine starke Gr&#246;&#223;enbeschr&#228;nkgung hat
@ -84194,18 +84231,17 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718730299524" ID="ID_1847366954" MODIFIED="1718730388370" TEXT="verifizieren, da&#xdf; die dynamische Anpassung stattgefunden hat">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718761161744" ID="ID_532446008" MODIFIED="1718761180110" TEXT="auch demonstrieren, da&#xdf; das nach einer Zwischen-Allokaiton nicht mehr geht">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1718730299524" ID="ID_1847366954" MODIFIED="1718810706376" TEXT="verifizieren, da&#xdf; die dynamische Anpassung stattgefunden hat">
<linktarget COLOR="#54b885" DESTINATION="ID_1847366954" ENDARROW="Default" ENDINCLINATION="534;710;" ID="Arrow_ID_510035319" SOURCE="ID_1222886197" STARTARROW="None" STARTINCLINATION="1024;-48;"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1718761161744" ID="ID_532446008" MODIFIED="1718810219869" TEXT="auch demonstrieren, da&#xdf; das nach einer Zwischen-Allokaiton nicht mehr geht">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1718761232124" ID="ID_482647269" MODIFIED="1718761241262" TEXT="Speicherbeschr&#xe4;nkung spricht an">
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1718761242724" ID="ID_103960271" MODIFIED="1718761290782" TEXT="sollte sie hier nicht">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
denn das eine zus&#228;tzliche Element w&#252;rde locker reinpassen &#8212; und zudem sollte ja nun der Block in den n&#228;chsten Extent migrieren
@ -84224,16 +84260,13 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1718799220944" ID="ID_767486342" MODIFIED="1718799361796" TEXT="sie wird zweimal verwendet">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
einmal aus emplaceNewElm() und einmal aus reserve()
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="info"/>
</node>
<node CREATED="1718799228581" ID="ID_278040714" MODIFIED="1718799338634" TEXT="und in zwei verschiedenen Bedeutungen">
@ -84242,9 +84275,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node COLOR="#338800" CREATED="1718799242437" ID="ID_186272424" MODIFIED="1718800434682" TEXT="Festlegung: da soll es um die zus&#xe4;tzliche Kapazit&#xe4;t gehen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
das ist es n&#228;mlich, worauf die Implementierung hinausl&#228;uft, und dieser Grebrauch ist auch naheliegend und korrekt, sofern es sich um das Einf&#252;gen neuer Datenelemente handelt. Insofern mu&#223; sich der andere Gebrauch in reserve() daran anpassen
@ -84256,7 +84287,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node CREATED="1718797389002" ID="ID_487967037" MODIFIED="1718797406916" TEXT="adjustStorage versucht exponentielle Erweiterung">
<node CREATED="1718797408528" ID="ID_1641482989" MODIFIED="1718797416963" TEXT="obwohl explizit weniger gefordert ist"/>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1718797462569" ID="ID_1609091342" MODIFIED="1718797572998" TEXT="es wird nur das Safety-Limit gepr&#xfc;ft, nicht aber der Allokator angefragt">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#690f14" CREATED="1718797462569" ID="ID_1609091342" MODIFIED="1718807844066" TEXT="es wird nur das Safety-Limit gepr&#xfc;ft, nicht aber der Allokator angefragt">
<arrowlink COLOR="#981848" DESTINATION="ID_114386960" ENDARROW="Default" ENDINCLINATION="17;-94;" ID="Arrow_ID_1052035181" STARTARROW="None" STARTINCLINATION="-451;18;"/>
<icon BUILTIN="broken-line"/>
</node>
<node CREATED="1718797473087" ID="ID_1313216059" MODIFIED="1718797490217" TEXT="konkret: versucht stets von 128 auf 256 zu vergr&#xf6;&#xdf;ern"/>
@ -84270,9 +84302,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1718798134610" ID="ID_1437311418" MODIFIED="1718798148283" TEXT="das bedeutet: es ist kein dynamischer Check im Codepfad">
<node CREATED="1718798206756" ID="ID_1802549345" MODIFIED="1718798263474" TEXT="eigentlich hatte ich ja gedacht...">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...da&#223; da immer noch high-level-Code dar&#252;ber liegt, der eine inhaltliche Pr&#252;fung gemacht hat, so da&#223; hier nur noch ein Konsistenzcheck vonn&#246;ten ist
@ -84283,9 +84313,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node CREATED="1718798266263" ID="ID_1888657389" MODIFIED="1718798419479" TEXT="realistisch betrachtet &#x2014; zu gut">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...aber realistisch betrachtet ist der AllocationCluster viel zu einfach zu verwenden, als da&#223; man da &#252;berhaupt daran denkt, noch explizit zu pr&#252;fen &#8212; und durch den standard-Allocator-Adapter gibt es unvermeidbar einen direkten Eingang &#252;ber allot().
@ -84311,9 +84339,24 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1718807769148" ID="ID_114386960" MODIFIED="1718810234819" TEXT="Konsequenz: exponentielle Expansion sinnvoll beschr&#xe4;nken">
<linktarget COLOR="#981848" DESTINATION="ID_114386960" ENDARROW="Default" ENDINCLINATION="17;-94;" ID="Arrow_ID_1052035181" SOURCE="ID_1609091342" STARTARROW="None" STARTINCLINATION="-451;18;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1718807852641" ID="ID_1147918184" MODIFIED="1718807980725" TEXT="den Allokator abfragen, was er kann">
<arrowlink COLOR="#313f5b" DESTINATION="ID_1980443647" ENDARROW="Default" ENDINCLINATION="364;849;" ID="Arrow_ID_1834035862" STARTARROW="None" STARTINCLINATION="411;-39;"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718730317115" ID="ID_1509954190" MODIFIED="1718761158043" TEXT="es sollte sich genau die erwartete Speicherbelegung ergeben">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1718807860888" ID="ID_1987668374" MODIFIED="1718807868682" TEXT="das zus&#xe4;tzlich zum Safety-Limit einarbeiten"/>
<node CREATED="1718807869487" ID="ID_620170823" MODIFIED="1718807877049" TEXT="Admin-Overhead auch noch beachten"/>
<node CREATED="1718807877712" ID="ID_1672346969" MODIFIED="1718807890289" TEXT="au&#xdf;erdem: auf Element-St&#xfc;ckung abrunden (nicht aufrunden)"/>
<node CREATED="1718807893252" ID="ID_1006970321" MODIFIED="1718807909693" TEXT="Fehler wenn dann der direkte Bedarf nicht mehr befriedigt werden kann"/>
<node CREATED="1718807910377" ID="ID_175511448" MODIFIED="1718807917533" TEXT="sonst: man nimmt mit was noch geht"/>
</node>
<node COLOR="#338800" CREATED="1718810223375" ID="ID_691213141" MODIFIED="1718810232908" TEXT="damit funktioniert es wie erwartet">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1718730317115" ID="ID_1509954190" MODIFIED="1718810242562" TEXT="es sollte sich genau die erwartete Speicherbelegung ergeben">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718730353373" ID="ID_819034170" MODIFIED="1718730388372" TEXT="Objekt-Cleanup findet statt &#x2014; aber keine de-Allokation">
<icon BUILTIN="flag-yellow"/>
@ -84777,9 +84820,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="ksmiletris"/>
<node COLOR="#435e98" CREATED="1718730762914" ID="ID_342906032" LINK="#ID_113992967" MODIFIED="1718730835701" TEXT="hat viel gebracht...">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
versteckte Inkonsistenz mit der Deleter-Behandlung aufgedeckt
@ -84793,26 +84834,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718368791047" ID="ID_59759193" MODIFIED="1718368826816" TEXT="direktes construct-and-embed mit AllocationCluster demonstrieren">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1718368831343" ID="ID_1248831538" LINK="#ID_1419157708" MODIFIED="1718368953078">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
braucht ein API zum <i>&#220;bernehmen </i>eines bereits konstruierten Objekts
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
zun&#228;chst hatte ich AllocationCluster daf&#252;r definiert, da&#223; die Objekte <i>direkt im Cluster-Speicher erzeugt </i>werden; hier aber liegt ein valider Fall vor, in dem das Objekt bereits erzeugt wurde (n&#228;mlich &#252;ber den Builder), und von dort per move/copy in den Cluster &#252;bernommen werden soll
</p>
</body>
</html></richcontent>
<node COLOR="#338800" CREATED="1718368791047" ID="ID_59759193" MODIFIED="1718810640841" TEXT="direktes construct-and-embed mit AllocationCluster demonstrieren">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1718810641824" ID="ID_1222886197" MODIFIED="1718810706375" TEXT="dynamische Anpassungen mit Allocation-Cluster demonstrieren">
<arrowlink COLOR="#54b885" DESTINATION="ID_1847366954" ENDARROW="Default" ENDINCLINATION="534;710;" ID="Arrow_ID_510035319" STARTARROW="None" STARTINCLINATION="1024;-48;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
@ -85087,8 +85114,6 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1715727225764" ID="ID_123722889" MODIFIED="1715727230671" TEXT="getAllocator&lt;TY&gt;"/>
<node CREATED="1715727232648" ID="ID_597499360" MODIFIED="1715727238366" TEXT="create"/>
<node CREATED="1716848614943" ID="ID_1316151534" MODIFIED="1716848618330" TEXT="createDisposable"/>
<node CREATED="1718368600814" ID="ID_1688514818" MODIFIED="1718368708563" TEXT="embed"/>
<node CREATED="1718368606877" ID="ID_1419157708" MODIFIED="1718368714204" TEXT="embedDisposable"/>
<node CREATED="1715728180516" ID="ID_412948320" MODIFIED="1715728191170" TEXT="allot&lt;TY&gt;(cnt)"/>
<node CREATED="1715727255639" ID="ID_1782845675" MODIFIED="1715727439713" TEXT="allotMemory(size_t)"/>
<node CREATED="1715727250709" ID="ID_886757416" MODIFIED="1716848629262" TEXT="numExtents"/>