Library: data layout for the new Several container

- favour dynamic polymorphism
- use additional memory for management data alongside the element allocation
- encode a flag and a deleter pointer to enable ownership of the allocation
- inherit base container privately into builder, so the build ends with a slice
This commit is contained in:
Fischlurch 2024-05-28 17:20:34 +02:00
parent 73dd24ecef
commit f6e4358259
3 changed files with 206 additions and 4 deletions

View file

@ -53,12 +53,22 @@ using std::vector;
namespace lib {
namespace {// Allocation managment policies
struct HeapOwn
{
};
}
/**
* Wrap a vector holding objects of a subtype and
* provide array-like access using the interface type.
*/
template<class I>
template<class I, class POL =HeapOwn>
class SeveralBuilder
: Several<I>
, POL
{
public:

View file

@ -36,22 +36,56 @@
#include "lib/nocopy.hpp"
#include "lib/iter-adapter.hpp"
#include <cstddef>
namespace lib {
/**
* Abstraction: Array of const references.
namespace {// Storage implementation details
struct Bucket
{
union Manager
{
typedef void (*Deleter) (void*, size_t);
bool unmanaged :1;
Deleter deleter;
};
Manager manager;
size_t spread;
};
template<class I, size_t bytes>
struct ArrayBucket
: Bucket
{
alignas(I)
std::byte storage[bytes];
};
}//(End)implementation details
/************************************************//**
* Abstraction: Fixed array of elements.
* Typically the return type is an interface,
* and the Implementation wraps some datastructure
* holding subclasses.
* @todo ouch -- a collection that isn't iterable... ///////////////////////TICKET #1040 //////////OOO cookie jar
* @warning in rework 5/2025
*/
template<class I>
class Several
: util::MoveOnly
{
protected:
size_t size_{0};
Bucket* data_{nullptr};
public:
size_t

View file

@ -81665,11 +81665,36 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715627195825" ID="ID_40203233" MODIFIED="1715627201745" TEXT="Details festlegen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1716856805949" ID="ID_792128264" MODIFIED="1716856808446" TEXT="Design">
<node CREATED="1716903878763" ID="ID_1194580959" MODIFIED="1716903884972" TEXT="der Container ist general-purpose">
<node CREATED="1716903981442" ID="ID_1597569499" MODIFIED="1716903997087" TEXT="es handelt sich um ein generell n&#xfc;tzliches Konzept"/>
<node CREATED="1716903997843" ID="ID_835405424" MODIFIED="1716904010573" TEXT="Funktionalit&#xe4;t ist vergleichbar zu ScopedCollection"/>
<node CREATED="1716904011753" ID="ID_1668126907" MODIFIED="1716904027723" TEXT="aber hier ist der Container nach der Population fixiert"/>
<node CREATED="1716904030375" ID="ID_325615879" MODIFIED="1716904048856" TEXT="man sollte ihn einfach mit Heap-Memory verwenden k&#xf6;nnen"/>
<node CREATED="1716904051908" ID="ID_1108048210" MODIFIED="1716904063859" TEXT="aber optimiert wird auf den Spezialfall mit AllocationCluster"/>
</node>
<node CREATED="1716856809343" ID="ID_1193014237" MODIFIED="1716856820503" TEXT="der Allocator wird &#xfc;ber eine Policy eingebunden">
<node CREATED="1716856840256" ID="ID_817075746" MODIFIED="1716856864012" TEXT="per Default ist das std::allocator"/>
<node CREATED="1716856892993" ID="ID_299290154" MODIFIED="1716856907499" TEXT="es gibt eine explizite Spezialisierung f&#xfc;r AllocationCluster"/>
<node CREATED="1716856915174" ID="ID_872073061" MODIFIED="1716856955511" TEXT="die Builder-Policy steuert auch eine Detail-Policy in den eigentlichen Container-Typ"/>
</node>
<node CREATED="1716902524310" ID="ID_336186594" MODIFIED="1716902554166" TEXT="der Container selber ist runtime-polymorph">
<node CREATED="1716902559461" ID="ID_796780489" MODIFIED="1716902593125">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Konsequenz: man kann einen einzigen Typ <font face="Monospaced" color="#8c0808">Several&lt;X&gt;</font>&#160;anschreiben
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1716902606624" ID="ID_1870642120" MODIFIED="1716902710954" TEXT="alle Detail-Variationen sind als runtime state gegeben">
<linktarget COLOR="#4b357c" DESTINATION="ID_1870642120" ENDARROW="Default" ENDINCLINATION="106;163;" ID="Arrow_ID_1077333305" SOURCE="ID_324116912" STARTARROW="None" STARTINCLINATION="-291;19;"/>
</node>
</node>
</node>
<node CREATED="1716857432809" ID="ID_976896851" MODIFIED="1716857436700" TEXT="API">
<node CREATED="1716861302691" ID="ID_346534745" MODIFIED="1716861305151" TEXT="Builder">
@ -81694,6 +81719,139 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1716861799273" ID="ID_521198508" MODIFIED="1716861807996" TEXT="man m&#xf6;chte Elemente verdrahten"/>
<node CREATED="1716861808632" ID="ID_361446966" MODIFIED="1716861818586" TEXT="man k&#xf6;nnte die Storage noch dynamisch anpassen"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716901371443" ID="ID_679786160" MODIFIED="1716901388931" TEXT="Beschlu&#xdf;: durch eine explizit aufzurufende Builder-Methode">
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716901390803" ID="ID_1798868375" MODIFIED="1716901421256" TEXT="diese reloziert ggfs. bestehende Elemente">
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1716901402394" ID="ID_1898535307" MODIFIED="1716901416153" TEXT="wenn man das nicht will, soll man&apos;s nicht machen">
<icon BUILTIN="smiley-oh"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716901426183" ID="ID_1212967398" MODIFIED="1716901442101" TEXT="Element-Zugriff und Iteration">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#5b280f" CREATED="1716901483423" ID="ID_609493193" MODIFIED="1716901839026" TEXT="Element-Spread wird ein Template-Parameter">
<icon BUILTIN="button_cancel"/>
<node CREATED="1716901840209" ID="ID_594866593" MODIFIED="1716901869287" TEXT="Nein &#x2014; eben grade nicht">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#990033" CREATED="1716902004068" ID="ID_324116912" MODIFIED="1716902720703" TEXT="Zielkonflikt &#x27f6; Richtungs-Entscheidung">
<arrowlink COLOR="#4b357c" DESTINATION="ID_1870642120" ENDARROW="Default" ENDINCLINATION="106;163;" ID="Arrow_ID_1077333305" STARTARROW="None" STARTINCLINATION="-291;19;"/>
<icon BUILTIN="help"/>
<node CREATED="1716902031480" ID="ID_1856172296" MODIFIED="1716902034473" TEXT="Ziel-A">
<node CREATED="1716902071002" ID="ID_1187678120" MODIFIED="1716902074858" TEXT="Storage sparen"/>
<node CREATED="1716902101303" ID="ID_506975430" MODIFIED="1716902109266" TEXT="maximale Optimierbarkeit"/>
</node>
<node CREATED="1716902110548" ID="ID_50747966" MODIFIED="1716902113489" TEXT="Ziel-B">
<node CREATED="1716902120284" ID="ID_1828684259" MODIFIED="1716902128378" TEXT="Klare lesbare Daten-Definition"/>
<node CREATED="1716902185830" ID="ID_799579578" MODIFIED="1716902192902" TEXT="runtime polymorphism"/>
</node>
<node CREATED="1716902202186" ID="ID_1015798898" MODIFIED="1716902275921" TEXT="Diskussion">
<node CREATED="1716902205235" ID="ID_1941027730" MODIFIED="1716902274648" TEXT="wir verschwenden Storage zur Performance-Optimierung">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...und zwar vor allem durch den AllocationCluster mit einer festen Extent-Size. Vorhersehbar werden die Extents meist zu gro&#223; sein...
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1716902277551" ID="ID_1279637635" MODIFIED="1716902337377" TEXT="Extents sind &#xfc;berdimensioniert &#x27f9; Platz ist &#x201e;eh da&#x201c;">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...und was noch besser ist: die Storage liegt kompakt
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1716902347758" ID="ID_737951964" MODIFIED="1716902457937" TEXT="Zus&#xe4;tzliche Typ-Komplexit&#xe4;t dagegen w&#xe4;re problematisch">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...weil wir durch den Connectivity-Descriptor bereits eine gef&#228;hrlich komplexes St&#252;ck Metaprogramming haben, mit dem Risiko kombinatorischer Explosion
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1716902466150" ID="ID_1670357749" MODIFIED="1716902481998" TEXT="Entscheidung &#xd83e;&#xdc32; Ziel-B pr&#xe4;ferieren">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716901650386" ID="ID_636334267" MODIFIED="1716903157046" TEXT="Array-Repr&#xe4;sentation">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1716903158346" ID="ID_1317174249" MODIFIED="1716907525705" TEXT="im Container(&#x2259;Handle): (size, start)"/>
<node CREATED="1716903185047" ID="ID_1036525121" MODIFIED="1716903198769" TEXT="im ArrayBucket">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716903201165" ID="ID_443006340" MODIFIED="1716907430046" TEXT="Manager">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1716904170396" ID="ID_1253230124" MODIFIED="1716904183622" TEXT="das ist eine trickreich belegte Union"/>
<node CREATED="1716904184162" ID="ID_990254994" MODIFIED="1716904195917" TEXT="kann als &#xbb;unmanaged&#xab; markiert werden"/>
<node CREATED="1716904197917" ID="ID_1121578813" MODIFIED="1716904215226" TEXT="nullptr &#x27f9; std::allocator verwenden"/>
<node CREATED="1716904231812" ID="ID_1732387735" MODIFIED="1716904732789" TEXT="sonst: pointer auf eine delete-Function void(void*, bytes)"/>
</node>
<node CREATED="1716904075721" ID="ID_1409827773" MODIFIED="1716904079637" TEXT="spread"/>
<node CREATED="1716904088399" ID="ID_1134374495" MODIFIED="1716904091035" TEXT="storage"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716901733807" ID="ID_955318801" MODIFIED="1716901736839" TEXT="Typdefinition">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716904763479" ID="ID_128910376" MODIFIED="1716907418032" TEXT="Several&lt;X&gt;">
<node CREATED="1716904775435" ID="ID_1732099625" MODIFIED="1716904782191" TEXT="ist bereits vollst&#xe4;ndig spezifiziert"/>
<node CREATED="1716904783055" ID="ID_1106871402" MODIFIED="1716904792309" TEXT="alle leeren Severals sind &#xe4;quivalent"/>
<node CREATED="1716904793417" ID="ID_628691116" MODIFIED="1716905172320" TEXT="polymorphes Verhalten steckt im ArrayBucket"/>
<node CREATED="1716905317043" ID="ID_1896634552" MODIFIED="1716905321407" TEXT="ist move-assignable">
<node CREATED="1716905326312" ID="ID_1705639100" MODIFIED="1716905341332" TEXT="wegen ownership"/>
<node CREATED="1716905342344" ID="ID_36544498" MODIFIED="1716905416848" TEXT="f&#xfc;r unmanaged ArrayBuckets k&#xf6;nnte man eine cloneCopy-Funktion bereitstellen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
diese Funktion w&#252;rde eine Exception werfen, wen das ArrayBucket eben doch ownership-managed ist. Ansonsten erzeugt sie eine neue Instanz mit Verweis auf das gemeinsam nutzbare Bucket
</p>
</body>
</html>
</richcontent>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716904812326" ID="ID_21128659" MODIFIED="1716907418033" TEXT="SeveralBuilder&lt;I,POL&gt;">
<node CREATED="1716904860512" ID="ID_1156798049" MODIFIED="1716904866131" TEXT="I : der Interface-Typ"/>
<node CREATED="1716904866967" ID="ID_806748628" MODIFIED="1716904877146" TEXT="POL : eingemischte Policy-Klasse"/>
<node CREATED="1716905087336" ID="ID_292950135" MODIFIED="1716905314680" TEXT="erbt vom Several&lt;I&gt; - Basiscontainer"/>
<node CREATED="1716905485069" ID="ID_171472761" MODIFIED="1716905490496" TEXT="zus&#xe4;tzliche dynamische Daten">
<node CREATED="1716905492418" ID="ID_53772373" MODIFIED="1716905504094" TEXT="storageSiz">
<node CREATED="1716905505418" ID="ID_430213337" MODIFIED="1716905518476" TEXT="allozierter Puffer im ArrayBucket"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716907249314" ID="ID_1711986050" MODIFIED="1716907418033" TEXT="Bucket">
<node CREATED="1716907252393" ID="ID_198747165" MODIFIED="1716907259884" TEXT="der Descriptor"/>
<node CREATED="1716907260424" ID="ID_1362772717" MODIFIED="1716907268555" TEXT="liegt am Anfang der Element-Storage"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716906944780" ID="ID_1643896091" MODIFIED="1716907418033" TEXT="ArrayBucket&lt;I,bytes&gt;">
<node CREATED="1716907277198" ID="ID_104268426" MODIFIED="1716907281769" TEXT="Subklasse von Bucket"/>
<node CREATED="1716907312241" ID="ID_835337350" MODIFIED="1716907333394" TEXT="umspannt das Storage-Array"/>
<node CREATED="1716907356091" ID="ID_1876919425" MODIFIED="1716907403909" TEXT="enth&#xe4;lt den subscript-Code"/>
</node>
</node>
</node>
</node>