20 : m_writeBufferSize(50), m_writeBufferUsed(0), m_nObjectsToWrite(0), m_free(), m_free_bySize(m_free.get<1>()),
33 : m_writeBufferSize(m_writeBufferSize), m_writeBufferUsed(0), m_nObjectsToWrite(0), m_free(),
34 m_free_bySize(m_free.get<1>()), m_fileLength(0) {
56 std::unique_lock<std::mutex> uniqueLock(
m_mutex);
64 std::lock_guard<std::mutex> lock(
m_mutex);
87 std::unique_lock<std::mutex> uniqueLock(
m_mutex);
111 std::lock_guard<std::mutex> _lock(
m_mutex);
113 std::list<ISaveable *> couldNotWrite;
114 size_t objectsNotWritten(0);
115 size_t memoryNotWritten(0);
123 for (; it != it_end; ++it) {
125 if (!
obj->isBusy()) {
126 uint64_t NumObjEvents =
obj->getTotalDataSize();
127 uint64_t fileIndexStart;
128 if (!
obj->wasSaved()) {
129 fileIndexStart = this->
allocate(NumObjEvents);
132 obj->saveAt(fileIndexStart, NumObjEvents);
134 uint64_t NumFileEvents =
obj->getFileSize();
135 if (NumObjEvents != NumFileEvents) {
141 obj->saveAt(fileIndexStart, NumObjEvents);
146 if (
obj->isDataChanged()) {
147 fileIndexStart =
obj->getFilePosition();
150 obj->saveAt(fileIndexStart, NumObjEvents);
156 obj->clearDataFromMemory();
160 obj->clearBufferState();
164 couldNotWrite.emplace_back(
obj);
169 memoryNotWritten +=
obj->setBufferPosition(--couldNotWrite.end());
206 if (size == 0 || size == std::numeric_limits<uint64_t>::max())
213 std::pair<freeSpace_t::iterator, bool> p =
m_free.insert(newBlock);
218 if (!p.second ||
m_free.size() <= 1) {
223 freeSpace_t::iterator it = p.first;
224 if (it !=
m_free.begin()) {
225 freeSpace_t::iterator it_before = it;
232 m_free.replace(it_before, block_before);
236 newBlock = block_before;
241 freeSpace_t::iterator it_after = it;
244 if (it_after !=
m_free.end()) {
248 m_free.replace(it, newBlock);
263 freeSpace_t::iterator it =
m_free.begin();
267 while (it !=
m_free.end()) {
269 freeSpace_t::iterator it_after = it;
275 m_free.replace(it, thisBlock);
295 std::unique_lock<std::mutex> uniqueLock(
m_freeMutex);
298 freeSpace_bySize_t::iterator it;
299 bool putAtFileEnd =
true;
316 uint64_t foundPos = it->getFilePosition();
317 uint64_t foundSize = it->getSize();
322 if (foundSize > newSize) {
323 this->
freeBlock(foundPos + newSize, foundSize - newSize);
353 free.reserve(
m_free.size() * 2);
354 freeSpace_bySize_t::const_iterator it =
m_free_bySize.begin();
355 freeSpace_bySize_t::const_iterator it_end =
m_free_bySize.end();
356 for (; it != it_end; ++it) {
357 free.emplace_back(it->getFilePosition());
358 free.emplace_back(it->getSize());
367 if (free.size() % 2 != 0)
368 throw std::length_error(
"Free vector size is not a factor of 2.");
370 for (
auto it = free.begin(); it != free.end(); it += 2) {
371 auto it_next = std::next(it);
373 if (*it == 0 && *it_next == 0) {
384 std::ostringstream mess;
double obj
the value of the quadratic function
std::mutex m_freeMutex
Mutex for modifying the free space list.
void freeBlock(uint64_t const pos, uint64_t const size)
This method is called by this->relocate when object that has shrunk and so has left a bit of free spa...
uint64_t relocate(uint64_t const oldPos, uint64_t const oldSize, const uint64_t newSize)
This method is called by an ISaveable object that has outgrown its space allocated on file and needs ...
std::list< ISaveable * > m_toWriteBuffer
A forward list for the buffer of "toWrite" objects.
uint64_t allocate(uint64_t const newSize)
Allocate a block of the given size in a free spot in the file, or at the end of the file if there is ...
void toWrite(ISaveable *item)
Call this method when an object is ready to be written out to disk.
uint64_t m_fileLength
Length of the file. This is where new blocks that don't fit get placed.
size_t m_writeBufferUsed
Total amount of memory in the "toWrite" buffer.
void defragFreeBlocks()
Method that defrags free blocks by combining adjacent ones together NOTE: This is not necessary to ru...
void flushCache()
Flush out all the data in the memory; and writes out everything in the to-write cache.
size_t m_nObjectsToWrite
number of objects stored in to write buffer list
void getFreeSpaceVector(std::vector< uint64_t > &free) const
Returns a vector with two entries per free block: position and size.
void objectDeleted(ISaveable *item)
Call this method when an object that might be in the cache is getting deleted.
void setFreeSpaceVector(std::vector< uint64_t > &free)
Sets the free space map.
freeSpace_bySize_t & m_free_bySize
Index into m_free, but indexed by block size.
size_t m_writeBufferSize
Do we use the write buffer? Always now.
void writeOldObjects()
Method to write out the old objects that have been stored in the "toWrite" buffer.
std::string getMemoryStr() const
std::mutex m_mutex
Mutex for modifying the the toWrite buffer.
freeSpace_t m_free
Map of the free blocks in the file.
FreeBlock: a simple class that holds the position and size of block of free space in a file.
static bool merge(FreeBlock &first, const FreeBlock &second)
Attempt to merge an adjacent block into this one.
An interface for objects that can be cached or saved to disk.
void clearBufferState()
clears the state of the object, and indicate that it is not stored in buffer any more
void setBufferSize(size_t newSize)
virtual uint64_t getFilePosition() const
size_t setBufferPosition(std::list< ISaveable * >::iterator bufPosition)
sets the iterator pointing to the location of this object in the memory buffer to write later
boost::optional< std::list< ISaveable * >::iterator > & getBufPostion()
returns the iterator pointing to the position of this object within the memory to-write buffer
uint64_t getFileSize() const
Return the number of units this block occipies on file.
size_t getBufferSize() const
return the amount of memory, this object had when it was stored in buffer last time;
virtual size_t getDataMemorySize() const =0
the data size kept in memory