From 9717ae49a479e3266aed834dc4b1f12239dd83b8 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Thu, 5 Sep 2024 18:48:07 -0400 Subject: [PATCH] Use fast random to decide when to split Blobs. --- Memory/Blob.h | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/Memory/Blob.h b/Memory/Blob.h index 5123be8..1481725 100644 --- a/Memory/Blob.h +++ b/Memory/Blob.h @@ -5,10 +5,12 @@ static_assert( __cplusplus > 2020'99 ); #include #include +#include #include #include +#include #include #include @@ -30,6 +32,9 @@ namespace Alepha::Hydrogen ::detail:: Blob_m namespace C { + const auto doubleBlobPointerOption= "ALEPHA_USE_DOUBLE_BLOB_POINTERS"; + const int storageSplitRandomBitDepth= 12; // TODO: Environment tunable? Global tunable? + const bool debug= false; const bool debugLifecycle= false or C::debug; const bool debugCtors= false or C::debugLifecycle or C::debug; @@ -77,20 +82,29 @@ namespace Alepha::Hydrogen ::detail:: Blob_m Buffer< Mutable > buffer; std::size_t viewLimit= 0; // TODO: Consider allowing for unrooted sub-buffer views? - // TODO: Take the `storage` parameter and make it not increment when this ctor is called -- only when the dice roll passes. + // Potentially rollover the internal storage, during a blob sharing operation. + void + maybeRollover() + { + if( not ::getenv( C::doubleBlobPointerOption ) ) return; + + if( Alepha::fastRandomBits( C::storageSplitRandomBitDepth ) ) return; + + // The inner pointer gets incremented. + std::shared_ptr< Blob > inner= *storage; + + // Capture the new inner into the outer. + storage= std::make_shared< std::shared_ptr< Blob > >( std::move( inner ) ); + + // Post rollover, there should only be one reference to start. + assert( storage.use_count() == 1 ); + } + + + // Takeover a portion of a shared block explicit Blob( IndirectStorage storage, Buffer< Mutable > buffer ) noexcept - : storage( Utility::evaluate <=[storage= std::move( storage )] () -> IndirectStorage - { - //if( fastRandomBits( C::storageSplitRandomBitDepth ) ) - return std::move( storage ); - //if( C::debugSplitSharing ) error() << "Observed a use count of " << storage.use_count() << " when we failed the dice roll." << std::endl; - //auto split= std::make_shared< std::shared_ptr< Blob > >( *storage ); - //if( C:: - //return split; - }), - buffer( buffer ), - viewLimit( buffer.size() ) + : storage( std::move( storage ) ), buffer( buffer ), viewLimit( buffer.size() ) {} public: @@ -242,7 +256,10 @@ namespace Alepha::Hydrogen ::detail:: Blob_m viewLimit= (*storage)->viewLimit; } + assert( storage ); + // Now we assume that there's a two-layer scheme, so we operate based upon that. + maybeRollover(); Blob rv{ storage, Buffer< Mutable >{ buffer, amount } }; buffer= buffer + amount;