Library: allow for dynamic adjustments in AllocationCluster
This is a low-level interface to allow changing the size of the currently latest allocation in `AllocationCluster`; a client aware of this capability can perform a real »in-place re-alloc«, assuming the very specific usage constraints can be met. `lib::Several<X>` will use this feature when attached to an `AllocationCluster`; with this special setup, an previously unknown number of non-copyable objects can be built without wasting any storage, as long as the storage reserve in the current extent of the `AllocationCluster` is sufficient.
This commit is contained in:
parent
3bbdf40c32
commit
bb164e37c8
4 changed files with 258 additions and 53 deletions
|
|
@ -30,6 +30,13 @@
|
|||
** pattern. Optionally it is even possible to skip invocation of object
|
||||
** destructors, making de-allocation highly efficient (typically the
|
||||
** memory pages are already cache-cold when about to discarded).
|
||||
** \par using as STL allocator
|
||||
** AllocationCluster::Allocator is an adapter to expose the interface
|
||||
** expected by std::allocator_traits (and thus usable by all standard compliant
|
||||
** containers). With this usage, the container _manages_ the contained objects,
|
||||
** including the invocation of their destructors, while relying on the allocator
|
||||
** to allot and discard bare memory. However, to avoid invoking any destructors,
|
||||
** the container itself can be created with AllocationCluster::createDisposable.
|
||||
** @warning deliberately *not threadsafe*.
|
||||
** @remark confine usage to a single thread or use thread-local clusters.
|
||||
** @see allocation-cluster-test.cpp
|
||||
|
|
@ -52,6 +59,7 @@
|
|||
|
||||
namespace lib {
|
||||
namespace test { class AllocationCluster_test; } // declared friend for low-level-checks
|
||||
namespace err = lumiera::error;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -77,17 +85,23 @@ namespace lib {
|
|||
void* pos{nullptr};
|
||||
size_t rest{0};
|
||||
|
||||
auto bytePos() { return static_cast<std::byte*> (pos); }
|
||||
|
||||
void*
|
||||
allot (size_t bytes, size_t alignment)
|
||||
{
|
||||
void* loc = std::align (alignment, bytes, pos, rest);
|
||||
if (loc)
|
||||
{ // requested allocation indeed fits in space
|
||||
pos = static_cast<std::byte*>(pos) + bytes;
|
||||
pos = bytePos() + bytes;
|
||||
rest -= bytes;
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
void adjustPos (int offset);
|
||||
bool hasReserve (int offset) const;
|
||||
bool matches_last_allocation (void const* loc, size_t siz) const;
|
||||
};
|
||||
Storage storage_;
|
||||
|
||||
|
|
@ -131,6 +145,9 @@ namespace lib {
|
|||
Allocator<X> getAllocator() { return this; }
|
||||
|
||||
|
||||
bool canAdjust (void* loc, size_t oldSiz, size_t newSiz) const;
|
||||
void doAdjust (void* loc, size_t oldSiz, size_t newSiz);
|
||||
|
||||
private:
|
||||
/**
|
||||
* portion out the requested amount of memory,
|
||||
|
|
@ -195,7 +212,7 @@ namespace lib {
|
|||
* but *without invoking its destructor* on clean-up (for performance reasons).
|
||||
*/
|
||||
template<class TY, typename...ARGS>
|
||||
TY&
|
||||
inline TY&
|
||||
AllocationCluster::createDisposable (ARGS&& ...args)
|
||||
{
|
||||
return * new(allot<TY>()) TY (std::forward<ARGS> (args)...);
|
||||
|
|
@ -207,7 +224,7 @@ namespace lib {
|
|||
* @note whenever possible, the #createDisposable variant should be preferred
|
||||
*/
|
||||
template<class TY, typename...ARGS>
|
||||
TY&
|
||||
inline TY&
|
||||
AllocationCluster::create (ARGS&& ...args)
|
||||
{
|
||||
if constexpr (std::is_trivial_v<TY>)
|
||||
|
|
@ -220,5 +237,55 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adjust the size of the latest raw memory allocation dynamically.
|
||||
* @param loc an allocation provided by this AllocationCluster
|
||||
* @param oldSiz the size requested for the allocation \a loc
|
||||
* @param newSiz desired new size for this allocation
|
||||
* @remarks since AllocationCluster must be used in a single threaded environment,
|
||||
* the invoking code can sometimes arrange to adapt the latest allocation
|
||||
* to a dynamically changing situation, like e.g. populating a container
|
||||
* with a previously unknown number of elements. Obviously, the overall
|
||||
* allocation must stay within the confines of the current extent; it
|
||||
* is thus mandatory to [check](\ref canAdjust) the ability beforehand.
|
||||
*/
|
||||
inline void
|
||||
AllocationCluster::doAdjust(void* loc, size_t oldSiz, size_t newSiz)
|
||||
{
|
||||
if (not canAdjust (loc,oldSiz,newSiz))
|
||||
throw err::Invalid {"AllocationCluster: unable to perform this allocation adjustment."};
|
||||
storage_.adjustPos (int(newSiz) - int(oldSiz));
|
||||
}
|
||||
|
||||
inline bool
|
||||
AllocationCluster::canAdjust(void* loc, size_t oldSiz, size_t newSiz) const
|
||||
{
|
||||
int offset{int(newSiz) - int(oldSiz)}; // is properly limited iff oldSiz is correct
|
||||
return storage_.matches_last_allocation (loc, oldSiz)
|
||||
and storage_.hasReserve (offset);
|
||||
}
|
||||
|
||||
inline void
|
||||
AllocationCluster::Storage::adjustPos (int offset) ///< @warning be sure a negative offset is properly limited
|
||||
{
|
||||
REQUIRE (pos);
|
||||
REQUIRE (hasReserve (rest));
|
||||
pos = bytePos() + offset;
|
||||
rest -= offset;
|
||||
}
|
||||
|
||||
inline bool
|
||||
AllocationCluster::Storage::hasReserve (int offset) const
|
||||
{
|
||||
return offset <= int(rest);
|
||||
}
|
||||
|
||||
inline bool
|
||||
AllocationCluster::Storage::matches_last_allocation (void const* loc, size_t siz) const
|
||||
{
|
||||
return loc == static_cast<std::byte const*> (pos) - siz;
|
||||
}
|
||||
|
||||
|
||||
} // namespace lib
|
||||
#endif /*LIB_ALLOCATION_CLUSTER_H*/
|
||||
|
|
|
|||
|
|
@ -250,8 +250,6 @@ namespace lib {
|
|||
|
||||
using Fac::Fac; // pass-through ctor
|
||||
|
||||
const bool isDisposable{false}; ///< memory must be explicitly deallocated
|
||||
|
||||
bool canExpand(size_t){ return false; }
|
||||
|
||||
Bucket*
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ namespace test {
|
|||
checkLifecycle();
|
||||
verifyInternals();
|
||||
use_as_Allocator();
|
||||
dynamicAdjustment();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -220,7 +221,6 @@ namespace test {
|
|||
* the additional metadata overhead is a power of two, exploiting contextual knowledge
|
||||
* about layout; moreover, a special usage-mode allows to skip invocation of destructors.
|
||||
* To document these machinations, change to internal data is explicitly verified here.
|
||||
* @todo WIP 5/24 ✔ define ⟶ ✔ implement
|
||||
*/
|
||||
void
|
||||
verifyInternals()
|
||||
|
|
@ -397,7 +397,7 @@ namespace test {
|
|||
AllocationCluster clu;
|
||||
CHECK (clu.numExtents() == 0);
|
||||
|
||||
VecI veci{clu.getAllocator<uint16_t>()};
|
||||
VecI vecI{clu.getAllocator<uint16_t>()};
|
||||
|
||||
// Since vector needs a contiguous allocation,
|
||||
// the maximum number of elements is limited by the Extent size (256 bytes - 2*sizeof(void*))
|
||||
|
|
@ -406,20 +406,91 @@ namespace test {
|
|||
const uint MAX = 64;
|
||||
|
||||
for (uint i=1; i<=MAX; ++i)
|
||||
veci.push_back(i);
|
||||
vecI.push_back(i);
|
||||
CHECK (clu.numExtents() == 2);
|
||||
CHECK (veci.capacity() == 64);
|
||||
CHECK (vecI.capacity() == 64);
|
||||
|
||||
// fill a set with random strings...
|
||||
SetS sets{clu.getAllocator<Strg>()};
|
||||
SetS setS{clu.getAllocator<Strg>()};
|
||||
|
||||
for (uint i=0; i<NUM_OBJECTS; ++i)
|
||||
sets.emplace (test::randStr(32), clu.getAllocator<char>());
|
||||
CHECK (sets.size() > 0.9 * NUM_OBJECTS);
|
||||
setS.emplace (test::randStr(32), clu.getAllocator<char>());
|
||||
CHECK (setS.size() > 0.9 * NUM_OBJECTS);
|
||||
CHECK (clu.numExtents() > 200);
|
||||
|
||||
// verify the data in the first allocation is intact
|
||||
CHECK (explore(veci).resultSum() == sum(64));
|
||||
CHECK (explore(vecI).resultSum() == sum(64));
|
||||
}
|
||||
|
||||
|
||||
/** @test verify the ability to adjust the latest allocation dynamically.
|
||||
*/
|
||||
void
|
||||
dynamicAdjustment()
|
||||
{
|
||||
AllocationCluster clu;
|
||||
auto& l1 = clu.create<array<uchar,12>>();
|
||||
CHECK (clu.numExtents() == 1);
|
||||
CHECK (clu.numBytes() == 12);
|
||||
|
||||
auto& l2 = clu.create<array<uchar,5>>();
|
||||
CHECK (clu.numExtents() == 1);
|
||||
CHECK (clu.numBytes() == 17);
|
||||
|
||||
CHECK ( clu.canAdjust (&l2, 5, 8)); // possible since l2 is verifiable as last allocation
|
||||
CHECK ( clu.canAdjust (&l2, 5, 5)); // arbitrary adjustments are then possible
|
||||
CHECK ( clu.canAdjust (&l2, 5, 2));
|
||||
CHECK ( clu.canAdjust (&l2, 5, 0)); // even shrinking to zero
|
||||
CHECK (not clu.canAdjust (&l1, 12,24)); // but the preceding allocation can not be changed anymore
|
||||
CHECK (not clu.canAdjust (&l2, 6, 8)); // similarly, reject requests when passing wrong original size
|
||||
CHECK (not clu.canAdjust (&l2, 4, 8));
|
||||
CHECK (not clu.canAdjust (&l2, 5, 1000)); // also requests exceeding the remaining extent space are rejected
|
||||
CHECK ( clu.canAdjust (&l1, 17,24)); // however, can not detect if a passed wrong size accidentally matches
|
||||
|
||||
CHECK (clu.numExtents() == 1);
|
||||
CHECK (clu.numBytes() == 17);
|
||||
l1[11] = 11; // put some marker values into the storage
|
||||
l2[0] = 5;
|
||||
l2[1] = 4;
|
||||
l2[2] = 3;
|
||||
l2[3] = 2;
|
||||
l2[4] = 1;
|
||||
l2[5] = 55; // yes, even behind the valid range (subscript is unchecked)
|
||||
l2[6] = 66;
|
||||
|
||||
using LERR_(INVALID);
|
||||
|
||||
VERIFY_ERROR (INVALID, clu.doAdjust(&l1, 12,24) );
|
||||
CHECK (clu.numExtents() == 1);
|
||||
CHECK (clu.numBytes() == 17);
|
||||
|
||||
// perform a size adjustment on the latest allocation
|
||||
clu.doAdjust (&l2, 5,12);
|
||||
CHECK (clu.numExtents() == 1);
|
||||
CHECK (clu.numBytes() == 24);
|
||||
// no memory corruption
|
||||
CHECK (l1[11] == 11);
|
||||
CHECK (l2[0] == 5);
|
||||
CHECK (l2[1] == 4);
|
||||
CHECK (l2[2] == 3);
|
||||
CHECK (l2[3] == 2);
|
||||
CHECK (l2[4] == 1);
|
||||
CHECK (l2[5] == 55);
|
||||
CHECK (l2[6] == 66);
|
||||
|
||||
// scale down the latest allocation completely
|
||||
clu.doAdjust (&l2, 12,0);
|
||||
CHECK (clu.numExtents() == 1);
|
||||
CHECK (clu.numBytes() == 12);
|
||||
// no memory corruption
|
||||
CHECK (l1[11] == 11);
|
||||
CHECK (l2[0] == 5);
|
||||
CHECK (l2[1] == 4);
|
||||
CHECK (l2[2] == 3);
|
||||
CHECK (l2[3] == 2);
|
||||
CHECK (l2[4] == 1);
|
||||
CHECK (l2[5] == 55);
|
||||
CHECK (l2[6] == 66);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -81325,9 +81325,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1715526412553" ID="ID_1310310561" MODIFIED="1715526457239" TEXT="bietet zusätzlich die Fähigkeit zur inplace-Allokation"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1715530825487" ID="ID_744922331" MODIFIED="1715530828707" TEXT="Design">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1715530839818" ID="ID_1299414083" MODIFIED="1715530843266" TEXT="Analyse">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1715530844562" ID="ID_598901793" MODIFIED="1715530852442" TEXT="warum nicht einen Vector?">
|
||||
<node COLOR="#338800" CREATED="1715530839818" FOLDED="true" ID="ID_1299414083" MODIFIED="1718320555733" TEXT="Analyse">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1715530844562" ID="ID_598901793" MODIFIED="1718320534356" TEXT="warum nicht einen Vector?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1715530856096" ID="ID_1985014876" MODIFIED="1715530876386" TEXT="im Grunde brauchen wir ein Array"/>
|
||||
<node CREATED="1715530878893" ID="ID_155576825" MODIFIED="1715530901590" TEXT="das Vector-Interface ist zu mächtig (und zu konkret)"/>
|
||||
|
|
@ -81346,11 +81346,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1715532455035" ID="ID_1288992537" MODIFIED="1715532458010" TEXT="ich möchte">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1715532455035" ID="ID_1288992537" MODIFIED="1718320531044" TEXT="ich möchte">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1715532458922" ID="ID_716858129" MODIFIED="1715532474934" TEXT="Zugriff auf bestehende Elemente"/>
|
||||
<node CREATED="1715532475464" ID="ID_618278235" MODIFIED="1715532480906" TEXT="Elemente sind aber non-const"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1715532483303" ID="ID_622474774" MODIFIED="1715532787640" TEXT="konkreter Element-Typ kann erased sein?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1715532483303" ID="ID_622474774" MODIFIED="1718320526176" TEXT="konkreter Element-Typ kann erased sein">
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
<node CREATED="1715532503700" ID="ID_1038248531" MODIFIED="1715532511472" TEXT="Länge als State"/>
|
||||
<node CREATED="1715532672941" ID="ID_1970537209" MODIFIED="1715532683208" TEXT="feste Größe (unabhängig von Element-Storage)"/>
|
||||
|
|
@ -81383,7 +81384,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1715532630466" ID="ID_169592902" MODIFIED="1715533548154" TEXT="muß dazu passenden Builder konzipieren...">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1715532833936" ID="ID_1009009693" MODIFIED="1715532840949" TEXT="Problem: Link zum Allocator">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1715532833936" ID="ID_1009009693" MODIFIED="1718320501473" TEXT="Problem: Link zum Allocator">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1715532843871" ID="ID_774375232" MODIFIED="1715532859150" TEXT="entweder der Allocator wird als Pointer mitgeschleppt">
|
||||
<node CREATED="1715532914728" ID="ID_1541420443" MODIFIED="1715532932838" TEXT="erfordert entweder separates Allocator-Objekt"/>
|
||||
|
|
@ -81411,7 +81412,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1715533107500" ID="ID_1456027641" MODIFIED="1715533121838" TEXT="idealerweise Wachstumsfähigkeit wie ein Vector"/>
|
||||
<node CREATED="1715533124273" ID="ID_508327678" MODIFIED="1715533140797" TEXT="Inhalt eines Vectors komplett per move übernehmen"/>
|
||||
<node CREATED="1715533141623" ID="ID_1757204023" MODIFIED="1715533168654" TEXT="Inhalt eines Array komplett übernehmen"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1715533192160" ID="ID_1324375347" MODIFIED="1715533214590" TEXT="Problem: deleter / braucht impliziten Link zum Allocator">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1715533192160" ID="ID_1324375347" MODIFIED="1718320493417" TEXT="Problem: deleter / braucht impliziten Link zum Allocator">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1715533228879" ID="ID_1909155403" MODIFIED="1715533251166" TEXT="der Destruktor muß wissen wie der Storage-Block freizugeben ist"/>
|
||||
<node CREATED="1715533251792" ID="ID_1479555840" MODIFIED="1715533283445" TEXT="u.u. muß überhaupt keine Freigabe gemacht werden">
|
||||
|
|
@ -81502,7 +81503,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...man verwendet <i>nur speziell im produktiven Einsatz im Node-Graph</i>  einen besonderen Allocator, der zwar den Destruktor aufruft, aber den Speicher nicht freigibt; alloziert wird immer in einen kompakten Block hinein, der dann auf der Basis der Prozeß-Kenntnis als Ganzes verworfen und neu verwendet wird.
|
||||
...man verwendet <i>nur speziell im produktiven Einsatz im Node-Graph</i> einen besonderen Allocator, der zwar den Destruktor aufruft, aber den Speicher nicht freigibt; alloziert wird immer in einen kompakten Block hinein, der dann auf der Basis der Prozeß-Kenntnis als Ganzes verworfen und neu verwendet wird.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
|
|
@ -81661,7 +81662,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1715627027263" ID="ID_1272289707" MODIFIED="1716848766314" TEXT="Aufgabe: den Standard-Allocator besser verstehen">
|
||||
<node COLOR="#435e98" CREATED="1715627027263" FOLDED="true" ID="ID_1272289707" MODIFIED="1716848766314" TEXT="Aufgabe: den Standard-Allocator besser verstehen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1715627069918" ID="ID_1496924967" MODIFIED="1715627170299" TEXT="es könnte nämlich eine Konvergenz geben">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -82642,11 +82643,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</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 COLOR="#338800" CREATED="1717777116726" ID="ID_1692491444" MODIFIED="1718320365056" TEXT="resize mit Element-Typ">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777127619" ID="ID_42350747" MODIFIED="1717777133490" TEXT="resize auf gegebenen Spread">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1717777127619" ID="ID_42350747" MODIFIED="1718320366608" TEXT="resize auf gegebenen Spread">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1717777134500" ID="ID_1083429601" MODIFIED="1717777151106" TEXT="shrink-to-fit">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -82831,9 +82832,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1718212749620" ID="ID_1659701829" MODIFIED="1718213228515">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
sonst würde eine Spread-Vergrößerung
|
||||
|
|
@ -82842,12 +82841,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
tatsächlich die Reserve <i>verkleinern...</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
|
|
@ -82876,8 +82872,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<u>Begründung</u>: das ganze Thema »spread« ist extrem technisch und für den Nutzer normalerweise nicht nachvollziehbar, aber die Kapazität in Anzahl der freien Slots ist sehr wohl verständlich für den User; es wäre also <i>ziemlich überraschend</i> wenn — scheinbar ohne ersichtlichen Grund — plötzlich die Reserve-Kapazität verschwunden wäre.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1717893967870" ID="ID_1707818601" MODIFIED="1717894043447" TEXT="Spread-Anpassung zweistufig">
|
||||
|
|
@ -82970,8 +82965,18 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718328808453" ID="ID_119150059" MODIFIED="1718328816482" TEXT="Spezialisierung für AllocationCluster">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1718328836352" ID="ID_456408300" MODIFIED="1718328872260" TEXT="Trigger: der Standard-Allocator-Adapter von AllocationCluster">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1717770993835" ID="ID_1878698297" MODIFIED="1718073615124" TEXT="Problem: Größe der Basis-Allokation">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718328650553" ID="ID_1053724868" MODIFIED="1718328832230" TEXT="dynamische Allokations-Änderung einbinden">
|
||||
<arrowlink COLOR="#415ab7" DESTINATION="ID_1869643772" ENDARROW="Default" ENDINCLINATION="-1433;-63;" ID="Arrow_ID_166309661" STARTARROW="None" STARTINCLINATION="1447;92;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1717770993835" FOLDED="true" ID="ID_1878698297" MODIFIED="1718073615124" TEXT="Problem: Größe der Basis-Allokation">
|
||||
<linktarget COLOR="#6045d8" DESTINATION="ID_1878698297" ENDARROW="Default" ENDINCLINATION="13;-122;" ID="Arrow_ID_605494253" SOURCE="ID_916393989" STARTARROW="None" STARTINCLINATION="-437;29;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1717771028662" ID="ID_1266328566" MODIFIED="1717771040728" TEXT="diese könnte....">
|
||||
|
|
@ -82994,16 +82999,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1717771200623" ID="ID_79846525" MODIFIED="1717771208658" TEXT="trotzdem ärgerlich">
|
||||
<node CREATED="1717771319363" ID="ID_165772412" MODIFIED="1718206065687" TEXT="weil es für den Haupt-Anwendungsfall gar nicht gebraucht wird">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</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>
|
||||
</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"/>
|
||||
|
|
@ -83192,8 +83194,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716914886169" ID="ID_505410227" MODIFIED="1716914902542" TEXT="Änderung Spread">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#5b280f" CREATED="1716914886169" ID="ID_505410227" MODIFIED="1718297612308" TEXT="Änderung Spread">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1718297613563" HGAP="24" ID="ID_516072366" MODIFIED="1718297623575" TEXT="YAGNI" VSHIFT="4">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1716914892972" ID="ID_1080699305" MODIFIED="1718147544739" TEXT="Platzieren neuer Daten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -83220,9 +83225,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716936138265" ID="ID_344813639" MODIFIED="1716936143886" TEXT="Allokations-Policies">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1716936150419" ID="ID_442325434" MODIFIED="1716936174356" TEXT="HeapOwn">
|
||||
<node CREATED="1716936175678" ID="ID_1766388404" MODIFIED="1716936183114" TEXT="die C-Funktionen nutzen (wegen realloc)"/>
|
||||
<node CREATED="1716936231944" ID="ID_1000807546" LINK="https://en.cppreference.com/w/cpp/memory/c/realloc" MODIFIED="1716936247901" TEXT="Doku std::realloc()">
|
||||
<icon BUILTIN="info"/>
|
||||
<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<byte> ein"/>
|
||||
<node CREATED="1718320035606" ID="ID_267945187" MODIFIED="1718320065582" TEXT="⟹ der Deleter im ArrayBucket wird ElementFactory::delete() aufrufen">
|
||||
<node CREATED="1718320072353" ID="ID_1223722656" MODIFIED="1718320095882" TEXT="hierdurch werden der Reihe nach die Elemente an den Allokator zur Zerstörung gebracht"/>
|
||||
<node CREATED="1718320100357" ID="ID_1051852408" MODIFIED="1718320160945" TEXT="danach wird das ArrayBucket selber nicht zerstört (das passiert schon vom lib::Several aus)"/>
|
||||
<node CREATED="1718320162597" ID="ID_1683490945" MODIFIED="1718320193995" TEXT="sondern nur noch die low-level Storage für den Array-Datenpuffer freigegeben"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -83231,8 +83239,31 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#338800" CREATED="1718147568653" ID="ID_175737075" MODIFIED="1718147586344" TEXT="makeSeveral ( initializer_list )">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718147641688" ID="ID_866349389" MODIFIED="1718147693481" TEXT="makeSeveral<TY> (elms...)">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1718298480031" ID="ID_937591590" MODIFIED="1718298490716" TEXT="makeSeveral<I,E>()">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1718147641688" ID="ID_866349389" MODIFIED="1718298475923" TEXT="makeSeveral<TY> (elms...)">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node CREATED="1718298492724" ID="ID_1330684020" MODIFIED="1718298598007" TEXT="hier könne man einiges an »Intelligenz« einbauen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...im Besonderen könnte man den std::common_type verwenden, um ein mögliches Interface zu inferieren, und zudem einen gemeinsamen Element-Typ zu erkennen...
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1718298506332" ID="ID_1158180092" MODIFIED="1718298677922" TEXT="bezweifle aber derzeit, daß das förderlich ist">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...denn lib::Several ist ein ziemlich trickreicher low-level-Container; es könnte gefährlich werden, wenn man beliebige Typ-Parameter verwendet; insofern ist es nicht wünschenswert, dem User das explizite Wählen der Typ-Parameter zu ersparen (abgesehen von dem einfachen Fall mit der Initializer-list)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1718147675355" ID="ID_1373098366" MODIFIED="1718147685899" TEXT="sinnvolle Syntax für Allokator??">
|
||||
<icon BUILTIN="help"/>
|
||||
|
|
@ -83645,8 +83676,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716857382441" ID="ID_1397767362" MODIFIED="1718219037095" TEXT="check_ElementStorage">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1716857382441" ID="ID_1397767362" MODIFIED="1718298219855" TEXT="check_ElementStorage">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1718290606176" ID="ID_1457988951" MODIFIED="1718290634409" TEXT="grundsätzlich: Platzierung mit gleichmäßigem Spread">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -83666,8 +83697,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1718202490965" ID="ID_247674037" MODIFIED="1718206085439" TEXT="Handhabung von non-copyable-Objekten">
|
||||
<node COLOR="#338800" CREATED="1718202490965" ID="ID_247674037" MODIFIED="1718297858099" TEXT="Handhabung von non-copyable-Objekten">
|
||||
<linktarget COLOR="#638ad5" DESTINATION="ID_247674037" ENDARROW="Default" ENDINCLINATION="-777;-16;" ID="Arrow_ID_10606647" SOURCE="ID_1146034926" STARTARROW="None" STARTINCLINATION="-438;67;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716857382442" ID="ID_28139752" MODIFIED="1716857402101" TEXT="check_CustomAllocator">
|
||||
|
|
@ -84302,6 +84334,39 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718320662514" ID="ID_1230271493" MODIFIED="1718328703884" TEXT="dynamische re-Allokation in Grenzen ermöglichen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1718320687487" ID="ID_633607607" MODIFIED="1718320721888" TEXT="Feature speziell für die Render-Engine">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Und zwar weil sich aus der konkreten Implementierung diese Möglichkeit einfach ergibt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1718320726218" ID="ID_1869643772" MODIFIED="1718328832230" TEXT="wird im Besonderen von lib::Several über einen dedizierte Policy genutzt">
|
||||
<linktarget COLOR="#415ab7" DESTINATION="ID_1869643772" ENDARROW="Default" ENDINCLINATION="-1433;-63;" ID="Arrow_ID_166309661" SOURCE="ID_1053724868" STARTARROW="None" STARTINCLINATION="1447;92;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1718320753278" ID="ID_517105268" MODIFIED="1718320773100" TEXT="Idee: den jeweils letzten Block kann man noch »flicken«">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1718320776115" ID="ID_658099032" MODIFIED="1718320779891" TEXT="Implementierung">
|
||||
<node COLOR="#338800" CREATED="1718320780738" ID="ID_228969406" MODIFIED="1718328621566" TEXT="Möglichkeit erkennen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718320785785" ID="ID_1660113692" MODIFIED="1718328621567" TEXT="Anpassung vornehmen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718320861990" ID="ID_1106019475" MODIFIED="1718328618246" TEXT="testen...">
|
||||
<arrowlink COLOR="#7aa9ba" DESTINATION="ID_1762316214" ENDARROW="Default" ENDINCLINATION="-502;-27;" ID="Arrow_ID_1080500991" STARTARROW="None" STARTINCLINATION="-365;86;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1715725950719" FOLDED="true" ID="ID_1150594476" MODIFIED="1716848654942" TEXT="Testfälle vereinfachen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1715782655513" ID="ID_563670116" MODIFIED="1716837163217" TEXT="Basis-Testfälle anpassen">
|
||||
|
|
@ -84396,6 +84461,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718320844138" ID="ID_1762316214" MODIFIED="1718328710748" TEXT="zusätzlicher Test zur dynamischen Allokations-Anpassung">
|
||||
<linktarget COLOR="#7aa9ba" DESTINATION="ID_1762316214" ENDARROW="Default" ENDINCLINATION="-502;-27;" ID="Arrow_ID_1080500991" SOURCE="ID_1106019475" STARTARROW="None" STARTINCLINATION="-365;86;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716848462075" ID="ID_1540153344" MODIFIED="1716848472810" TEXT="Node-Factory initial zum Laufen bekommen">
|
||||
|
|
|
|||
Loading…
Reference in a new issue