From 1601838037fb577e639062ea00c85a272ea5ca33 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 19 Apr 2026 15:14:31 +0200 Subject: [PATCH] BufferProvider: reduce synchronisation effort The recursive synchronisation up the parent-chain can in most cases be skipped, by relying on the fact that inconsistent data is never stored in the BufferMetadata table. If thus an entry is locally present and matches the entry from the other side, then it can be concluded that its parent must also be already in sync. --- src/vault/mem/buffer-metadata.hpp | 14 ++++++++++---- tests/vault/mem/local-buffer-stage-test.cpp | 2 +- wiki/thinkPad.ichthyo.mm | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/vault/mem/buffer-metadata.hpp b/src/vault/mem/buffer-metadata.hpp index e825a4c75..3af6d4826 100644 --- a/src/vault/mem/buffer-metadata.hpp +++ b/src/vault/mem/buffer-metadata.hpp @@ -789,8 +789,8 @@ namespace mem { if (not srcReg.isKnown (key)) return; Entry const& entry{srcReg.get(key)}; - doSynchronise (entry); - import (entry.parentKey(), srcReg); + if (doSynchronise (entry)) + import (entry.parentKey(), srcReg); } @@ -892,15 +892,17 @@ namespace mem { /** import data from another metadata entry, - * without violating sanity rules + * yet reject violating sanity rules. * @remark usually this is used to import new type-keys; * an active buffer entry can only be handled if it is new, * or implies a valid state transition. * @note if the buffer is not NULL, it must be the same address, * otherwise the keys would differ, since they are generated * with \ref Key::forEntry() + * @return `true` if new data was stored, which implies + * that synchronisation should proceed up to the parent */ - void + bool doSynchronise (Entry const& otherEntry) { Entry* entry = table_.fetch (otherEntry); @@ -917,6 +919,10 @@ namespace mem { else entry->mark(otherEntry.state()); } + else + return true; + // something to synchronise => continue up the path + return false; } }; diff --git a/tests/vault/mem/local-buffer-stage-test.cpp b/tests/vault/mem/local-buffer-stage-test.cpp index 65d780d49..170335d4b 100644 --- a/tests/vault/mem/local-buffer-stage-test.cpp +++ b/tests/vault/mem/local-buffer-stage-test.cpp @@ -160,7 +160,7 @@ namespace test { CHECK (eDD.state() == FREE); CHECK (meta2.get(eDD).state() == EMITTED); - // it is not allowed to mark de-allocated through synchronisation + // it is not allowed to mark as de-allocated through synchronisation VERIFY_ERROR (LOGIC, meta2.import (eDD, meta1) ); VERIFY_ERROR (LIFECYCLE, meta2.release(HashVal(eDD)) ); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 93e028432..8f06c621c 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -144475,6 +144475,20 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + +

+ ...damit kann man in der Regel das rekursive Traversieren der Kette vorzeitig abbrechen; das beruht auf einem »Invarianten-Argument«: Daten in der Registry sind stets konsistent, was impliziert, daß wir auch den Parent-Key bereits gespeichert haben, entweder durch reguläres Anlegen, oder durch eine vorausgegangenen Synchronisation +

+ + +
+ +