186 #ifdef SVF_THREAD_SAFE
194 #define SVF_ASSERT(x) assert(x)
197 #define SVF_ASSERT(x)
202 #pragma mark - Exceptions
204 namespace Exceptions {
211 [[nodiscard]]
const std::string &
message()
const {
return msg; }
244 #pragma mark - typedefs
257 #pragma mark - SVF configuration
278 #pragma mark - The SVF class
307 m_time_write(std::chrono::time_point<std::chrono::system_clock>::min()),
308 m_time_read(std::chrono::time_point<std::chrono::system_clock>::min()),
318 [[nodiscard]]
bool has(
t_fpos fpos,
size_t len)
const noexcept;
320 void write(
t_fpos fpos,
const char *data,
size_t len);
333 void clear() noexcept;
348 [[nodiscard]]
size_t size_of() const noexcept;
367 [[nodiscard]]
const std::string &
id() const noexcept {
return m_id; }
399 [[nodiscard]] std::chrono::time_point<std::chrono::system_clock>
time_write() const noexcept {
406 [[nodiscard]] std::chrono::time_point<std::chrono::system_clock>
time_read() const noexcept {
413 size_t lru_punt(
size_t cache_size_upper_bound);
421 #ifdef SVF_THREAD_SAFE
467 typedef std::map<t_fpos, t_val>
t_map;
472 #ifdef SVF_THREAD_SAFE
485 void _throw_diff(
t_fpos fpos,
const char *data, t_map::const_iterator iter,
size_t index_iter)
const;
493 t_map::iterator base_block_iter);
Might be thrown during a write operation where the data differs.
ExceptionSparseVirtualFileDiff(const std::string &in_msg)
Might be thrown during a erase operation where the file position is not at the exact beginning of a b...
ExceptionSparseVirtualFileErase(const std::string &in_msg)
Exception specialisation for the SparseVirtualFile.
ExceptionSparseVirtualFile(const std::string &in_msg)
const std::string & message() const
Might be thrown during a write operation where the data differs.
ExceptionSparseVirtualFileRead(const std::string &in_msg)
Might be thrown during a write operation which fails.
ExceptionSparseVirtualFileWrite(const std::string &in_msg)
Implementation of a Sparse Virtual File.
size_t bytes_read() const noexcept
Count of total bytes read with read() operations.
SparseVirtualFile & operator=(SparseVirtualFile &&rhs)=delete
ERROR_CONDITION
Check result of internal integrity.
@ ERROR_BLOCKS_OVERLAP
Blocks overlap.
@ ERROR_ADJACENT_BLOCKS
Blocks are adjacent and have not been coalesced.
@ ERROR_BYTE_COUNT_MISMATCH
Missmatch in byte count where the count of the bytes in all the blocks does not match m_bytes_total.
@ ERROR_DUPLICATE_BLOCK
Duplicate blocks of the same length and at the same file positions.
@ ERROR_EMPTY_BLOCK
A block is empty.
@ ERROR_DUPLICATE_BLOCK_TOUCH
Two or more blocks have the same block touch value.
t_fpos _file_position_immediatly_after_end() const noexcept
Returns the file position immediately after the last block.
t_seek_reads need_many(t_seek_reads &seek_reads, size_t greedy_length=0) const noexcept
Given many [(file position, lengths), ...] what data do I need that I don't yet have?
size_t m_bytes_punted
The count of bytes that have been erased by punting.
static t_seek_reads _minimise_seek_reads(const t_seek_reads &seek_reads, size_t greedy_length) noexcept
May reduce the list of file position/lengths by coalescing them if possible up to a limit greedy_leng...
std::chrono::time_point< std::chrono::system_clock > m_time_write
Last access real-time timestamp for a write.
size_t size_of() const noexcept
size_of() gives best guess of total memory usage.
size_t m_bytes_total
Total number of bytes in this SVF.
size_t m_blocks_punted
The count of blocks that have been erased by punting.
size_t lru_punt(size_t cache_size_upper_bound)
void _write_append_new_to_old(t_fpos fpos, const char *new_data, size_t new_data_len, t_map::iterator base_block_iter)
From file position, write the new_data to the block identified by base_block_iter....
size_t blocks_punted() const noexcept
Returns the The total count of blocks that have been erased by punting.
tSparseVirtualFileConfig m_config
The SVF configuration.
t_block_touches block_touches() const noexcept
Returns a std::map of latest touch value key and file position value.
size_t num_blocks() const noexcept
Number of blocks used.
void _throw_diff(t_fpos fpos, const char *data, t_map::const_iterator iter, size_t index_iter) const
Throws a ExceptionSparseVirtualFileDiff with an explanation of the data difference.
double file_mod_time() const noexcept
The file modification time as a double representing UNIX seconds.
size_t bytes_erased() const noexcept
Returns the The total count of bytes that have been erased either directly or by punting.
const std::string & id() const noexcept
The ID of the file.
size_t num_bytes() const noexcept
Gives exact number of data bytes held.
size_t m_bytes_erased
The total count of bytes that have been erased either directly or by punting.
std::chrono::time_point< std::chrono::system_clock > time_write() const noexcept
size_t m_blocks_erased
The total count of blocks that have been erased either directly or by punting.
SparseVirtualFile(const std::string &id, double mod_time, const tSparseVirtualFileConfig &config=tSparseVirtualFileConfig())
Create a Sparse Virtual File.
size_t m_count_write
Access statistics: count of write operations.
t_block_touch block_touch() const noexcept
Return the latest value of the monotonically increasing block_touch value.
std::chrono::time_point< std::chrono::system_clock > m_time_read
Last access real-time timestamp for a read.
void write(t_fpos fpos, const char *data, size_t len)
Write the data a the given file position.
const tSparseVirtualFileConfig & config() const noexcept
The configuration.
void clear() noexcept
Executes the data deletion strategy.
t_fpos _file_position_immediatly_after_block(t_map::const_iterator iter) const noexcept
Returns the file position immediately after the particular block.
void _write_new_append_old(t_fpos fpos, const char *data, size_t len, t_map::iterator iter)
Write a new block and append existing blocks to it.
size_t bytes_punted() const noexcept
Returns the The total count of bytes that have been erased by punting.
SparseVirtualFile operator=(const SparseVirtualFile &rhs)=delete
Eliminate copying.
t_block_touches _block_touches_no_lock() const noexcept
Returns a std::map of latest touch value key and file position value.
static size_t _amount_to_read(t_seek_read iter, size_t greedy_length) noexcept
Returns the maximal length to read given a greedy length.
std::chrono::time_point< std::chrono::system_clock > time_read() const noexcept
size_t erase(t_fpos fpos)
Remove a particular block.
size_t blocks_erased() const noexcept
Returns the The total count of blocks that have been erased either directly or by punting.
size_t count_read() const noexcept
Count of read() operations.
bool has(t_fpos fpos, size_t len) const noexcept
Do I have the data at the given file position and length?
size_t block_size(t_fpos fpos) const
The length of the block at a specific file position.
size_t bytes_write() const noexcept
Count of total bytes written with write() operations.
size_t _erase_no_lock(t_fpos fpos)
Remove a particular block.
bool file_mod_time_matches(const double &file_mod_time) const noexcept
void _write_new_block(t_fpos fpos, const char *data, size_t len, t_map::const_iterator hint)
Write a brand new block into either an empty SVF or beyond the current blocks.
ERROR_CONDITION integrity() const noexcept
Internal integrity check.
size_t count_write() const noexcept
Count of write() operations.
std::mutex m_mutex
Thread mutex. This adds about 5-10% execution time compared with a single threaded version.
t_map m_svf
The actual SVF.
t_fpos last_file_position() const noexcept
The position of the last byte.
void read(t_fpos fpos, size_t len, char *p)
Read data and write to the buffer provided by the caller. This is non-const as it updates the non-con...
t_seek_reads _need_no_lock(t_fpos fpos, size_t len, size_t greedy_length=0) const noexcept
size_t m_count_read
Access statistics: count of read operations.
t_seek_reads need(t_fpos fpos, size_t len, size_t greedy_length=0) const noexcept
Create a new fragmentation list of seek/read instructions.
double m_file_mod_time
The original file modification date as UNIX time. This is used for consistency checking.
std::string m_id
The SVF ID.
SparseVirtualFile(SparseVirtualFile &&other)=delete
Prohibit moving, the mutex has no move constructor.
~SparseVirtualFile()
Destruction just clears the internal map.
t_seek_reads blocks() const noexcept
The existing blocks as a list of (file_position, size) pairs.
t_block_touch m_block_touch
A monotonically increasing integer that indicates the age of a block, smaller is older.
std::map< t_fpos, t_val > t_map
Typedef for the map of file blocks <file_position, data>.
The namespace for all svfsc code.
struct SVFS::SparseVirtualFileConfig tSparseVirtualFileConfig
Configuration for the Sparse Virtual File.
std::vector< t_seek_read > t_seek_reads
std::map< t_block_touch, t_fpos > t_block_touches
std::pair< t_fpos, size_t > t_seek_read
Typedef for the data. This allows for extra per-block fields in the future.
t_block_touch block_touch
Configuration for the Sparse Virtual File.