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 <Alepha/Alepha.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <Alepha/swappable.h>
|
#include <Alepha/swappable.h>
|
||||||
|
#include <Alepha/fastRandom.h>
|
||||||
#include <Alepha/Exception.h>
|
#include <Alepha/Exception.h>
|
||||||
#include <Alepha/error.h>
|
#include <Alepha/error.h>
|
||||||
|
|
||||||
@ -30,6 +32,9 @@ namespace Alepha::Hydrogen ::detail:: Blob_m
|
|||||||
|
|
||||||
namespace C
|
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 debug= false;
|
||||||
const bool debugLifecycle= false or C::debug;
|
const bool debugLifecycle= false or C::debug;
|
||||||
const bool debugCtors= false or C::debugLifecycle 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;
|
Buffer< Mutable > buffer;
|
||||||
std::size_t viewLimit= 0; // TODO: Consider allowing for unrooted sub-buffer views?
|
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
|
explicit
|
||||||
Blob( IndirectStorage storage, Buffer< Mutable > buffer ) noexcept
|
Blob( IndirectStorage storage, Buffer< Mutable > buffer ) noexcept
|
||||||
: storage( Utility::evaluate <=[storage= std::move( storage )] () -> IndirectStorage
|
: storage( std::move( storage ) ), buffer( buffer ), viewLimit( buffer.size() )
|
||||||
{
|
|
||||||
//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() )
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -242,7 +256,10 @@ namespace Alepha::Hydrogen ::detail:: Blob_m
|
|||||||
viewLimit= (*storage)->viewLimit;
|
viewLimit= (*storage)->viewLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert( storage );
|
||||||
|
|
||||||
// Now we assume that there's a two-layer scheme, so we operate based upon that.
|
// Now we assume that there's a two-layer scheme, so we operate based upon that.
|
||||||
|
maybeRollover();
|
||||||
|
|
||||||
Blob rv{ storage, Buffer< Mutable >{ buffer, amount } };
|
Blob rv{ storage, Buffer< Mutable >{ buffer, amount } };
|
||||||
buffer= buffer + amount;
|
buffer= buffer + amount;
|
||||||
|
Reference in New Issue
Block a user