40 #ifndef SRC_VAULT_MEM_EXTENT_FAMILY_H_ 41 #define SRC_VAULT_MEM_EXTENT_FAMILY_H_ 61 const size_t ALLOC_SAFETY_LIMIT = 8_GiB;
66 template<
typename T,
size_t siz>
79 template<
typename T,
size_t siz>
85 static const size_t EXCESS_ALLOC{5};
94 using SIZ = std::integral_constant<size_t,siz>;
99 using _UniqueStoragePtr = std::unique_ptr<lib::UninitialisedStorage<T,siz>>;
119 auto* rawStorage = this->
get();
120 ENSURE (rawStorage !=
nullptr);
121 return static_cast<Extent&
> (rawStorage->array());
124 using Extents = std::vector<Storage>;
141 return exFam and index != exFam->after_;
147 return exFam->access (index);
153 index = exFam->incWrap (index);
157 operator== (
IdxLink const& oi)
const 159 return exFam == oi.exFam
160 and index == oi.index;
166 size_t getIndex() {
return index; }
169 expandAlloc (
size_t cnt =1)
171 size_t prevStart = exFam->start_;
173 if (index >= prevStart)
174 index += (exFam->start_-prevStart);
176 ENSURE (exFam->isValidPos (index));
188 if (exFam->matchPos (index,knownTarget))
190 size_t prevIdx = index;
193 if (exFam->matchPos (index,knownTarget))
196 while (index != prevIdx);
198 throw err::Logic {
"Unable to fix-up an iterator after Extent allocation. " 199 "Reference position obsolete or unknown to the memory manager."};
208 size_t start_,after_;
213 : extents_{initialCnt}
219 reserve (
size_t expectedMaxExtents)
221 extents_.reserve (expectedMaxExtents);
234 if (not canAccomodate (cnt))
236 size_t oldSiz = slotCnt();
237 size_t addSiz = cnt - freeSlotCnt()
240 ___sanityCheckAllocSize (addSiz);
241 extents_.resize (oldSiz + addSiz);
244 auto p = extents_.begin();
245 auto first = p + start_;
246 auto mid = p + oldSiz;
247 auto last = p + oldSiz + addSiz;
249 std::rotate (first, mid, last);
254 ENSURE (canAccomodate (cnt));
255 after_ = incWrap (after_, cnt);
262 REQUIRE (cnt <= activeSlotCnt());
263 start_ = incWrap (start_, cnt);
279 bool empty()
const {
return start_ == after_; }
287 REQUIRE (not empty());
288 size_t penultimate = incWrap (after_, slotCnt()-1);
289 return iterator{IdxLink{
this, penultimate}};
297 return after_ < start_;
303 return extents_.size();
310 REQUIRE (start_ < slotCnt());
311 REQUIRE (after_ <= slotCnt());
313 return not isWrapped()? after_ - start_
315 +(slotCnt() - start_);
321 REQUIRE (activeSlotCnt() < slotCnt());
323 return slotCnt() - activeSlotCnt();
327 canAccomodate (
size_t addCnt)
const 329 return addCnt < freeSlotCnt();
339 return (idx+inc) % slotCnt();
343 isValidPos (
size_t idx)
const 345 REQUIRE (idx < slotCnt());
346 REQUIRE (activeSlotCnt() > 0);
348 return isWrapped()? (start_ <= idx and idx < slotCnt())
350 : (start_ <= idx and idx < after_);
354 matchPos (
size_t idx,
void* address)
356 REQUIRE (idx < slotCnt());
357 return address == extents_[idx].get();
361 access (
size_t idx)
const 363 REQUIRE (isValidPos (idx));
364 return unConst(
this)->extents_[idx].access();
368 ___sanityCheckAllocSize (
size_t addCnt)
370 size_t resultSiz = slotCnt()+addCnt;
371 size_t requiredSpace = resultSiz *
sizeof(Extent);
372 if (requiredSpace > ALLOC_SAFETY_LIMIT)
373 throw err::Fatal{
"Raw allocation exceeds safety limit: " 374 +util::showSize(requiredSpace) +
" > " 375 +util::showSize(ALLOC_SAFETY_LIMIT)
376 ,err::LUMIERA_ERROR_CAPACITY};
392 template<
typename T,
size_t siz>
399 size_t first() {
return exFam_.start_; }
400 size_t last() {
return exFam_.after_; }
401 size_t size() {
return exFam_.slotCnt(); }
402 size_t active() {
return exFam_.activeSlotCnt(); }
405 template<
typename T,
size_t siz>
logical structure of a memory Extent
iterator begin()
iterate over all the currently active Extents
void openNew(size_t cnt=1)
claim next cnt extents, possibly allocate.
Helper template(s) for creating Lumiera Forward Iterators.
Any copy and copy construction prohibited.
iterator last()
positioned to the last / latest storage extent opened
void validatePos(Extent *knownTarget)
Ensure this iterator is still in-sync with expected target position; attempt to re-establish proper s...
size_t activeSlotCnt() const
Derived specific exceptions within Lumiera's exception hierarchy.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Entry in the Extents management datastructure.
Extent & access()
access projected Extent storage type
void dropOld(size_t cnt)
discard oldest cnt extents
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Block of raw uninitialised storage with array like access.
size_t incWrap(size_t idx, size_t inc=1)
increment index, but wrap at array end.
Iteration »State Core« based on Extents index position.
A raw memory block with proper alignment and array access.
Memory manager to provide a sequence of Extents for cyclic usage.
Basic set of definitions and includes commonly used together (Vault).
Decorator-Adapter to make a »state core« iterable as Lumiera Forward Iterator.
Vault-Layer implementation namespace root.