forked from Alepha/Alepha
Use fast random to decide when to split Blobs.
This commit is contained in:
@ -5,10 +5,12 @@ static_assert( __cplusplus > 2020'99 );
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Alepha/swappable.h>
|
||||
#include <Alepha/fastRandom.h>
|
||||
#include <Alepha/Exception.h>
|
||||
#include <Alepha/error.h>
|
||||
|
||||
@ -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;
|
||||
|
Reference in New Issue
Block a user