forked from Alepha/Alepha
Slab strings via slots...
This commit is contained in:
3
Blob.h
3
Blob.h
@ -94,6 +94,9 @@ namespace Alepha::Hydrogen ::detail:: Blob_m
|
|||||||
public:
|
public:
|
||||||
~Blob() { reset(); }
|
~Blob() { reset(); }
|
||||||
|
|
||||||
|
using StorageReservation= IndirectStorage;
|
||||||
|
StorageReservation reservation() const { return storage; }
|
||||||
|
|
||||||
auto
|
auto
|
||||||
swap_lens() noexcept
|
swap_lens() noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
@ -27,17 +27,18 @@ namespace Alepha::Hydrogen::Memory ::detail:: ThreadSlab_m
|
|||||||
class exports::ThreadSlab
|
class exports::ThreadSlab
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
class Impl
|
inline static thread_local Blob slab;
|
||||||
|
using Slot= std::tuple< void *, Blob::StorageReservation >;
|
||||||
|
std::array< Slot, 16 > slots;
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
freeSlots() const
|
||||||
{
|
{
|
||||||
public:
|
std::cerr << "Slot map for " << (void *) this << std::endl;
|
||||||
std::vector< Blob > leases;
|
for( const auto &[ key, res ]:
|
||||||
|
return std::count( begin( slots ), end( slots ), Slot{ nullptr, nullptr } );
|
||||||
|
}
|
||||||
|
|
||||||
inline static thread_local Blob slab;
|
|
||||||
|
|
||||||
Impl() { leases.reserve( 8 ); }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr< Impl > pimpl;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type= T;
|
using value_type= T;
|
||||||
@ -46,72 +47,31 @@ namespace Alepha::Hydrogen::Memory ::detail:: ThreadSlab_m
|
|||||||
using propagate_on_container_swap= std::true_type;
|
using propagate_on_container_swap= std::true_type;
|
||||||
using is_always_equal= std::false_type;
|
using is_always_equal= std::false_type;
|
||||||
|
|
||||||
ThreadSlab select_on_container_copy_construction() { auto rv= ThreadSlab{}; std::cerr << "selection creation at " << (void *) &rv << std::endl; return rv; }
|
ThreadSlab select_on_container_copy_construction() { auto rv= ThreadSlab{}; }
|
||||||
|
|
||||||
ThreadSlab()
|
ThreadSlab()= default;
|
||||||
: pimpl( std::make_unique< Impl >() )
|
|
||||||
{
|
|
||||||
std::cerr << (void *) this << " owns " << (void *) pimpl.get() << " (creation)" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ThreadSlab() { std::cerr << "Retired allocator external " << (void *) this << " which held " << (void *) pimpl.get() << std::endl; }
|
|
||||||
|
|
||||||
ThreadSlab &
|
ThreadSlab &operator= ( const ThreadSlab &other )= default;
|
||||||
operator= ( ThreadSlab &&other )
|
|
||||||
{
|
|
||||||
std::cerr << "Allocator move assign from " << (void *) &other << " which owns " << (void *) other.pimpl.get()
|
|
||||||
<< " to " << (void *) this << " which owns " << (void *) pimpl.get() << std::endl;
|
|
||||||
|
|
||||||
pimpl= std::move( other.pimpl );
|
ThreadSlab( const ThreadSlab &other )= default;
|
||||||
other.pimpl.reset();
|
|
||||||
std::cerr << "After the move assign from " << (void *) &other << " it now owns " << (void *) other.pimpl.get()
|
|
||||||
<< " and I'm still " << (void *) this << " which now owns " << (void *) pimpl.get() << std::endl;
|
|
||||||
|
|
||||||
return *this;
|
ThreadSlab( ThreadSlab &&other ) : ThreadSlab( std::as_const( other ) ) {}
|
||||||
}
|
|
||||||
|
|
||||||
ThreadSlab &
|
|
||||||
operator= ( const ThreadSlab &other )
|
|
||||||
{
|
|
||||||
std::cerr << "Allocator copy assign from " << (void *) &other << " which owns " << (void *) other.pimpl.get()
|
|
||||||
<< " to " << (void *) this << " which owns " << (void *) pimpl.get() << std::endl;
|
|
||||||
|
|
||||||
pimpl= other.pimpl;
|
|
||||||
std::cerr << "After the copy assign from " << (void *) &other << " it now owns " << (void *) other.pimpl.get()
|
|
||||||
<< " and I'm still " << (void *) this << " which now owns " << (void *) pimpl.get() << std::endl;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadSlab( const ThreadSlab &other )
|
|
||||||
: pimpl( other.pimpl )
|
|
||||||
{
|
|
||||||
std::cerr << "Allocator copy construction created " << (void *) this << " (from " << (void *) &other << ") which held " << (void *) pimpl.get() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadSlab( ThreadSlab &&other )
|
|
||||||
: pimpl( std::move( other.pimpl ) )
|
|
||||||
{
|
|
||||||
std::cerr << "Allocator move construction created " << (void *) this << " (from " << (void *) &other << ") which held " << (void *) pimpl.get() << std::endl;
|
|
||||||
assert( pimpl );
|
|
||||||
std::cerr << "Allocator move construction still holds " << pimpl.get() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] T *
|
[[nodiscard]] T *
|
||||||
allocate( const std::size_t amt )
|
allocate( const std::size_t amt )
|
||||||
{
|
{
|
||||||
assert( pimpl );
|
std::cerr << "Pre allocation there are " << freeSlots() << " free slots" << std::endl;
|
||||||
std::cerr << (void *) this << " owns " << (void *) pimpl.get() << " (alloc)" << std::endl;
|
if( slab.size() < amt ) slab.reset( std::max( amt, C::slabSize ) );
|
||||||
if( pimpl->slab.size() < amt ) pimpl->slab.reset( std::max( amt, C::slabSize ) );
|
|
||||||
|
|
||||||
auto next= pimpl->slab.carveHead( amt );
|
const auto slot= std::find( begin( slots ), end( slots ), Slot{ nullptr, nullptr } );
|
||||||
|
assert( slot != end( slots ) );
|
||||||
|
|
||||||
|
auto next= slab.carveHead( amt );
|
||||||
const auto rv= &next.template as< T >();
|
const auto rv= &next.template as< T >();
|
||||||
std::cerr << "Carved off " << amt << " bytes to address " << (void *) rv << " as allocator at " << (void *) pimpl.get() << std::endl;
|
*slot= { rv, next.reservation() };
|
||||||
|
|
||||||
pimpl->leases.push_back( std::move( next ) );
|
std::cerr << "Post allocation there are " << freeSlots() << " free slots" << std::endl;
|
||||||
|
|
||||||
std::cerr << "The allocator at 0x" << (void *) pimpl.get() << " has " << pimpl->leases.size() << " leases. (alloc)" << std::endl;
|
|
||||||
assert( pimpl );
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -119,28 +79,20 @@ namespace Alepha::Hydrogen::Memory ::detail:: ThreadSlab_m
|
|||||||
void
|
void
|
||||||
deallocate( T *const p, const std::size_t /* ignored */ ) noexcept
|
deallocate( T *const p, const std::size_t /* ignored */ ) noexcept
|
||||||
{
|
{
|
||||||
assert( pimpl );
|
std::cerr << "Pre deallocation there are " << freeSlots() << " free slots" << std::endl;
|
||||||
std::cerr << (void *) this << " owns " << (void *) pimpl.get() << " (dealloc)" << std::endl;
|
const auto slot= std::find_if( begin( slots ), end( slots ),
|
||||||
std::cerr << "Deallocation attempt of " << (void *) p << " by " << (void *) pimpl.get() << " when there are " << pimpl->leases.size() << " leases left." << std::endl;
|
[p]( const auto &slot ){ const auto &[ which, _ ]= slot; return which == p; } );
|
||||||
auto found= std::find_if( begin( pimpl->leases ), end( pimpl->leases ), [p]( const auto &x ) { return x.data() == p; } );
|
assert( slot != end( slots ) );
|
||||||
if( found != end( pimpl->leases ) )
|
|
||||||
{
|
*slot= { nullptr, nullptr };
|
||||||
pimpl->leases.erase( found );
|
|
||||||
std::cerr << "The allocator at 0x" << (void *) pimpl.get() << " has " << pimpl->leases.size() << " leases. (dealloc)" << std::endl;
|
std::cerr << "Post deallocation there are " << freeSlots() << " free slots" << std::endl;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
abort(); // Panic because it wasn't found in the list!
|
|
||||||
}
|
|
||||||
assert( pimpl );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
friend constexpr bool
|
friend constexpr bool
|
||||||
operator == ( const ThreadSlab &a, const ThreadSlab &b ) noexcept
|
operator == ( const ThreadSlab &a, const ThreadSlab &b ) noexcept
|
||||||
{
|
{
|
||||||
assert( a.pimpl );
|
return a.slots == b.slots;
|
||||||
assert( b.pimpl );
|
|
||||||
return a.pimpl == b.pimpl;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,10 +22,14 @@ static auto init= Alepha::Utility::enroll <=[]
|
|||||||
std::cerr << "small hello world string." << std::endl;
|
std::cerr << "small hello world string." << std::endl;
|
||||||
|
|
||||||
String s3= s2 + ": and bob";
|
String s3= s2 + ": and bob";
|
||||||
std::cerr << "appended..." << std::endl;
|
|
||||||
s3= s3 + s3 + s2;
|
|
||||||
|
|
||||||
s2= std::move( s3 );
|
for( int i= 0; i < 10; ++i )
|
||||||
|
{
|
||||||
|
std::cerr << "appended..." << std::endl;
|
||||||
|
s3= s3 + s3 + s2;
|
||||||
|
|
||||||
|
s2= std::move( s3 );
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << s3 << std::endl;
|
std::cout << s3 << std::endl;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user