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:
parent
73dd24ecef
commit
f6e4358259
3 changed files with 206 additions and 4 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -81665,11 +81665,36 @@ Date:   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ützliches Konzept"/>
|
||||
<node CREATED="1716903997843" ID="ID_835405424" MODIFIED="1716904010573" TEXT="Funktionalitä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ö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 ü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ü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<X></font> 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:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1716861799273" ID="ID_521198508" MODIFIED="1716861807996" TEXT="man möchte Elemente verdrahten"/>
|
||||
<node CREATED="1716861808632" ID="ID_361446966" MODIFIED="1716861818586" TEXT="man könnte die Storage noch dynamisch anpassen"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716901371443" ID="ID_679786160" MODIFIED="1716901388931" TEXT="Beschluß: 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'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 — eben grade nicht">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#990033" CREATED="1716902004068" ID="ID_324116912" MODIFIED="1716902720703" TEXT="Zielkonflikt ⟶ 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ß sein...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1716902277551" ID="ID_1279637635" MODIFIED="1716902337377" TEXT="Extents sind überdimensioniert ⟹ Platz ist „eh da“">
|
||||
<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ätzliche Typ-Komplexität dagegen wäre problematisch">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...weil wir durch den Connectivity-Descriptor bereits eine gefährlich komplexes Stü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 �� Ziel-B prä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äsentation">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1716903158346" ID="ID_1317174249" MODIFIED="1716907525705" TEXT="im Container(≙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 »unmanaged« markiert werden"/>
|
||||
<node CREATED="1716904197917" ID="ID_1121578813" MODIFIED="1716904215226" TEXT="nullptr ⟹ 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<X>">
|
||||
<node CREATED="1716904775435" ID="ID_1732099625" MODIFIED="1716904782191" TEXT="ist bereits vollständig spezifiziert"/>
|
||||
<node CREATED="1716904783055" ID="ID_1106871402" MODIFIED="1716904792309" TEXT="alle leeren Severals sind ä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ür unmanaged ArrayBuckets könnte man eine cloneCopy-Funktion bereitstellen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
diese Funktion wü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<I,POL>">
|
||||
<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<I> - Basiscontainer"/>
|
||||
<node CREATED="1716905485069" ID="ID_171472761" MODIFIED="1716905490496" TEXT="zusä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<I,bytes>">
|
||||
<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ält den subscript-Code"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue