31 #ifndef SRC_VAULT_MEM_EXTENT_FAMILY_H_ 32 #define SRC_VAULT_MEM_EXTENT_FAMILY_H_ 52 const size_t ALLOC_SAFETY_LIMIT = 8_GiB;
57 template<
typename T,
size_t siz>
70 template<
typename T,
size_t siz>
76 static const size_t EXCESS_ALLOC{5};
85 using SIZ = std::integral_constant<size_t,siz>;
90 using _UniqueStoragePtr = std::unique_ptr<lib::UninitialisedStorage<T,siz>>;
110 auto* rawStorage = this->
get();
111 ENSURE (rawStorage !=
nullptr);
112 return static_cast<Extent&
> (rawStorage->array());
115 using Extents = std::vector<Storage>;
132 return exFam and index != exFam->after_;
138 return exFam->access (index);
144 index = exFam->incWrap (index);
148 operator== (
IdxLink const& oi)
const 150 return exFam == oi.exFam
151 and index == oi.index;
157 size_t getIndex() {
return index; }
160 expandAlloc (
size_t cnt =1)
162 size_t prevStart = exFam->start_;
164 if (index >= prevStart)
165 index += (exFam->start_-prevStart);
167 ENSURE (exFam->isValidPos (index));
179 if (exFam->matchPos (index,knownTarget))
181 size_t prevIdx = index;
184 if (exFam->matchPos (index,knownTarget))
187 while (index != prevIdx);
189 throw err::Logic {
"Unable to fix-up an iterator after Extent allocation. " 190 "Reference position obsolete or unknown to the memory manager."};
199 size_t start_,after_;
204 : extents_{initialCnt}
210 reserve (
size_t expectedMaxExtents)
212 extents_.reserve (expectedMaxExtents);
225 if (not canAccomodate (cnt))
227 size_t oldSiz = slotCnt();
228 size_t addSiz = cnt - freeSlotCnt()
231 ___sanityCheckAllocSize (addSiz);
232 extents_.resize (oldSiz + addSiz);
235 auto p = extents_.begin();
236 auto first = p + start_;
237 auto mid = p + oldSiz;
238 auto last = p + oldSiz + addSiz;
240 std::rotate (first, mid, last);
245 ENSURE (canAccomodate (cnt));
246 after_ = incWrap (after_, cnt);
253 REQUIRE (cnt <= activeSlotCnt());
254 start_ = incWrap (start_, cnt);
270 bool empty()
const {
return start_ == after_; }
278 REQUIRE (not empty());
279 size_t penultimate = incWrap (after_, slotCnt()-1);
280 return iterator{IdxLink{
this, penultimate}};
288 return after_ < start_;
294 return extents_.size();
301 REQUIRE (start_ < slotCnt());
302 REQUIRE (after_ <= slotCnt());
304 return not isWrapped()? after_ - start_
306 +(slotCnt() - start_);
312 REQUIRE (activeSlotCnt() < slotCnt());
314 return slotCnt() - activeSlotCnt();
318 canAccomodate (
size_t addCnt)
const 320 return addCnt < freeSlotCnt();
330 return (idx+inc) % slotCnt();
334 isValidPos (
size_t idx)
const 336 REQUIRE (idx < slotCnt());
337 REQUIRE (activeSlotCnt() > 0);
339 return isWrapped()? (start_ <= idx and idx < slotCnt())
341 : (start_ <= idx and idx < after_);
345 matchPos (
size_t idx,
void* address)
347 REQUIRE (idx < slotCnt());
348 return address == extents_[idx].get();
352 access (
size_t idx)
const 354 REQUIRE (isValidPos (idx));
355 return unConst(
this)->extents_[idx].access();
359 ___sanityCheckAllocSize (
size_t addCnt)
361 size_t resultSiz = slotCnt()+addCnt;
362 size_t requiredSpace = resultSiz *
sizeof(Extent);
363 if (requiredSpace > ALLOC_SAFETY_LIMIT)
364 throw err::Fatal{
"Raw allocation exceeds safety limit: " 365 +util::showSize(requiredSpace) +
" > " 366 +util::showSize(ALLOC_SAFETY_LIMIT)
367 ,err::LUMIERA_ERROR_CAPACITY};
383 template<
typename T,
size_t siz>
390 size_t first() {
return exFam_.start_; }
391 size_t last() {
return exFam_.after_; }
392 size_t size() {
return exFam_.slotCnt(); }
393 size_t active() {
return exFam_.activeSlotCnt(); }
396 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.