Common/LinearDiskCache: Replace std::fstream with File::IOFile

File::IOFile is better suited to this type of task.
Split out from a future PR.
This commit is contained in:
JosJuice 2020-11-04 20:59:34 +01:00
parent 069840fb7e
commit 28aa04312c
3 changed files with 22 additions and 45 deletions

View File

@ -6,12 +6,11 @@
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <type_traits>
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
#include "Common/File.h"
#include "Common/Version.h"
// On disk format:
@ -54,8 +53,6 @@ public:
// return number of read entries
u32 OpenAndRead(const std::string& filename, LinearDiskCacheReader<K, V>& reader)
{
using std::ios_base;
// Since we're reading/writing directly to the storage of K instances,
// K must be trivially copyable.
static_assert(std::is_trivially_copyable<K>::value, "K must be a trivially copyable type");
@ -65,16 +62,12 @@ public:
m_num_entries = 0;
// try opening for reading/writing
File::OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary);
m_file.Open(filename, "r+b");
m_file.seekg(0, std::ios::end);
std::fstream::pos_type end_pos = m_file.tellg();
m_file.seekg(0, std::ios::beg);
std::fstream::pos_type start_pos = m_file.tellg();
std::streamoff file_size = end_pos - start_pos;
const u64 file_size = m_file.GetSize();
m_header.Init();
if (m_file.is_open() && ValidateHeader())
if (m_file.IsOpen() && ValidateHeader())
{
// good header, read some key/value pairs
K key;
@ -83,11 +76,9 @@ public:
u32 value_size = 0;
u32 entry_number = 0;
std::fstream::pos_type last_pos = m_file.tellg();
while (Read(&value_size))
while (m_file.ReadArray(&value_size, 1))
{
std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size;
const u64 next_extent = m_file.Tell() + sizeof(value_size) + value_size;
if (next_extent > file_size)
break;
@ -95,8 +86,8 @@ public:
value = new V[value_size];
// read key/value and pass to reader
if (Read(&key) && Read(value, value_size) && Read(&entry_number) &&
entry_number == m_num_entries + 1)
if (m_file.ReadArray(&key, 1) && m_file.ReadArray(value, value_size) &&
m_file.ReadArray(&entry_number, 1) && entry_number == m_num_entries + 1)
{
reader.Read(key, value, value_size);
}
@ -106,10 +97,8 @@ public:
}
m_num_entries++;
last_pos = m_file.tellg();
}
m_file.seekp(last_pos);
m_file.clear();
m_file.Clear();
delete[] value;
return m_num_entries;
@ -118,18 +107,16 @@ public:
// failed to open file for reading or bad header
// close and recreate file
Close();
File::OpenFStream(m_file, filename, ios_base::out | ios_base::trunc | ios_base::binary);
m_file.Open(filename, "wb");
WriteHeader();
return 0;
}
void Sync() { m_file.flush(); }
void Sync() { m_file.Flush(); }
void Close()
{
if (m_file.is_open())
m_file.close();
// clear any error flags
m_file.clear();
if (m_file.IsOpen())
m_file.Close();
}
// Appends a key-value pair to the store.
@ -137,35 +124,23 @@ public:
{
// TODO: Should do a check that we don't already have "key"? (I think each caller does that
// already.)
Write(&value_size);
Write(&key);
Write(value, value_size);
m_file.WriteArray(&value_size, 1);
m_file.WriteArray(&key, 1);
m_file.WriteArray(value, value_size);
m_num_entries++;
Write(&m_num_entries);
m_file.WriteArray(&m_num_entries, 1);
}
private:
void WriteHeader() { Write(&m_header); }
void WriteHeader() { m_file.WriteArray(&m_header, 1); }
bool ValidateHeader()
{
char file_header[sizeof(Header)];
return (Read(file_header, sizeof(Header)) &&
return (m_file.ReadArray(file_header, sizeof(Header)) &&
!memcmp((const char*)&m_header, file_header, sizeof(Header)));
}
template <typename D>
bool Write(const D* data, u32 count = 1)
{
return m_file.write(reinterpret_cast<const char*>(data), count * sizeof(D)).good();
}
template <typename D>
bool Read(D* data, u32 count = 1)
{
return m_file.read(reinterpret_cast<char*>(data), count * sizeof(D)).good();
}
struct Header
{
void Init()
@ -183,6 +158,6 @@ private:
} m_header;
std::fstream m_file;
File::IOFile m_file;
u32 m_num_entries;
};

View File

@ -10,6 +10,7 @@
#include "Common/Assert.h"
#include "Common/CommonFuncs.h"
#include "Common/FileUtil.h"
#include "Common/LinearDiskCache.h"
#include "Common/MsgHandler.h"

View File

@ -16,6 +16,7 @@
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/Event.h"
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Core/Config/MainSettings.h"