BufferProvider: draft a test setup to play through usage scenarios

The goal is to develop a heuristic when to trigger clean-up of the local pool.

For developing this heuristic, I'll use a unit-test
- represent "allocations" by dummy buffer pointers
- use a queue and a stack to push those "allocations" around
- the "global pool" is just a queue with such dummy pointers
- next step is to define some λ-primitives
- finally, a λ-DSL to allow to perform "N operations of kind X"
This commit is contained in:
Fischlurch 2026-05-25 01:28:44 +02:00
parent 37fc78b027
commit 08fef0c64c
3 changed files with 123 additions and 2 deletions

View file

@ -407,13 +407,13 @@ namespace mem {
ENSURE (this->empty()); ENSURE (this->empty());
} }
private:
void void
ingest() ingest()
{ {
inQueue_.consume_all ([this](Alloc alloc){ supplyImmediately (move(alloc)); }); inQueue_.consume_all ([this](Alloc alloc){ supplyImmediately (move(alloc)); });
} }
private:
template<class PRED> template<class PRED>
Block const* Block const*
findMatch (PRED&& predicate) const findMatch (PRED&& predicate) const

View file

@ -19,11 +19,16 @@
#include "test/run.hpp" #include "test/run.hpp"
#include "test/test-helper.hpp" #include "test/test-helper.hpp"
#include "vault/mem/local-mem-pool.hpp" #include "vault/mem/local-mem-pool.hpp"
#include "lib/iter-explorer.hpp"
#include "lib/iter-stack.hpp" #include "lib/iter-stack.hpp"
#include "lib/format-util.hpp" #include "lib/format-util.hpp"
#include "test/diagnostic-output.hpp"////////////TODO
#include <concepts>
using util::join; using util::join;
using lib::explore;
using std::invocable;
namespace vault { namespace vault {
namespace mem { namespace mem {
@ -302,6 +307,7 @@ namespace test {
/** @test heuristic trigger mechanism for pool clean-up /** @test heuristic trigger mechanism for pool clean-up
* - use a setup where the global pool is just a queue of buffer pointers
* - create abbreviated notation to play through various scenarios * - create abbreviated notation to play through various scenarios
* - watch how turnover and max-score are computed for each step * - watch how turnover and max-score are computed for each step
* - document the trigger points for heuristic clean-up. * - document the trigger points for heuristic clean-up.
@ -309,7 +315,101 @@ namespace test {
void void
verify_turnoverTrigger() verify_turnoverTrigger()
{ {
LocalMemPool pool;
lib::IterQueue<Buff*> globalPool;
lib::IterStack<Buff*> usedBuff;
size_t SIZ = SIZ10;
//------------ pretty printing of "allocations"
auto buffID = [](Buff* buff){ return size_t(buff); };
auto show = [&](auto coll){ return join (explore(coll).transform(buffID)); };
//------------ define abstracted form of the basic actions on the pool...
auto pullMem = [&]{ // retrieve one allocation from global pool
if (globalPool)
{
pool.supply (*globalPool, SIZ);
pool.ingest();
++globalPool;
}
};
auto pushMem = [&](Buff* mem, size_t)
{ // return one allocation into global pool
globalPool.feed (mem);
};
auto useMem = [&]{ // claim one allocation from local pool
auto [mem,_] = pool.retrieve (SIZ);
usedBuff.push(mem);
};
auto freeMem = [&]{ // return one used allocation into local pool
if (usedBuff)
{
pool.reSupply (*usedBuff);
++usedBuff;
}
};
auto repeat = [](uint n, invocable<> auto action)
{
for (uint i=0; i<n; ++i)
action();
};
//------------ define four building blocks for scenarios
auto reserve = [&](uint n){ pool.reserve(n, SIZ); };
auto supply = [&](uint n){ repeat(n, pullMem); };
auto claim = [&](uint n){ repeat(n, useMem ); };
auto free = [&](uint n){ repeat(n, freeMem); };
// populate the global pool with some "allocations"
globalPool.feed(MEM11)
.feed(MEM12)
.feed(MEM13)
.feed(MEM21)
.feed(MEM31)
.feed(MEM32)
.feed(MEM33);
SHOW_EXPR(show(globalPool));
SHOW_EXPR(watch(pool).size())
supply(3);
SHOW_EXPR(show(globalPool));
SHOW_EXPR(watch(pool).size())
SHOW_EXPR(watch(pool).cntFree())
reserve(2);
SHOW_EXPR(watch(pool).size())
SHOW_EXPR(watch(pool).cntFree())
SHOW_EXPR(watch(pool).cntResd())
claim(3);
SHOW_EXPR(watch(pool).size())
SHOW_EXPR(watch(pool).cntFree())
SHOW_EXPR(watch(pool).cntResd())
SHOW_EXPR(show(usedBuff));
free(3);
SHOW_EXPR(watch(pool).size())
SHOW_EXPR(watch(pool).cntFree())
SHOW_EXPR(watch(pool).cntResd())
SHOW_EXPR(show(usedBuff));
pool.yield (3, SIZ, pushMem);
SHOW_EXPR(watch(pool).size())
SHOW_EXPR(show(globalPool));
} }
}; };

View file

@ -146986,7 +146986,28 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<node CREATED="1778979230293" ID="ID_1129342480" MODIFIED="1779664866045" TEXT="meine Idee der Heuristik umsetzen"> <node CREATED="1778979230293" ID="ID_1129342480" MODIFIED="1779664866045" TEXT="meine Idee der Heuristik umsetzen">
<arrowlink COLOR="#4d5f6c" DESTINATION="ID_1141255727" ENDARROW="Default" ENDINCLINATION="-376;22;" ID="Arrow_ID_514664149" STARTARROW="None" STARTINCLINATION="-76;-210;"/> <arrowlink COLOR="#4d5f6c" DESTINATION="ID_1141255727" ENDARROW="Default" ENDINCLINATION="-376;22;" ID="Arrow_ID_514664149" STARTARROW="None" STARTINCLINATION="-76;-210;"/>
</node> </node>
<node CREATED="1778979241959" ID="ID_241540634" MODIFIED="1778979251687" TEXT="mit einzelnen Grenz-Szenarien durchspielen"/> <node CREATED="1778979241959" ID="ID_241540634" MODIFIED="1778979251687" TEXT="mit einzelnen Grenz-Szenarien durchspielen">
<node COLOR="#338800" CREATED="1779670307076" ID="ID_850518169" MODIFIED="1779677812089" TEXT="brauche daf&#xfc;r ein &#xbb;Baukastensystem&#xab; f&#xfc;r Szenarien">
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1779670329822" ID="ID_1971093649" MODIFIED="1779677820109" TEXT="Idee: eine &#x3bb;-DSL">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#435e98" CREATED="1779670579244" ID="ID_1221276556" MODIFIED="1779677834308" TEXT="Primitive">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="list"/>
<node CREATED="1779670594268" ID="ID_1451616229" MODIFIED="1779670611189" TEXT="eine kontexturell vorgegebene SIZE"/>
<node CREATED="1779677581012" ID="ID_1406506279" MODIFIED="1779677594870" TEXT="einen kontextuellen &#xbb;globalen Pool&#xab;"/>
<node CREATED="1779670699998" ID="ID_954266367" MODIFIED="1779670719943" TEXT="einen kontextuellen Stack mit belegten Allocs"/>
<node CREATED="1779670614712" ID="ID_603310345" MODIFIED="1779670676968" TEXT="reserve(N)"/>
<node CREATED="1779670677760" ID="ID_1175480047" MODIFIED="1779670681979" TEXT="supply(N)"/>
<node CREATED="1779670733857" ID="ID_1430519739" MODIFIED="1779670739180" TEXT="claim(N)"/>
<node CREATED="1779670739992" ID="ID_1222609344" MODIFIED="1779670767260" TEXT="free(N)"/>
</node>
<node COLOR="#338800" CREATED="1779677790937" ID="ID_60505507" MODIFIED="1779677803941" TEXT="einfachen Fall mit pretty-Printing durchspielen...">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node CREATED="1778979252922" ID="ID_155080806" MODIFIED="1778979264429" TEXT="Verhalten sollte deterministisch vorhersagbar sein"/> <node CREATED="1778979252922" ID="ID_155080806" MODIFIED="1778979264429" TEXT="Verhalten sollte deterministisch vorhersagbar sein"/>
</node> </node>
</node> </node>