Chain-Load: investigate ways for notation of topology rules

While the Cap-Helper introduced yesterday was already a step in the
right direction, I had considerable difficulties picking the correct
parameters for the upper/lower bounds and the divisor for random generation
so as to match an intended probability profile. Since this tool shall be
used for load testing, an easier to handle notation will both help
with focusing on the main tasks and later to document the test cases.

Thus engaging (again) into the DSL building game...
This commit is contained in:
Fischlurch 2023-11-18 19:28:16 +01:00
parent 0686c534cf
commit 34f1b0da89
2 changed files with 101 additions and 85 deletions

View file

@ -47,14 +47,16 @@
// 01/21 - look for ways to detect the presence of an (possibly inherited) getID() function
// 08/22 - techniques to supply additional feature selectors to a constructor call
// 10/23 - search for ways to detect signatures of member functions and functors uniformly
// 11/23 - prototype for a builder-DSL to configure a functor to draw and map random values
/** @file try.cpp
* Investigate how to detect the signature of a _function-like member,_ irrespective
* if referring to a static function, a member function or a functor member. Turns out this
* can be achieved in a syntactically uniform way by passing either a pointer or member pointer.
* @see vault::gear::_verify_usable_as_ExecutionContext
* @see lib::meta::isFunMember
* Prototyping to find a suitable DSL to configure drawing of random numbers and mapping results.
* The underlying implementation shall be extracted from (and later used by) TestChainLoad; the
* random numbers will be derived from node hash values and must be mapped to yield parameters
* limited to a very small value range. While numerically simple, this turns out to be rather
* error-prone, hence the desire to put a DSL in front. The challenge however arises from
* the additional requirement to support various usage patters, all with minimal specs.
*/
typedef unsigned int uint;
@ -66,100 +68,81 @@ typedef unsigned int uint;
#include "lib/util.hpp"
#include "lib/meta/function.hpp"
#include <functional>
struct Stat
using std::function;
template<typename T, T max>
struct Limited
{
static long fun (double, char*) {return 42; }
static constexpr T min() { return T(0); }
static constexpr T max() { return max; }
T val;
template<typename X>
Limited (X raw)
: val(util::limited (X(min()), raw, X(max())))
{ }
};
struct Funi
template<typename T, T max>
struct Spec
{
std::function<long(double, char*)> fun;
short gun;
using Lim = Limited<T,max>;
static constexpr double CAP_EPSILON = 0.001;
double lower{0};
double upper{max};
Spec() = default;
Lim
limited (double val)
{
if (val==lower)
return Lim{0};
val -= lower;
val /= upper-lower;
val *= max;
val += CAP_EPSILON;
return Lim{val};
}
};
struct Dyna
template<typename T, T max>
struct Draw
: Spec<T,max>
, function<Limited<T,max>(size_t)>
{
long fun (double, char*) const {return 42; }
using Spc = Spec<T,max>;
using Lim = typename Spc::Lim;
using Fun = function<Lim(size_t)>;
Draw()
: Spc{}
, Fun{[](size_t){ return Spc{}.limited(0); }}
{ }
template<class FUN>
Draw(FUN fun)
: Fun{fun}
{ }
};
using lib::meta::_Fun;
/** @deprecated this is effectively the same than using decltype */
template<typename P>
struct Probe
: _Fun<P>
{
Probe(P&&){}
};
template<typename FUN, typename SIG, bool =_Fun<FUN>()>
struct has_SIGx
: std::is_same<SIG, typename _Fun<FUN>::Sig>
{
// has_SIGx() = default;
// has_SIGx(FUN, _Fun<SIG>){ }
};
template<typename FUN, typename X>
struct has_SIGx<FUN,X,false>
: std::false_type
{
// has_SIGx() = default;
// has_SIGx(FUN, _Fun<X>){ }
};
template<typename SIG, typename FUN>
constexpr inline auto
isFunMember (FUN)
{
return has_SIGx<FUN,SIG>{};
}
#define ARSERT_MEMBER_FUNCTOR(_EXPR_, _SIG_) \
static_assert (isFunMember<_SIG_>(_EXPR_), \
"Member " STRINGIFY(_EXPR_) " unsuitable, expect function signature: " STRINGIFY(_SIG_));
int
main (int, char**)
{
using F1 = decltype(Stat::fun);
using F2 = decltype(Funi::fun);
using F3 = decltype(&Dyna::fun);
using D = Draw<uint,16>;
using L = typename D::Lim;
using S = typename D::Spc;
D draw;
SHOW_EXPR(draw)
SHOW_EXPR(draw(5).val)
draw = D{[](size_t i){ return S{}.limited(i); }};
SHOW_TYPE(F1)
SHOW_TYPE(F2)
SHOW_TYPE(F3)
using F1a = decltype(&Stat::fun);
using F2a = decltype(&Funi::fun);
using F2b = decltype(&Funi::gun);
SHOW_TYPE(F1a)
SHOW_TYPE(F2a)
SHOW_TYPE(F2b)
SHOW_TYPE(_Fun<F1>::Sig)
SHOW_TYPE(_Fun<F2>::Sig)
SHOW_TYPE(_Fun<F3>::Sig)
SHOW_TYPE(_Fun<F1a>::Sig)
SHOW_TYPE(_Fun<F2a>::Sig)
SHOW_EXPR(_Fun<F2a>::value)
SHOW_EXPR(_Fun<F2b>::value)
cout << "\n--------\n";
SHOW_EXPR(bool(isFunMember<long(double,char*)>(&Stat::fun)))
SHOW_EXPR(bool(isFunMember<long(double,char*)>(&Funi::fun)))
SHOW_EXPR(bool(isFunMember<long(double,char*)>(&Funi::gun)))
SHOW_EXPR(bool(isFunMember<long(double,char*)>(&Dyna::fun)))
ARSERT_MEMBER_FUNCTOR (&Stat::fun, long(double,char*));
ARSERT_MEMBER_FUNCTOR (&Dyna::fun, long(double,char*));
SHOW_EXPR(draw(5).val)
cout << "\n.gulp.\n";
return 0;

View file

@ -96098,6 +96098,39 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700240155314" ID="ID_6655140" MODIFIED="1700243338694" TEXT="Hilfsmittel: Regel-Builder">
<linktarget COLOR="#fef7b5" DESTINATION="ID_6655140" ENDARROW="Default" ENDINCLINATION="206;-191;" ID="Arrow_ID_1782877370" SOURCE="ID_697379621" STARTARROW="None" STARTINCLINATION="-63;175;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700264860430" ID="ID_911248195" MODIFIED="1700331811934" TEXT="nochmal umst&#xfc;lpen....">
<icon BUILTIN="pencil"/>
<node CREATED="1700264870441" ID="ID_1812170860" MODIFIED="1700264912656">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Cap &#10230; Ergebnis-Typ <font face="Monospaced" color="#410ec3"><b>Draw</b></font>
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700264918159" ID="ID_334644013" MODIFIED="1700331828639" TEXT="diesen aber zugleich als Regel-Builder nutzbar machen">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700264938245" ID="ID_2732200" MODIFIED="1700331828640" TEXT="und zwar durch eine DSL die darauf als Manipulator-Funktion aufsetzt">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700264961367" ID="ID_788328130" MODIFIED="1700331818142" TEXT="Einstieg: ein Funktor-Adaptor (wie neulich f&#xfc;r microbenchmark)">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1700265008950" ID="ID_751701905" MODIFIED="1700265018898" TEXT="der Funktor liefert am Ende ein Draw"/>
<node CREATED="1700265019715" ID="ID_624547616" MODIFIED="1700265047770" TEXT="aber auf Wunsch kann man auch ein Draw in die Hand bekommen"/>
<node CREATED="1700331717687" ID="ID_503595857" MODIFIED="1700331791642" TEXT="&#x27f9; Draw mu&#xdf; eine Doppel-Natur haben: es ist sowohl das Cap, alsauch ein Funktor">
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700331799351" ID="ID_619819862" MODIFIED="1700331808784" TEXT="Baumuster untersuchen (try.cpp)...">
<icon BUILTIN="pencil"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700240183293" ID="ID_1092101612" MODIFIED="1700240190782" TEXT="Regel-Baukasten">
<icon BUILTIN="flag-yellow"/>