19 #include "fifo_buffer_base.h" 23 #if __has_include(<filesystem>) 26 #include <experimental/filesystem> 29 BEGIN_NAMESPACE_MEMORY
43 explicit FileHandler(
const std::string& filename,
bool deleteFileAfterClose =
true)
45 , deleteFileAfterClose(deleteFileAfterClose)
66 void open(
char const* mode)
68 if (strcmp(mode,
"w") == 0)
70 file.open(filename.c_str(), std::fstream::app | std::fstream::out);
72 file.open(filename.c_str(), std::fstream::binary | std::fstream::in | std::fstream::out);
74 else if (strcmp(mode,
"r") == 0)
76 file = std::fstream(filename.c_str(), std::fstream::binary | std::fstream::in);
79 throw std::invalid_argument(
"Opening disk buffer file with argument: " + std::string(mode));
82 throw std::runtime_error(
"Error opening disk buffer file");
91 if (!file || !file.is_open())
95 throw std::runtime_error(
"File closing error");
96 assert(!file.is_open());
97 if (deleteFileAfterClose)
107 const size_t MAX_RETRIES = 5;
109 auto start = std::chrono::steady_clock::now();
111 Threading::RisingDelay risingDelay{100, 1000};
117 removeResult =
remove(filename.c_str());
118 if (removeResult == 0)
122 }
while (++it < MAX_RETRIES);
124 auto end = std::chrono::steady_clock::now();
125 auto durationInMs = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
126 std::stringstream ss;
127 ss <<
"File closing error; file:" << this->filename <<
"; error code:" << removeResult <<
"; retries: " << MAX_RETRIES
128 <<
"; elapsed[ms]:" << durationInMs;
129 throw std::runtime_error(ss.str().c_str());
138 file.seekg(0, std::fstream::beg);
148 size_t write(
const T* data,
size_t count)
150 return write(data,
sizeof(T), count);
160 size_t writeAt(
const T* data,
size_t count,
size_t pos)
163 return write(data, count);
172 size_t read(T* data,
size_t count)
174 return read(data,
sizeof(T), count);
184 size_t readAt(T* data,
size_t count,
size_t pos)
187 return read(data, count);
197 file.seekg(offset *
sizeof(T));
199 throw std::runtime_error(
"Failed to change read position in file");
208 file.seekg(0, std::fstream::end);
210 throw std::runtime_error(
"Failed to determine size of a file in bytes");
211 size_t size = size_t(file.tellg());
235 std::string filename;
236 bool deleteFileAfterClose;
238 size_t write(
const void* data,
size_t size,
size_t count)
240 file.write(static_cast<const char*>(data), size * count);
242 throw std::runtime_error(
"Error writing data to file");
246 size_t read(
void* data,
size_t size,
size_t count)
248 file.read(static_cast<char*>(data), size * count);
250 throw std::runtime_error(
"Error reading data from file");
258 template <
typename T>
267 DiskBuffer(
size_t capacity,
const std::string& fileName,
bool deleteFileAfterClose =
true);
274 void reset()
override;
289 size_t write(
const T* samples,
size_t samplesCount,
size_t pos)
override;
298 size_t read(T* samples,
size_t samplesCount,
const size_t pos)
override;
316 template <
typename T>
318 : fileHandler(fileName, deleteFileAfterClose)
323 template <
typename T>
326 std::lock_guard<std::recursive_mutex> guard(this->getLock());
331 template <
typename T>
337 template <
typename T>
340 return fileHandler.writeAt(samples, samplesCount, pos);
343 template <
typename T>
344 size_t Dewesoft::Utils::Memory::DiskBuffer<T>::read(T* samples,
size_t samplesCount,
const size_t pos)
346 return fileHandler.readAt(samples, samplesCount, pos);
349 template <
typename T>
352 throw std::runtime_error(
"Not supported");
355 template <
typename T>
358 std::lock_guard<std::recursive_mutex> guard(this->getLock());
360 auto lower = this->getReadPos();
361 auto upper = this->getWritePos();
362 auto capacity = this->getCapacity();
364 return (readPos < capacity) &&
365 ((lower < upper && readPos < upper && readPos >= lower) || (upper < lower && !(readPos >= upper && readPos < lower)));
376 template <
typename T>
379 bool incrementPosition =
true,
380 size_t samplesCount = (std::numeric_limits<size_t>::max)())
394 template <
typename T>
397 bool incrementPosition =
true,
398 size_t samplesCount = (std::numeric_limits<size_t>::max)())
FileHandler< T > & getHandler()
Returns buffer (file) handler.
Definition: disk_buffer.h:332
void seekPos(size_t offset)
Repositions file pointer relative to beginning of the file.
Definition: disk_buffer.h:195
void removeFile()
Deletes the file.
Definition: disk_buffer.h:105
virtual void reset()
Function resets all positions to default value.
Definition: fifo_buffer_base.h:167
Basic source buffer interface.
Definition: buffer.h:25
The class FifoBufferBase is used to implement first-in-first-out (FIFO) buffers.
Definition: fifo_buffer_base.h:21
void rewind()
Places file pointer at start of the file.
Definition: disk_buffer.h:135
void reset()
Clears file.
Definition: disk_buffer.h:227
size_t read(T *data, size_t count)
Reads data from disk at the current file pointer position.
Definition: disk_buffer.h:172
T * getData() const override
Function returns pointer to the internal buffer.
Definition: disk_buffer.h:350
size_t getSizeInBytes()
Returns the size of the file in bytes.
Definition: disk_buffer.h:206
void open(char const *mode)
Opens file as binary in given file access mode.
Definition: disk_buffer.h:66
virtual void setCapacity(size_t aCapacity)
Function allocates memory at the heap.
Definition: fifo_buffer_base.h:145
void open()
Opens file as binary in write/update mode.
Definition: disk_buffer.h:57
bool close()
Closes the file and frees the file pointer.
Definition: disk_buffer.h:89
FileHandler(const std::string &filename, bool deleteFileAfterClose=true)
The constructor creates an instance.
Definition: disk_buffer.h:43
The class DiskBuffer implements a first-in-first-out (FIFO) data structure on physical disc...
Definition: disk_buffer.h:259
size_t writeAt(const T *data, size_t count, size_t pos)
Writes data on disk.
Definition: disk_buffer.h:160
void reset() override
Function resets all positions to default value.
Definition: disk_buffer.h:324
size_t write(const T *samples, size_t samplesCount, size_t pos) override
Writes samples into buffer.
Definition: disk_buffer.h:338
Interface to array-backed target buffers.
Definition: direct_array_buffer.h:131
size_t read(T *samples, size_t samplesCount, const size_t pos) override
Reads from buffer into samples.
RisingDelay enables quadratic increment of delay with each iteration.
Wrapper of operations on file.
Definition: disk_buffer.h:35
bool validateReadPos(size_t readPos)
Function validates whether reading position is inside buffer boundaries.
Definition: disk_buffer.h:356
size_t readAt(T *data, size_t count, size_t pos)
Reads data from disk.
Definition: disk_buffer.h:184
Basic target buffer interface.
Definition: buffer.h:63
size_t getSize()
Returns the size of the file in type T elements.
Definition: disk_buffer.h:219
size_t write(const T *data, size_t count)
Writes data on disk at the current file pointer position.
Definition: disk_buffer.h:148
size_t transferBuffer(IDirectArraySourceBuffer< T > &source, DiskBuffer< T > &target, bool incrementPosition=true, size_t samplesCount=(std::numeric_limits< size_t >::max)())
Transferring data from source buffer to disk buffer without intermediate buffer.
Definition: disk_buffer.h:377
DiskBuffer(size_t capacity, const std::string &fileName, bool deleteFileAfterClose=true)
The constructor prepares file on disk and creates an instance.
Definition: disk_buffer.h:317