Library: simplify diagnostics using a transient list
since the calculation to find the current block start has been recast as a private method, it is now possible to calculate the allocation statistics without mutating the pos pointer. To enable such usages, add a wrapper for `LinkedElements` to expose an element-pointer temporarily as a immutable `LinkedElements` list, allowing to iterate or use subscript and size information functions
This commit is contained in:
parent
08e0f52e61
commit
3edf727c23
2 changed files with 28 additions and 31 deletions
|
|
@ -163,11 +163,18 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
size_t
|
||||
determineExtentCnt() ///< @warning finalises current block
|
||||
bool
|
||||
empty() const
|
||||
{
|
||||
closeCurrentBlock();
|
||||
return view_.extents.size();
|
||||
return nullptr == view_.storage.pos;
|
||||
}
|
||||
|
||||
size_t
|
||||
determineExtentCnt() const
|
||||
{
|
||||
return empty()? 0
|
||||
: lib::asLinkedElements (getCurrentBlockStart())
|
||||
.size();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
|
@ -177,13 +184,12 @@ namespace lib {
|
|||
return STORAGE_SIZ - view_.storage.rest;
|
||||
}
|
||||
|
||||
static auto determineStorageSize (AllocationCluster const&);
|
||||
|
||||
|
||||
private:
|
||||
Extent*
|
||||
getCurrentBlockStart() const
|
||||
{
|
||||
REQUIRE (not empty());
|
||||
void* pos = static_cast<byte*>(view_.storage.pos)
|
||||
+ view_.storage.rest
|
||||
- EXTENT_SIZ;
|
||||
|
|
@ -193,7 +199,7 @@ namespace lib {
|
|||
void
|
||||
closeCurrentBlock()
|
||||
{
|
||||
if (not view_.storage.pos) return;
|
||||
if (empty()) return;
|
||||
// relocate the pos-pointer to the start of the block
|
||||
view_.storage.pos = getCurrentBlockStart();
|
||||
view_.storage.rest = 0;
|
||||
|
|
@ -281,30 +287,10 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
/** @internal diagnostics helper for unit testing.
|
||||
* Creates a shallow copy of the management data and then locates
|
||||
* the start of the current extent to determine the allocation size
|
||||
* @return a pair (extent-count, bytes-in-last-extent)
|
||||
*/
|
||||
inline auto
|
||||
AllocationCluster::StorageManager::determineStorageSize (AllocationCluster const& o)
|
||||
{
|
||||
size_t extents{0}, bytes{0};
|
||||
if (o.storage_.pos)
|
||||
{ // must manipulate pos pointer to find out count
|
||||
Storage shallowCopy{o.storage_};
|
||||
StorageManager& access = reinterpret_cast<StorageManager&> (shallowCopy);
|
||||
bytes = access.calcAllocInCurrentBlock();
|
||||
extents = access.determineExtentCnt();
|
||||
}
|
||||
return std::make_pair (extents, bytes);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
AllocationCluster::numExtents() const
|
||||
{
|
||||
return StorageManager::determineStorageSize(*this).first;
|
||||
return StorageManager::access (unConst(*this)).determineExtentCnt();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -315,9 +301,10 @@ namespace lib {
|
|||
size_t
|
||||
AllocationCluster::numBytes() const
|
||||
{
|
||||
auto [extents,bytes] = StorageManager::determineStorageSize(*this);
|
||||
return extents? bytes + (extents - 1) * STORAGE_SIZ
|
||||
: 0;
|
||||
size_t extents = numExtents();
|
||||
if (not extents) return 0;
|
||||
size_t bytes = StorageManager::access (unConst(*this)).calcAllocInCurrentBlock();
|
||||
return (extents - 1) * STORAGE_SIZ + bytes;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -471,6 +471,16 @@ namespace lib {
|
|||
};
|
||||
|
||||
|
||||
/** transiently reinterpret an element pointer as const LinkedElements,
|
||||
* allowing to count, iterate or subscript a chain of elements */
|
||||
template<class N>
|
||||
auto&
|
||||
asLinkedElements (N* const& anchor)
|
||||
{
|
||||
using Linked = LinkedElements<const N,linked_elements::NoOwnership>;
|
||||
return reinterpret_cast<Linked const&>(anchor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace lib
|
||||
|
|
|
|||
Loading…
Reference in a new issue