From ea84935f2a71fb977a8356634ca8143a916d08db Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 12 Nov 2023 16:56:39 +0100 Subject: [PATCH] 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 --- tests/vault/gear/test-chain-load-test.cpp | 16 +++++- tests/vault/gear/test-chain-load.hpp | 52 ++++++++++--------- wiki/thinkPad.ichthyo.mm | 62 ++++++++++++++++------- 3 files changed, 88 insertions(+), 42 deletions(-) diff --git a/tests/vault/gear/test-chain-load-test.cpp b/tests/vault/gear/test-chain-load-test.cpp index 086a1244d..12a05af8c 100644 --- a/tests/vault/gear/test-chain-load-test.cpp +++ b/tests/vault/gear/test-chain-load-test.cpp @@ -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)); } diff --git a/tests/vault/gear/test-chain-load.hpp b/tests/vault/gear/test-chain-load.hpp index b9dd9c770..a6836bc1e 100644 --- a/tests/vault/gear/test-chain-load.hpp +++ b/tests/vault/gear/test-chain-load.hpp @@ -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; + using _Arr = std::array; + 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"); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 53be081a8..720f24816 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -95865,25 +95865,38 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - + + + + - - - - + + + + + + + + + - - - + + + + + + + + + + - + + @@ -95892,8 +95905,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + @@ -95905,16 +95920,29 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ +
- + - - + + + + + + + + + + + + +