Library: attempt to build a re-alloc on top of the new adapter
...which basically ''seems doable'' now, yet turns up several unsolved problems - need a way to handle excess storage for the raw allocation - generally should relocate all metadata into the ArrayBucket - mismatch at various APIs; must re-think where to pass size explicitly - unclear yet how and where to pass the actual element type to create
This commit is contained in:
parent
24b3e5ceba
commit
154a7018be
3 changed files with 296 additions and 34 deletions
|
|
@ -43,8 +43,11 @@
|
|||
#define LIB_SEVERAL_BUILDER_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/several.hpp"
|
||||
#include "include/limits.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
|
@ -55,6 +58,8 @@
|
|||
|
||||
|
||||
namespace lib {
|
||||
namespace err = lumiera::error;
|
||||
|
||||
using std::vector;
|
||||
using std::forward;
|
||||
using std::move;
|
||||
|
|
@ -62,7 +67,9 @@ namespace lib {
|
|||
|
||||
namespace {// Allocation management policies
|
||||
|
||||
|
||||
using util::max;
|
||||
using util::min;
|
||||
using util::_Fmt;
|
||||
|
||||
template<class I, template<typename> class ALO>
|
||||
class ElementFactory
|
||||
|
|
@ -105,13 +112,13 @@ namespace lib {
|
|||
|
||||
using BucketAlloT = typename AlloT::template rebind_traits<Bucket>;
|
||||
auto bucketAllo = adaptAllocator<Bucket>();
|
||||
try { BucketAlloT::construct (bucketAllo, loc, spread); }
|
||||
try { BucketAlloT::construct (bucketAllo, reinterpret_cast<Bucket*> (loc), spread); }
|
||||
catch(...)
|
||||
{
|
||||
AlloT::deallocate (baseAllocator(), loc, storageBytes);
|
||||
throw;
|
||||
}
|
||||
return static_cast<Bucket*> (loc);
|
||||
return reinterpret_cast<Bucket*> (loc);
|
||||
};
|
||||
|
||||
template<class E, typename...ARGS>
|
||||
|
|
@ -137,8 +144,8 @@ namespace lib {
|
|||
for (size_t i=0; i<size; ++i)
|
||||
ElmAlloT::destroy (elmAllo, & bucket->subscript(i));
|
||||
|
||||
size_t storageBytes = calcSize (size, bucket->spread);
|
||||
AlloT::deallocate (baseAllocator(), bucket, storageBytes);
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -148,12 +155,56 @@ namespace lib {
|
|||
: ElementFactory<I, ALO>
|
||||
{
|
||||
using Fac = ElementFactory<I, ALO>;
|
||||
using Fac::Fac;
|
||||
using Bucket = ArrayBucket<I>;
|
||||
|
||||
void*
|
||||
realloc (void* data, size_t oldSiz, size_t newSiz)
|
||||
using Fac::Fac; // pass-through ctor
|
||||
|
||||
Bucket*
|
||||
realloc (Bucket* data, size_t cnt, size_t& storage, size_t demand)
|
||||
{
|
||||
UNIMPLEMENTED ("adjust memory allocation"); ///////////////////////////OOO Problem Objekte verschieben
|
||||
if (demand == storage)
|
||||
return data;
|
||||
if (demand > storage)
|
||||
{// 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));
|
||||
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 = demand / spread;
|
||||
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)));
|
||||
////////////////////////////////////////////////////////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;
|
||||
return newBucket;
|
||||
}
|
||||
else
|
||||
{// shrink into precisely fitting new allocation
|
||||
Bucket* newBucket{nullptr};
|
||||
if (cnt > 0)
|
||||
{
|
||||
REQUIRE (data);
|
||||
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;
|
||||
}
|
||||
return newBucket;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -209,8 +260,8 @@ namespace lib {
|
|||
* Wrap a vector holding objects of a subtype and
|
||||
* provide array-like access using the interface type.
|
||||
*/
|
||||
template<class I ///< Interface or base type visible on resulting Several<I>
|
||||
,class E =I ///< a subclass element element type (relevant when not trivially movable and destructible)
|
||||
template<class I ///< Interface or base type visible on resulting Several<I>
|
||||
,class E =I ///< a subclass element element type (relevant when not trivially movable and destructible)
|
||||
,class POL =HeapOwn<I> ///< Allocator policy
|
||||
>
|
||||
class SeveralBuilder
|
||||
|
|
@ -218,7 +269,7 @@ namespace lib {
|
|||
, util::MoveOnly
|
||||
, POL
|
||||
{
|
||||
using Col = Several<I>;
|
||||
using Coll = Several<I>;
|
||||
|
||||
size_t storageSiz_{0};
|
||||
|
||||
|
|
@ -236,7 +287,7 @@ namespace lib {
|
|||
SeveralBuilder&&
|
||||
reserve (size_t cntElm)
|
||||
{
|
||||
adjustStorage (cntElm, sizeof(I));
|
||||
adjustStorage (cntElm, sizeof(E));
|
||||
return move(*this);
|
||||
}
|
||||
|
||||
|
|
@ -258,19 +309,24 @@ namespace lib {
|
|||
void
|
||||
adjustStorage (size_t cnt, size_t spread)
|
||||
{
|
||||
if (cnt*spread > storageSiz_)
|
||||
size_t demand{cnt*spread};
|
||||
if (demand > storageSiz_)
|
||||
{ // need more storage...
|
||||
Col::data_ = static_cast<typename Col::Bucket> (POL::realloc (Col::data_, storageSiz_, cnt*spread));
|
||||
storageSiz_ = cnt*spread;
|
||||
Coll::data_ = static_cast<typename Coll::Bucket> (POL::realloc (Coll::data_, Coll::size_, storageSiz_, demand));
|
||||
}
|
||||
ENSURE (Col::data_);
|
||||
if (spread != Col::data_->spread)
|
||||
ENSURE (Coll::data_);
|
||||
if (spread != Coll::data_->spread)
|
||||
adjustSpread (spread);
|
||||
|
||||
if (cnt*spread < storageSiz_)
|
||||
}
|
||||
|
||||
void
|
||||
fitStorage()
|
||||
{
|
||||
if (not Coll::data_) return;
|
||||
size_t demand{Coll::size_ * Coll::data_->spread};
|
||||
if (demand < storageSiz_)
|
||||
{ // attempt to shrink storage
|
||||
Col::data_ = static_cast<typename Col::Bucket> (POL::realloc (Col::data_, storageSiz_, cnt*spread));
|
||||
storageSiz_ = cnt*spread;
|
||||
Coll::data_ = static_cast<typename Coll::Bucket> (POL::realloc (Coll::data_, Coll::size_, storageSiz_, demand));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,20 +334,20 @@ namespace lib {
|
|||
void
|
||||
adjustSpread (size_t newSpread)
|
||||
{
|
||||
REQUIRE (Col::size_);
|
||||
REQUIRE (Col::data_);
|
||||
REQUIRE (newSpread * Col::size_ <= storageSiz_);
|
||||
size_t oldSpread = Col::data_->spread;
|
||||
REQUIRE (Coll::size_);
|
||||
REQUIRE (Coll::data_);
|
||||
REQUIRE (newSpread * Coll::size_ <= storageSiz_);
|
||||
size_t oldSpread = Coll::data_->spread;
|
||||
if (newSpread > oldSpread)
|
||||
// need to spread out
|
||||
for (size_t i=Col::size_-1; 0<i; --i)
|
||||
for (size_t i=Coll::size_-1; 0<i; --i)
|
||||
shiftStorage (i, oldSpread, newSpread);
|
||||
else
|
||||
// attempt to condense spread
|
||||
for (size_t i=1; i<Col::size_; ++i)
|
||||
for (size_t i=1; i<Coll::size_; ++i)
|
||||
shiftStorage (i, oldSpread, newSpread);
|
||||
// data elements now spaced by new spread
|
||||
Col::data_->spread = newSpread;
|
||||
Coll::data_->spread = newSpread;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -300,8 +356,8 @@ namespace lib {
|
|||
REQUIRE (idx);
|
||||
REQUIRE (oldSpread);
|
||||
REQUIRE (newSpread);
|
||||
REQUIRE (Col::data_);
|
||||
byte* oldPos = Col::data_->storage;
|
||||
REQUIRE (Coll::data_);
|
||||
byte* oldPos = Coll::data_->storage;
|
||||
byte* newPos = oldPos;
|
||||
oldPos += idx * oldSpread;
|
||||
newPos += idx * newSpread;
|
||||
|
|
@ -314,14 +370,14 @@ namespace lib {
|
|||
{
|
||||
using Val = typename IT::value_type;
|
||||
size_t elmSiz = sizeof(Val);
|
||||
adjustStorage (Col::size_+1, requiredSpread(elmSiz));
|
||||
adjustStorage (Coll::size_+1, requiredSpread(elmSiz));
|
||||
UNIMPLEMENTED ("emplace data");
|
||||
}
|
||||
|
||||
size_t
|
||||
requiredSpread (size_t elmSiz)
|
||||
{
|
||||
size_t currSpread = Col::empty()? 0 : Col::data_->spread;
|
||||
size_t currSpread = Coll::empty()? 0 : Coll::data_->spread;
|
||||
return util::max (currSpread, elmSiz);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,36 @@
|
|||
|
||||
|
||||
/** @file several.hpp
|
||||
** Abstraction interface: array-like access by subscript
|
||||
** Abstraction interface: array-like random access by subscript.
|
||||
**
|
||||
** # Design
|
||||
**
|
||||
** This is a data structure abstraction suitable for performance critical code.
|
||||
** It is used pervasively in the backbone of the Lumiera »Render Node Network«.
|
||||
** - usage is clear and concise, allowing to hide implementation details
|
||||
** - adaption and optimisation for various usage patterns is possible
|
||||
** - suitably fast read access with a limited amount of indirections
|
||||
** \par why not `std::vector`?
|
||||
** The most prevalent STL container _almost_ fulfils the above mentioned criteria,
|
||||
** and thus served as a blueprint for design and implementations. Some drawbacks
|
||||
** however prevent its direct use for this purpose. Notably, `std::vector` leaks
|
||||
** implementation details of the contained data and generally exposes way too much
|
||||
** operations; it is not possible to abstract away the concrete element type.
|
||||
** Moreover, using `vector` with a custom allocator is surprisingly complicated,
|
||||
** requires to embody the concrete allocator type into the container type and
|
||||
** requires to store an additional back-link whenever the allocator is not
|
||||
** a _monostate._ The intended use case calls for a large number of small
|
||||
** collection elements, which are repeatedly bulk- allocated and deallocated.
|
||||
**
|
||||
** The lib::Several container is a smart front-end and exposes array-style
|
||||
** random access through references to a interface type. It can only be created
|
||||
** and populated through a builder, and is immutable during lifetime, while it
|
||||
** can hold non-const element data. The actual implementation data types and the
|
||||
** allocator framework used are _not exposed in the front-end's type signature._
|
||||
** The container is single-ownership (move-asignable); some additional metadata
|
||||
** and the data storage reside in an `ArrayBucket<I>`, managed by the allocator.
|
||||
** In its simplest form, this storage is heap allocated and automatically deleted.
|
||||
**
|
||||
** @todo as of 2016, this concept seems very questionable: do we _really_ want
|
||||
** to abstract over random access, or do we _actually_ want for-iteration??
|
||||
** @warning WIP-WIP-WIP in rework 5/2025
|
||||
|
|
|
|||
|
|
@ -82293,6 +82293,37 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1717543083078" ID="ID_530261806" MODIFIED="1717543114805" TEXT="getMover()"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777101317" ID="ID_826816346" MODIFIED="1717777105434" TEXT="konkret einbinden">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777109755" ID="ID_1395035594" MODIFIED="1717777115683" TEXT="neue Elemente erstellen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777153193" ID="ID_626770308" MODIFIED="1717777157073" TEXT="Element-Typ">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777157905" ID="ID_1190162917" MODIFIED="1717777164089" TEXT="beliebiger Typ">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777167167" ID="ID_893092417" MODIFIED="1717777178595" TEXT="hier die Einschränkungen korrekt einarbeiten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node CREATED="1717777223888" ID="ID_1213625055" MODIFIED="1717777230003" TEXT="die wild-move-Flag"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1717777186269" ID="ID_473170944" MODIFIED="1717777213678" TEXT="can Destroy?">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1717777198480" ID="ID_158380654" MODIFIED="1717777204412" TEXT="canDynGrow?">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777116726" ID="ID_1692491444" MODIFIED="1717777127002" TEXT="resize mit Element-Typ">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777127619" ID="ID_42350747" MODIFIED="1717777133490" TEXT="resize auf gegebenen Spread">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777134500" ID="ID_1083429601" MODIFIED="1717777151106" TEXT="shrink-to-fit">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717723412216" ID="ID_1483275702" MODIFIED="1717723419487" TEXT="Allokator flexibel einbinden">
|
||||
|
|
@ -82326,6 +82357,39 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717776954529" ID="ID_103031227" MODIFIED="1717779551508" TEXT="Basis-Implementierung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<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"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1717776981387" ID="ID_631542593" MODIFIED="1717776987939" TEXT="safety-Limit einbauen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717779506814" ID="ID_584325941" MODIFIED="1717779525853" TEXT="Objekte umkopieren">
|
||||
<linktarget COLOR="#ec1c03" DESTINATION="ID_584325941" ENDARROW="Default" ENDINCLINATION="167;18;" ID="Arrow_ID_1090340504" SOURCE="ID_184907732" STARTARROW="None" STARTINCLINATION="178;0;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1717776994933" ID="ID_916393989" MODIFIED="1717777035492" TEXT="Problem: nicht genau passende Storage">
|
||||
<arrowlink COLOR="#d84591" DESTINATION="ID_1878698297" ENDARROW="Default" ENDINCLINATION="13;-122;" ID="Arrow_ID_605494253" STARTARROW="None" STARTINCLINATION="-436;31;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1717776966802" ID="ID_1301179349" MODIFIED="1717776969877" TEXT="schrumpfen">
|
||||
<node COLOR="#338800" CREATED="1717779536089" ID="ID_1997959648" MODIFIED="1717779542019" TEXT="leer-Fall ausschließen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1717779506814" ID="ID_1523639170" MODIFIED="1717779525853" TEXT="Objekte umkopieren">
|
||||
<linktarget COLOR="#ec1c03" DESTINATION="ID_1523639170" ENDARROW="Default" ENDINCLINATION="167;18;" ID="Arrow_ID_15683997" SOURCE="ID_184907732" STARTARROW="None" STARTINCLINATION="178;0;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1717777049607" ID="ID_184907732" MODIFIED="1717779530415" TEXT="brauche den konkreten Zieltyp hier">
|
||||
<arrowlink COLOR="#ec1c03" DESTINATION="ID_584325941" ENDARROW="Default" ENDINCLINATION="167;18;" ID="Arrow_ID_1090340504" STARTARROW="None" STARTINCLINATION="178;0;"/>
|
||||
<arrowlink COLOR="#ec1c03" DESTINATION="ID_1523639170" ENDARROW="Default" ENDINCLINATION="167;18;" ID="Arrow_ID_15683997" STARTARROW="None" STARTINCLINATION="178;0;"/>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1717723649872" ID="ID_1412900866" MODIFIED="1717723682406" TEXT="Deleter einbinden?">
|
||||
<linktarget COLOR="#e1073d" DESTINATION="ID_1412900866" ENDARROW="Default" ENDINCLINATION="344;0;" ID="Arrow_ID_453255140" SOURCE="ID_1791379026" STARTARROW="Default" STARTINCLINATION="344;0;"/>
|
||||
|
|
@ -82336,6 +82400,119 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1717770993835" ID="ID_1878698297" MODIFIED="1717777028572" TEXT="Problem: Größe der Basis-Allokation">
|
||||
<linktarget COLOR="#d84591" DESTINATION="ID_1878698297" ENDARROW="Default" ENDINCLINATION="13;-122;" ID="Arrow_ID_605494253" SOURCE="ID_916393989" STARTARROW="None" STARTINCLINATION="-436;31;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1717771028662" ID="ID_1266328566" MODIFIED="1717771040728" TEXT="diese könnte....">
|
||||
<node CREATED="1717771041580" ID="ID_710954788" MODIFIED="1717771046512" TEXT="überdimensioniert sein"/>
|
||||
<node CREATED="1717771047298" ID="ID_1301246479" MODIFIED="1717771060366" TEXT="nicht genau auf den Element-Spread aufgehen"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1717771086306" ID="ID_382189850" MODIFIED="1717771413927" TEXT="muß diesen Wert zur de-Allokation kennen">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1717771137791" ID="ID_1321354068" MODIFIED="1717771166027">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
das ist jetzt <b>noch ein weiteres</b> extra Datenfeld
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
<node CREATED="1717771172737" ID="ID_339804394" MODIFIED="1717771190676" TEXT="das läge zwar im Bucket in der Storage"/>
|
||||
<node CREATED="1717771200623" ID="ID_79846525" MODIFIED="1717771208658" TEXT="trotzdem ärgerlich">
|
||||
<node CREATED="1717771319363" ID="ID_165772412" MODIFIED="1717771389855" TEXT="weil es für den Haupt-Anwendungsfall gar nicht gebraucht wird">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
denn der Allocation-Cluster weiß selber die Zahl seiner belegten Roh-Blöcke; zur de-Allokation muß ansonsten gar nichts gemacht werden
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1717771640460" ID="ID_1646507168" MODIFIED="1717771661118" TEXT="weil die Datenstruktur doch so schön elegant sein sollte....">
|
||||
<icon BUILTIN="smiley-oh"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1717771668227" ID="ID_218024173" MODIFIED="1717771674057" TEXT="was für Auswege gibt es?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1717771677991" ID="ID_1848656527" MODIFIED="1717771708671" TEXT="das zusätzliche Datenfeld einfach akzeptieren">
|
||||
<node CREATED="1717771763428" ID="ID_823499935" MODIFIED="1717771767903" TEXT="leicht zu implementieren"/>
|
||||
<node CREATED="1717771768371" ID="ID_370564159" MODIFIED="1717771775678" TEXT="sicher und klar"/>
|
||||
<node CREATED="1717771790928" ID="ID_1239859891" MODIFIED="1717772007103" TEXT="Irre verschwenderisch">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Der vermutlich häufigste Fall ist ein Several<ProcNode*> — mit typischerweise genau einem Element mit einem »Slot«Größe. Dafür haben wir jetzt schon 4 »Slot« Overhead, und jetzt sollen das 5 »Slot« werden....
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1717771727481" ID="ID_1872517693" MODIFIED="1717771751937" TEXT="am Ende des Build-Vorganges stets ein shrink-to-fit machen">
|
||||
<node CREATED="1717772013611" ID="ID_789464480" MODIFIED="1717772040435" TEXT="im Fall Allocation-Cluster ist das im Regelfall transparent in-place möglich"/>
|
||||
<node CREATED="1717772041335" ID="ID_871652702" MODIFIED="1717772085852" TEXT="wenn nicht, dann verschwenden wir im AllocationCluster den ganzen bisherigen Platz"/>
|
||||
<node CREATED="1717772086536" ID="ID_1322940252" MODIFIED="1717772099619" TEXT="und für Heap-Allokation müssen wir zumindest noch einmal alles umkopieren"/>
|
||||
</node>
|
||||
<node CREATED="1717773260668" ID="ID_1403509932" MODIFIED="1717773690731" TEXT="das ArrayBucket dynamisch flexibel machen">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1717773280353" ID="ID_1332303474" MODIFIED="1717773295509" TEXT="alle weiteren Metadaten liegen im ArrayBucket"/>
|
||||
<node CREATED="1717773296351" ID="ID_129834213" MODIFIED="1717773606110" TEXT="dabei wird ein spezielles optimiertes Placement verwendet">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...das heißt, wir verwenden im ersten »Slot« ein Bit-Feld, da die Zahl der Elemente ohnehin praktisch begrenzt ist (auf ein paar Hundert); in den freien oberen Bits kann daher das konkrete weitere Layout encodiert werden. Das kostet nur einen minimalen Runtime-Overhead (ein paar Bit-Manipulationen vor der Indirektion zum Datenelement, welches ebenfalls im Cache liegt). Der intendierte use-case nutzt diese Collection als Basis einer verzeigerten Datenstruktur, und nicht in einer innersten Loop.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1717773313924" ID="ID_1133884189" MODIFIED="1717773348408" TEXT="im wichtigsten Standardfall kann damit die Storage auf 1 »slot« reduziert werden">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1717773611076" ID="ID_569133844" MODIFIED="1717773685833">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<u>besonderes geschickt</u>: <i>man kann das „später mal“ machen</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Denn Lumiera hat im Moment wirklich andere Sorgen, als die Optimierung einer nocht-gar-nicht-wirklich-genutzten Datenstruktur
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1716914864769" ID="ID_966642586" MODIFIED="1716914906125" TEXT="Builder-Operationen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue