mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
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:
@ -6,12 +6,11 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/File.h"
|
||||||
#include "Common/Version.h"
|
#include "Common/Version.h"
|
||||||
|
|
||||||
// On disk format:
|
// On disk format:
|
||||||
@ -54,8 +53,6 @@ public:
|
|||||||
// return number of read entries
|
// return number of read entries
|
||||||
u32 OpenAndRead(const std::string& filename, LinearDiskCacheReader<K, V>& reader)
|
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,
|
// Since we're reading/writing directly to the storage of K instances,
|
||||||
// K must be trivially copyable.
|
// K must be trivially copyable.
|
||||||
static_assert(std::is_trivially_copyable<K>::value, "K must be a trivially copyable type");
|
static_assert(std::is_trivially_copyable<K>::value, "K must be a trivially copyable type");
|
||||||
@ -65,16 +62,12 @@ public:
|
|||||||
m_num_entries = 0;
|
m_num_entries = 0;
|
||||||
|
|
||||||
// try opening for reading/writing
|
// 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);
|
const u64 file_size = m_file.GetSize();
|
||||||
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;
|
|
||||||
|
|
||||||
m_header.Init();
|
m_header.Init();
|
||||||
if (m_file.is_open() && ValidateHeader())
|
if (m_file.IsOpen() && ValidateHeader())
|
||||||
{
|
{
|
||||||
// good header, read some key/value pairs
|
// good header, read some key/value pairs
|
||||||
K key;
|
K key;
|
||||||
@ -83,11 +76,9 @@ public:
|
|||||||
u32 value_size = 0;
|
u32 value_size = 0;
|
||||||
u32 entry_number = 0;
|
u32 entry_number = 0;
|
||||||
|
|
||||||
std::fstream::pos_type last_pos = m_file.tellg();
|
while (m_file.ReadArray(&value_size, 1))
|
||||||
|
|
||||||
while (Read(&value_size))
|
|
||||||
{
|
{
|
||||||
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)
|
if (next_extent > file_size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -95,8 +86,8 @@ public:
|
|||||||
value = new V[value_size];
|
value = new V[value_size];
|
||||||
|
|
||||||
// read key/value and pass to reader
|
// read key/value and pass to reader
|
||||||
if (Read(&key) && Read(value, value_size) && Read(&entry_number) &&
|
if (m_file.ReadArray(&key, 1) && m_file.ReadArray(value, value_size) &&
|
||||||
entry_number == m_num_entries + 1)
|
m_file.ReadArray(&entry_number, 1) && entry_number == m_num_entries + 1)
|
||||||
{
|
{
|
||||||
reader.Read(key, value, value_size);
|
reader.Read(key, value, value_size);
|
||||||
}
|
}
|
||||||
@ -106,10 +97,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_num_entries++;
|
m_num_entries++;
|
||||||
last_pos = m_file.tellg();
|
|
||||||
}
|
}
|
||||||
m_file.seekp(last_pos);
|
m_file.Clear();
|
||||||
m_file.clear();
|
|
||||||
|
|
||||||
delete[] value;
|
delete[] value;
|
||||||
return m_num_entries;
|
return m_num_entries;
|
||||||
@ -118,18 +107,16 @@ public:
|
|||||||
// failed to open file for reading or bad header
|
// failed to open file for reading or bad header
|
||||||
// close and recreate file
|
// close and recreate file
|
||||||
Close();
|
Close();
|
||||||
File::OpenFStream(m_file, filename, ios_base::out | ios_base::trunc | ios_base::binary);
|
m_file.Open(filename, "wb");
|
||||||
WriteHeader();
|
WriteHeader();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sync() { m_file.flush(); }
|
void Sync() { m_file.Flush(); }
|
||||||
void Close()
|
void Close()
|
||||||
{
|
{
|
||||||
if (m_file.is_open())
|
if (m_file.IsOpen())
|
||||||
m_file.close();
|
m_file.Close();
|
||||||
// clear any error flags
|
|
||||||
m_file.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appends a key-value pair to the store.
|
// 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
|
// TODO: Should do a check that we don't already have "key"? (I think each caller does that
|
||||||
// already.)
|
// already.)
|
||||||
Write(&value_size);
|
m_file.WriteArray(&value_size, 1);
|
||||||
Write(&key);
|
m_file.WriteArray(&key, 1);
|
||||||
Write(value, value_size);
|
m_file.WriteArray(value, value_size);
|
||||||
m_num_entries++;
|
m_num_entries++;
|
||||||
Write(&m_num_entries);
|
m_file.WriteArray(&m_num_entries, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void WriteHeader() { Write(&m_header); }
|
void WriteHeader() { m_file.WriteArray(&m_header, 1); }
|
||||||
bool ValidateHeader()
|
bool ValidateHeader()
|
||||||
{
|
{
|
||||||
char file_header[sizeof(Header)];
|
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)));
|
!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
|
struct Header
|
||||||
{
|
{
|
||||||
void Init()
|
void Init()
|
||||||
@ -183,6 +158,6 @@ private:
|
|||||||
|
|
||||||
} m_header;
|
} m_header;
|
||||||
|
|
||||||
std::fstream m_file;
|
File::IOFile m_file;
|
||||||
u32 m_num_entries;
|
u32 m_num_entries;
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/CommonFuncs.h"
|
#include "Common/CommonFuncs.h"
|
||||||
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/LinearDiskCache.h"
|
#include "Common/LinearDiskCache.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Config/Config.h"
|
#include "Common/Config/Config.h"
|
||||||
#include "Common/Event.h"
|
#include "Common/Event.h"
|
||||||
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
|
Reference in New Issue
Block a user