Library: adapt allocation and realloc to new layout
significantly simplifies both API and calculations, since all necessary data is now within the ArrayBucket
This commit is contained in:
parent
130a021020
commit
deaabcda6e
3 changed files with 63 additions and 52 deletions
|
|
@ -92,13 +92,6 @@ namespace lib {
|
|||
return XAllo{};
|
||||
}
|
||||
|
||||
static size_t
|
||||
calcSize (size_t cnt, size_t spread)
|
||||
{
|
||||
return sizeof(Bucket) - sizeof(Bucket::storage)
|
||||
+ cnt * spread;
|
||||
}
|
||||
|
||||
public:
|
||||
ElementFactory (Allo allo = Allo{})
|
||||
: Allo{std::move (allo)}
|
||||
|
|
@ -107,18 +100,19 @@ namespace lib {
|
|||
Bucket*
|
||||
create (size_t cnt, size_t spread)
|
||||
{
|
||||
size_t storageBytes = calcSize (cnt, spread);
|
||||
size_t storageBytes = Bucket::requiredStorage (cnt, spread);
|
||||
std::byte* loc = AlloT::allocate (baseAllocator(), storageBytes);
|
||||
Bucket* bucket = reinterpret_cast<Bucket*> (loc);
|
||||
|
||||
using BucketAlloT = typename AlloT::template rebind_traits<Bucket>;
|
||||
auto bucketAllo = adaptAllocator<Bucket>();
|
||||
try { BucketAlloT::construct (bucketAllo, reinterpret_cast<Bucket*> (loc), spread); }
|
||||
try { BucketAlloT::construct (bucketAllo, bucket, storageBytes, spread); }
|
||||
catch(...)
|
||||
{
|
||||
AlloT::deallocate (baseAllocator(), loc, storageBytes);
|
||||
throw;
|
||||
}
|
||||
return reinterpret_cast<Bucket*> (loc);
|
||||
return bucket;
|
||||
};
|
||||
|
||||
template<class E, typename...ARGS>
|
||||
|
|
@ -136,16 +130,18 @@ namespace lib {
|
|||
|
||||
template<class E>
|
||||
void
|
||||
destroy (ArrayBucket<I>* bucket, size_t size)
|
||||
destroy (ArrayBucket<I>* bucket)
|
||||
{
|
||||
REQUIRE (bucket);
|
||||
size_t cnt = bucket->cnt;
|
||||
size_t storageBytes = bucket->buffSiz;
|
||||
using ElmAlloT = typename AlloT::template rebind_traits<E>;
|
||||
auto elmAllo = adaptAllocator<E>();
|
||||
for (size_t i=0; i<size; ++i)
|
||||
ElmAlloT::destroy (elmAllo, & bucket->subscript(i));
|
||||
for (size_t idx=0; idx<cnt; ++idx)
|
||||
ElmAlloT::destroy (elmAllo, & bucket->subscript(idx));
|
||||
|
||||
size_t storageBytes = calcSize (size, bucket->spread); ////////////////////////////////////OOO das ist naiv ... es kann mehr Storage sein
|
||||
AlloT::deallocate (baseAllocator(), reinterpret_cast<std::byte*> (bucket), storageBytes);
|
||||
std::byte* loc = reinterpret_cast<std::byte*> (bucket);
|
||||
AlloT::deallocate (baseAllocator(), loc, storageBytes);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -160,16 +156,17 @@ namespace lib {
|
|||
using Fac::Fac; // pass-through ctor
|
||||
|
||||
Bucket*
|
||||
realloc (Bucket* data, size_t cnt, size_t& storage, size_t demand)
|
||||
realloc (Bucket* data, size_t demand)
|
||||
{
|
||||
if (demand == storage)
|
||||
size_t buffSiz{data? data->buffSiz : 0};
|
||||
if (demand == buffSiz)
|
||||
return data;
|
||||
if (demand > storage)
|
||||
if (demand > buffSiz)
|
||||
{// grow into exponentially expanded new allocation
|
||||
size_t spread = data? data->spread : sizeof(I);
|
||||
size_t safetyLim = LUMIERA_MAX_ORDINAL_NUMBER * spread;
|
||||
size_t expandAlloc = min (safetyLim
|
||||
,max (2*storage, demand));
|
||||
,max (2*buffSiz, demand));
|
||||
if (expandAlloc < demand)
|
||||
throw err::State{_Fmt{"Storage expansion for Several-collection "
|
||||
"exceeds safety limit of %d bytes"} % safetyLim
|
||||
|
|
@ -179,29 +176,28 @@ namespace lib {
|
|||
if (newCnt * spread < demand) ++newCnt;
|
||||
Bucket* newBucket = Fac::create (newCnt, spread);
|
||||
// move (or copy) existing data...
|
||||
ENSURE (data or cnt==0);
|
||||
for (size_t i=0; i<cnt; ++i)
|
||||
Fac::template createAt<I> (newBucket, i
|
||||
,std::move_if_noexcept (data->subscript(i)));
|
||||
size_t cnt = data? data->cnt : 0;
|
||||
for (size_t idx=0; idx<cnt; ++idx)
|
||||
Fac::template createAt<I> (newBucket, idx
|
||||
,std::move_if_noexcept (data->subscript(idx)));
|
||||
////////////////////////////////////////////////////////OOO schee... aba mia brauchn E, ned I !!!!!
|
||||
// discard old storage
|
||||
if (data)
|
||||
Fac::template destroy<I> (data, cnt); /////////////////////////////////////////////OOO Problem mit der überschüssigen Storage
|
||||
storage = newCnt*spread;
|
||||
Fac::template destroy<I> (data);
|
||||
return newBucket;
|
||||
}
|
||||
else
|
||||
{// shrink into precisely fitting new allocation
|
||||
Bucket* newBucket{nullptr};
|
||||
if (cnt > 0)
|
||||
if (data)
|
||||
{
|
||||
REQUIRE (data);
|
||||
size_t cnt{data->cnt};
|
||||
ASSERT (cnt > 0);
|
||||
newBucket = Fac::create (cnt, data->spread);
|
||||
for (size_t i=0; i<cnt; ++i)
|
||||
Fac::template createAt<I> (newBucket, i
|
||||
,std::move_if_noexcept (data->subscript(i))); ////////////OOO selbes Problem: E hier
|
||||
Fac::template destroy<I> (data, cnt); /////////////////////////////////////////////OOO nicht passende Storage!!
|
||||
storage = cnt * data->spread;
|
||||
for (size_t idx=0; idx<cnt; ++idx)
|
||||
Fac::template createAt<I> (newBucket, idx
|
||||
,std::move_if_noexcept (data->subscript(idx))); ////////////OOO selbes Problem: E hier
|
||||
Fac::template destroy<I> (data);
|
||||
}
|
||||
return newBucket;
|
||||
}
|
||||
|
|
@ -310,12 +306,9 @@ namespace lib {
|
|||
adjustStorage (size_t cnt, size_t spread)
|
||||
{
|
||||
size_t demand{cnt*spread};
|
||||
if (demand > storageSiz_)
|
||||
{ // need more storage...
|
||||
Coll::data_ = static_cast<typename Coll::Bucket> (POL::realloc (Coll::data_, Coll::size_, storageSiz_, demand));
|
||||
}
|
||||
Coll::data_ = POL::realloc (Coll::data_, demand);
|
||||
ENSURE (Coll::data_);
|
||||
if (spread != Coll::data_->spread)
|
||||
if (spread != Coll::data_->spread) ///////////////OOO API für spread?
|
||||
adjustSpread (spread);
|
||||
}
|
||||
|
||||
|
|
@ -324,10 +317,7 @@ namespace lib {
|
|||
{
|
||||
if (not Coll::data_) return;
|
||||
size_t demand{Coll::size_ * Coll::data_->spread};
|
||||
if (demand < storageSiz_)
|
||||
{ // attempt to shrink storage
|
||||
Coll::data_ = static_cast<typename Coll::Bucket> (POL::realloc (Coll::data_, Coll::size_, storageSiz_, demand));
|
||||
}
|
||||
Coll::data_ = POL::realloc (Coll::data_, demand);
|
||||
}
|
||||
|
||||
/** move existing data to accommodate spread */
|
||||
|
|
|
|||
|
|
@ -77,10 +77,10 @@ namespace lib {
|
|||
template<class I>
|
||||
struct ArrayBucket
|
||||
{
|
||||
ArrayBucket (size_t elmSize = sizeof(I))
|
||||
ArrayBucket (size_t bytes, size_t elmSize = sizeof(I))
|
||||
: cnt{0}
|
||||
, spread{elmSize}
|
||||
, buffSiz{0}//////////////////////////////////////////////////////////////OOO sollte man das nicht besser zwingend korrekt setzen?
|
||||
, buffSiz{bytes}
|
||||
, deleter{nullptr}
|
||||
{ }
|
||||
|
||||
|
|
@ -95,6 +95,14 @@ namespace lib {
|
|||
alignas(I)
|
||||
std::byte storage[sizeof(I)];
|
||||
|
||||
|
||||
static size_t
|
||||
requiredStorage (size_t cnt, size_t spread)
|
||||
{
|
||||
return sizeof(ArrayBucket) - sizeof(storage)
|
||||
+ cnt * spread;
|
||||
}
|
||||
|
||||
/** perform unchecked access into the storage area
|
||||
* @note typically reaching behind the nominal end of this object
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -81809,8 +81809,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717796539825" ID="ID_719213336" MODIFIED="1717797044756" TEXT="Umbau Storage: alle Metadaten in das ArrayBucket verlagern">
|
||||
<linktarget COLOR="#af28b1" DESTINATION="ID_719213336" ENDARROW="Default" ENDINCLINATION="-878;40;" ID="Arrow_ID_1140258959" SOURCE="ID_505052942" STARTARROW="None" STARTINCLINATION="-190;-16;"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717796539825" ID="ID_719213336" MODIFIED="1717803235299" TEXT="Umbau Storage: alle Metadaten in das ArrayBucket verlagern">
|
||||
<linktarget COLOR="#af28b1" DESTINATION="ID_719213336" ENDARROW="Default" ENDINCLINATION="-878;40;" ID="Arrow_ID_1140258959" SOURCE="ID_505052942" STARTARROW="None" STARTINCLINATION="-488;-57;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1717796640496" ID="ID_962872298" MODIFIED="1717796742452" TEXT="Begründung: Raum für zukünftige Optimierungen schaffen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -82394,10 +82394,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1717723580796" ID="ID_453265164" MODIFIED="1717796591123" TEXT="der Builder erbt von dieser (Policy Mix-In)"/>
|
||||
<node CREATED="1717723599686" ID="ID_1353907596" MODIFIED="1717723615688" TEXT="sie mischt ihrerseits eine ElementFactory ein"/>
|
||||
<node CREATED="1717723625139" ID="ID_1954915705" MODIFIED="1717723635781" TEXT="Adapter-Methoden">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717723636675" ID="ID_1612255322" MODIFIED="1717723717303" TEXT="realloc">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717723636675" ID="ID_1612255322" MODIFIED="1717803199017" TEXT="realloc">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1717723720004" ID="ID_456348135" MODIFIED="1717723723226" TEXT="Anforderungen">
|
||||
<node CREATED="1717723724203" ID="ID_54813391" MODIFIED="1717723733914" TEXT="entscheidet intelligent was zu tun ist"/>
|
||||
<node CREATED="1717723724203" ID="ID_54813391" MODIFIED="1717801571693" TEXT="entscheidet intelligent ob und was zu tun ist"/>
|
||||
<node CREATED="1717723734527" ID="ID_184980735" MODIFIED="1717723746074" TEXT="unterstützt auch die normale (initiale) Allokation"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1717723747298" ID="ID_1111696667" MODIFIED="1717723776089" TEXT="kann mit dem unterliegenden Allokator eine Spezialbehandlung abstimmen">
|
||||
<icon BUILTIN="yes"/>
|
||||
|
|
@ -82405,6 +82405,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717776954529" ID="ID_103031227" MODIFIED="1717779551508" TEXT="Basis-Implementierung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#435e98" CREATED="1717801589821" ID="ID_1293735403" MODIFIED="1717803186231" TEXT="arbeitet explizit mit ArrayBucket">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#338800" CREATED="1717801612658" ID="ID_1718482523" MODIFIED="1717803181303" TEXT="bezieht von dort detailierte Metadaten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1717801627592" ID="ID_1687392869" MODIFIED="1717803182847" TEXT="bekommt darüberhinaus nur eine Größenanforderung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1717776962179" ID="ID_1142886481" MODIFIED="1717776966238" TEXT="wachsen">
|
||||
<node COLOR="#338800" CREATED="1717776973613" ID="ID_1749910669" MODIFIED="1717776980785" TEXT="exponentielle Erweiterung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -82559,8 +82568,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717796486424" ID="ID_505052942" MODIFIED="1717796637654" TEXT="Konsequenz: Storage umbauen">
|
||||
<arrowlink COLOR="#af28b1" DESTINATION="ID_719213336" ENDARROW="Default" ENDINCLINATION="-878;40;" ID="Arrow_ID_1140258959" STARTARROW="None" STARTINCLINATION="-190;-16;"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717796486424" ID="ID_505052942" MODIFIED="1717803235298" TEXT="Konsequenz: Storage umbauen">
|
||||
<arrowlink COLOR="#af28b1" DESTINATION="ID_719213336" ENDARROW="Default" ENDINCLINATION="-878;40;" ID="Arrow_ID_1140258959" STARTARROW="None" STARTINCLINATION="-488;-57;"/>
|
||||
<linktarget COLOR="#5a38d9" DESTINATION="ID_505052942" ENDARROW="Default" ENDINCLINATION="83;-42;" ID="Arrow_ID_1081178000" SOURCE="ID_1403509932" STARTARROW="None" STARTINCLINATION="-249;16;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
|
|
@ -82631,9 +82640,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1717795090715" ID="ID_921338481" MODIFIED="1717795104887" TEXT="construct nach reserve">
|
||||
<node CREATED="1717795334309" ID="ID_316562540" MODIFIED="1717795453788" TEXT="Fall-1+2 : spread paßt"/>
|
||||
<node CREATED="1717795455247" ID="ID_297247338" MODIFIED="1717795472585" TEXT="Fall-3a : spread paßt"/>
|
||||
<node CREATED="1717795473180" ID="ID_97000651" MODIFIED="1717795484438" TEXT="Fall-3b : spread zu klein"/>
|
||||
<node CREATED="1717795473180" ID="ID_97000651" MODIFIED="1717795484438" TEXT="Fall-3b : spread zu klein">
|
||||
<node CREATED="1717800522402" ID="ID_1139602600" MODIFIED="1717800541667" TEXT="⟵ nur möglich wenn leer oder in Fall-5"/>
|
||||
</node>
|
||||
<node CREATED="1717795513454" ID="ID_849597121" MODIFIED="1717795533783" TEXT="Fall-4a : spread paßt"/>
|
||||
<node CREATED="1717795534452" ID="ID_1159542667" MODIFIED="1717795551575" TEXT="Fall-4b : spread zu klein"/>
|
||||
<node CREATED="1717795534452" ID="ID_1159542667" MODIFIED="1717795551575" TEXT="Fall-4b : spread zu klein">
|
||||
<node CREATED="1717800522402" ID="ID_1599391300" MODIFIED="1717800541667" TEXT="⟵ nur möglich wenn leer oder in Fall-5"/>
|
||||
</node>
|
||||
<node CREATED="1717795553544" ID="ID_1475405867" MODIFIED="1717795587727" TEXT="Fall-5 ⟵ setzt hier Fall-3 oder Fall-4 vorraus"/>
|
||||
</node>
|
||||
<node CREATED="1717795105446" ID="ID_521456032" MODIFIED="1717795111470" TEXT="construct ohne reserve">
|
||||
|
|
|
|||
Loading…
Reference in a new issue