File size is updated correctly according to 

> fdatasync() is similar to fsync(), but does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be correctly handled.  For example, changes to  st_atime  or  st_mtime  (respec‐
       tively,  time  of  last  access  and  time  of last modification; see inode(7)) do not require flushing because they are not necessary for a subsequent data read to be handled correctly.  On the other hand, a change to the file size
       (st_size, as made by say ftruncate(2)), would require a metadata flush.

And we don't care about modification times.
Should work alright.
: block_size(block_size_)
    {}
    
    static bool canBeWrittenInEmptyBlock(SSDCacheSimpleKey & simple_key, size_t block_size)
    {
        static constexpr size_t simple_key_size = sizeof(simple_key.key);
        return (block_header_size + simple_key_size + sizeof(simple_key.size) + simple_key.size) <= block_size;
    }
    
    static bool canBeWrittenInEmptyBlock(SSDCacheComplexKey & complex_key, size_t block_size)
    {
        StringRef & key = complex_key.key;
        size_t complex_key_size = sizeof(key.size) + key.size;
        return (block_header_size + complex_key_size + sizeof(complex_key.size) + complex_key.size) <= block_size;
    }
    
    
    inline void reset(char * new_block_data)
    {
        block_data = new_block_data;
        current_block_offset = block_header_size;
        keys_size = unalignedLoad<size_t>(new_block_data + block_header_check_sum_size);
    }
    
    inline bool enoughtPlaceToWriteKey(const SSDCacheSimpleKey & cache_key) const
    {
        return (current_block_offset + (sizeof(cache_key.key) + sizeof(cache_key.size) + cache_key.size)) <= block_size;
    }
    
    inline bool enoughtPlaceToWriteKey(const SSDCacheComplexKey & cache_key) const