Chain-Load: improve Node-link storage

- use a specialised class, layered on top of std::array
- use additional storage to mark filling degree
- check/fail on link owerflow directly there

We still use fixed size inline storage for the node links,
yet adding this comparatively small overhead in storage helps
getting the code simpler and adding links is now constant-complexity
This commit is contained in:
Fischlurch 2023-11-12 16:56:39 +01:00
parent 7bc2c80d3a
commit ea84935f2a
3 changed files with 88 additions and 42 deletions

View file

@ -38,6 +38,7 @@
//using lib::time::Time;
//using lib::time::FSecs;
using util::isnil;
using util::isSameObject;
//using lib::test::randStr;
//using lib::test::randTime;
@ -87,8 +88,8 @@ namespace test {
Node n0; // Default-created empty Node
CHECK (n0.hash == 0);
CHECK (n0.pred.size() == DEFAULT_FAN);
CHECK (n0.succ.size() == DEFAULT_FAN);
CHECK (n0.pred.size() == 0 );
CHECK (n0.succ.size() == 0 );
CHECK (n0.pred == Node::Tab{0});
CHECK (n0.succ == Node::Tab{0});
@ -143,6 +144,17 @@ namespace test {
CHECK (n00.hash == 17052526497278249714u);
n00.calculate(); // calculation is NOT idempotent (inherently statefull)
CHECK (n00.hash == 13151338213516862912u);
CHECK (isnil (n0.succ));
CHECK (isnil (n00.succ));
CHECK (n00.succ.empty());
CHECK (0 == n00.succ.size());
CHECK (2 == n00.pred.size());
CHECK (2 == n0.pred.size());
CHECK (2 == n1.succ.size());
CHECK (2 == n2.succ.size());
CHECK (isnil (n1.pred));
CHECK (isnil (n2.pred));
}

View file

@ -80,6 +80,7 @@ namespace test {
// using lib::time::Offset;
// using lib::meta::RebindVariadic;
// using util::isnil;
using util::unConst;
// using std::forward;
// using std::move;
using boost::hash_combine;
@ -110,7 +111,30 @@ namespace test {
struct Node
: util::MoveOnly
{
using Tab = std::array<Node*, maxFan>;
using _Arr = std::array<Node*, maxFan>;
using Iter = typename _Arr::iterator;
/** Table with connections to other Node records */
struct Tab : _Arr
{
Iter after = _Arr::begin();
Iter end() { return after; }
friend Iter end(Tab& tab) { return tab.end(); }
size_t size() const { return unConst(this)->end()-_Arr::begin(); }
bool empty() const { return 0 == size(); }
Iter
add(Node& n)
{
if (after != _Arr::end())
{
*after = &n;
return after++;
}
NOTREACHED ("excess node linkage");
}
};
size_t hash;
Tab pred;
@ -125,34 +149,16 @@ namespace test {
Node&
addPred (Node& other)
{
for (Node*& entry : pred)
if (not entry)
{
entry = &other;
for (Node*& backlink : other.succ)
if (not backlink)
{
backlink = this;
return *this;
}
}
pred.add(other);
other.succ.add(*this);
NOTREACHED ("excess node linkage");
}
Node&
addSucc (Node& other)
{
for (Node*& entry : succ)
if (not entry)
{
entry = &other;
for (Node*& backlink : other.pred)
if (not backlink)
{
backlink = this;
return *this;
}
}
pred.add(other);
other.pred.add(*this);
NOTREACHED ("excess node linkage");
}

View file

@ -95865,25 +95865,38 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699746891934" ID="ID_1003055056" MODIFIED="1699747555554" TEXT="Node">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699746898954" ID="ID_1174327209" MODIFIED="1699747552946" TEXT="Datenstruktur">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699746891934" ID="ID_1003055056" MODIFIED="1699803875494" TEXT="Node">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699746898954" ID="ID_1174327209" MODIFIED="1699803865847" TEXT="Datenstruktur">
<icon BUILTIN="pencil"/>
<node COLOR="#435e98" CREATED="1699746902068" ID="ID_1045369485" MODIFIED="1699754419615" TEXT="maxFan ist ein Template-Param">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1699746922151" ID="ID_292908322" MODIFIED="1699746934836" TEXT="verwende ein std::Array"/>
<node CREATED="1699747392222" ID="ID_85247310" MODIFIED="1699747397174" TEXT="pred / succ">
<node CREATED="1699747398919" ID="ID_458723840" MODIFIED="1699747405529" TEXT="Anzahl"/>
<node CREATED="1699747406121" ID="ID_1825332114" MODIFIED="1699747411156" TEXT="Iteration"/>
<node COLOR="#338800" CREATED="1699746922151" ID="ID_292908322" MODIFIED="1699803838767" TEXT="verwende std::Array">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1699747392222" ID="ID_85247310" MODIFIED="1699803842297" TEXT="pred / succ">
<node COLOR="#338800" CREATED="1699747398919" ID="ID_458723840" MODIFIED="1699803834171" TEXT="Anzahl">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1699747406121" ID="ID_1825332114" MODIFIED="1699803835812" TEXT="Iteration">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699747423371" ID="ID_1818811688" MODIFIED="1699747550979" TEXT="Berechnung">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1699747433986" ID="ID_1557543092" MODIFIED="1699747548608" TEXT="setzt Berechnung aller Prefecessors vorraus">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699803850765" ID="ID_1046832305" MODIFIED="1699803862199" TEXT="weitere Payload">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1699803858055" ID="ID_598864815" MODIFIED="1699803859975" TEXT="hash">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1699747423371" ID="ID_1818811688" MODIFIED="1699803681498" TEXT="Berechnung">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1699747433986" ID="ID_1557543092" MODIFIED="1699803673235" TEXT="setzt Berechnung aller Prefecessors vorraus">
<icon BUILTIN="messagebox_warning"/>
</node>
<node COLOR="#338800" CREATED="1699747511840" ID="ID_96811527" MODIFIED="1699758489537" TEXT="speichert das Ergebnis per Seiteneffekt">
<node COLOR="#338800" CREATED="1699747511840" ID="ID_96811527" MODIFIED="1699803777983" TEXT="speichert das Ergebnis per Seiteneffekt">
<linktarget COLOR="#621ebb" DESTINATION="ID_96811527" ENDARROW="Default" ENDINCLINATION="374;25;" ID="Arrow_ID_1925771236" SOURCE="ID_1681365504" STARTARROW="None" STARTINCLINATION="135;10;"/>
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699747521150" ID="ID_356376425" MODIFIED="1699747533637" TEXT="kann durch Repetitionen aufwendig gemacht werden">
@ -95892,8 +95905,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#435e98" CREATED="1699756460900" ID="ID_1877216077" MODIFIED="1699758391567" TEXT="Implementierung per boost-Hash">
<icon BUILTIN="yes"/>
<node CREATED="1699756475850" ID="ID_1420065302" MODIFIED="1699756491156" TEXT="wie &#xfc;blich: weil wesentlich einfacher zu benutzen"/>
<node CREATED="1699756491632" ID="ID_1814709620" MODIFIED="1699756499051" TEXT="und: Boost bietet bereits hash_combine"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1699758395938" ID="ID_1681365504" MODIFIED="1699758441229">
<node CREATED="1699756491632" ID="ID_1814709620" MODIFIED="1699803797157" TEXT="und: Boost bietet bereits hash_combine">
<arrowlink COLOR="#ae2a85" DESTINATION="ID_1681365504" ENDARROW="Default" ENDINCLINATION="57;1;" ID="Arrow_ID_167902510" STARTARROW="None" STARTINCLINATION="71;5;"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1699758395938" ID="ID_1681365504" MODIFIED="1699803799476">
<richcontent TYPE="NODE"><html>
<head>
@ -95905,16 +95920,29 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html>
</richcontent>
<arrowlink COLOR="#621ebb" DESTINATION="ID_96811527" ENDARROW="Default" ENDINCLINATION="374;25;" ID="Arrow_ID_1925771236" STARTARROW="None" STARTINCLINATION="135;10;"/>
<linktarget COLOR="#ae2a85" DESTINATION="ID_1681365504" ENDARROW="Default" ENDINCLINATION="57;1;" ID="Arrow_ID_167902510" SOURCE="ID_1814709620" STARTARROW="None" STARTINCLINATION="71;5;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699758530360" ID="ID_1331344948" MODIFIED="1699758538983" TEXT="Verlinkung">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1699758540245" ID="ID_1948581542" MODIFIED="1699758595139" TEXT="Zahl der Verbindungen implizit codiert">
<node COLOR="#5b280f" CREATED="1699758540245" ID="ID_1948581542" MODIFIED="1699803614293" TEXT="Zahl der Verbindungen implizit codiert">
<icon BUILTIN="help"/>
<node CREATED="1699758599662" ID="ID_475795635" MODIFIED="1699758623119" TEXT="elegant zu coden so"/>
<node CREATED="1699758626410" ID="ID_254710650" MODIFIED="1699758644732" TEXT="aber nat&#xfc;rlich quadratisch"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1699758599662" ID="ID_475795635" MODIFIED="1699803638799" TEXT="ist erst mal naheliegend (und bequem)">
<icon BUILTIN="ksmiletris"/>
</node>
<node CREATED="1699758626410" ID="ID_254710650" MODIFIED="1699803643433" TEXT="aber nat&#xfc;rlich quadratisch">
<icon BUILTIN="smiley-oh"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1699802151220" FOLDED="true" ID="ID_1133520353" MODIFIED="1699803652460" TEXT="eine spezialisierte Klasse w&#xe4;re besser">
<icon BUILTIN="yes"/>
<node CREATED="1699802174727" ID="ID_1489941015" MODIFIED="1699802178642" TEXT="baut auf std::array auf"/>
<node CREATED="1699802179159" ID="ID_1822324287" MODIFIED="1699802196552" TEXT="speichert zus&#xe4;tzlich den Endpunkt-Iterator"/>
<node CREATED="1699802484022" ID="ID_1587433523" MODIFIED="1699802495258" TEXT="ansonsten so offen wie std::array selber"/>
</node>
</node>
<node COLOR="#338800" CREATED="1699758650056" ID="ID_232473697" MODIFIED="1699758655959" TEXT="Backlinks einf&#xfc;gen">
<icon BUILTIN="button_ok"/>