Core/DataStores: Devirtualize DB2Storage

This commit is contained in:
Shauren
2022-12-14 00:29:03 +01:00
parent b1805d291c
commit ba4c148a69
5 changed files with 50 additions and 94 deletions

View File

@@ -615,7 +615,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
if (!availableDb2Locales[defaultLocale])
return 0;
#define LOAD_DB2(store) LoadDB2(availableDb2Locales, loadErrors, _stores, &store, db2Path, defaultLocale, GetCppRecordSize(store))
#define LOAD_DB2(store) LoadDB2(availableDb2Locales, loadErrors, _stores, &(store), db2Path, defaultLocale, GetCppRecordSize(store))
LOAD_DB2(sAchievementStore);
LOAD_DB2(sAchievementCategoryStore);

View File

@@ -42,7 +42,7 @@ public:
static char* AddString(char const** holder, std::string const& value);
private:
std::string _storageName;
std::string const& _storageName;
DB2LoadInfo const* _loadInfo;
};

View File

@@ -23,7 +23,8 @@
#include "StringFormat.h"
DB2StorageBase::DB2StorageBase(char const* fileName, DB2LoadInfo const* loadInfo)
: _tableHash(0), _layoutHash(0), _fileName(fileName), _fieldCount(0), _loadInfo(loadInfo), _dataTable(nullptr), _dataTableEx(), _indexTableSize(0)
: _tableHash(0), _layoutHash(0), _fileName(fileName), _fieldCount(0), _loadInfo(loadInfo), _dataTable(nullptr), _dataTableEx(),
_indexTable(nullptr), _indexTableSize(0)
{
}
@@ -34,10 +35,14 @@ DB2StorageBase::~DB2StorageBase()
delete[] _dataTableEx[1];
for (char* strings : _stringPool)
delete[] strings;
delete[] _indexTable;
}
void DB2StorageBase::WriteRecordData(char const* entry, LocaleConstant locale, ByteBuffer& buffer) const
void DB2StorageBase::WriteRecord(uint32 id, LocaleConstant locale, ByteBuffer& buffer) const
{
ASSERT(id < _indexTableSize);
char const* entry = ASSERT_NOTNULL(_indexTable[id]);
if (!_loadInfo->Meta->HasIndexFieldInData())
entry += 4;
@@ -48,45 +53,40 @@ void DB2StorageBase::WriteRecordData(char const* entry, LocaleConstant locale, B
switch (_loadInfo->Meta->Fields[i].Type)
{
case FT_INT:
buffer << *(uint32*)entry;
buffer << *reinterpret_cast<uint32 const*>(entry);
entry += 4;
break;
case FT_FLOAT:
buffer << *(float*)entry;
buffer << *reinterpret_cast<float const*>(entry);
entry += 4;
break;
case FT_BYTE:
buffer << *(uint8*)entry;
buffer << *reinterpret_cast<uint8 const*>(entry);
entry += 1;
break;
case FT_SHORT:
buffer << *(uint16*)entry;
buffer << *reinterpret_cast<uint16 const*>(entry);
entry += 2;
break;
case FT_LONG:
buffer << *(uint64*)entry;
buffer << *reinterpret_cast<uint64 const*>(entry);
entry += 8;
break;
case FT_STRING:
{
buffer << (*(LocalizedString*)entry)[locale];
buffer << (*reinterpret_cast<LocalizedString const*>(entry))[locale];
entry += sizeof(LocalizedString);
break;
}
case FT_STRING_NOT_LOCALIZED:
{
buffer << *(char const**)entry;
buffer << *reinterpret_cast<char const* const*>(entry);
entry += sizeof(char const*);
break;
}
}
}
}
}
void DB2StorageBase::Load(std::string const& path, LocaleConstant locale, char**& indexTable)
void DB2StorageBase::Load(std::string const& path, LocaleConstant locale)
{
indexTable = nullptr;
DB2FileLoader db2;
DB2FileSystemSource source(path + _fileName);
// Check if load was successful, only then continue
@@ -97,19 +97,19 @@ void DB2StorageBase::Load(std::string const& path, LocaleConstant locale, char**
_layoutHash = db2.GetLayoutHash();
// load raw non-string data
_dataTable = db2.AutoProduceData(_indexTableSize, indexTable);
_dataTable = db2.AutoProduceData(_indexTableSize, _indexTable);
// load strings from db2 data
if (char* stringBlock = db2.AutoProduceStrings(indexTable, _indexTableSize, locale))
if (char* stringBlock = db2.AutoProduceStrings(_indexTable, _indexTableSize, locale))
_stringPool.push_back(stringBlock);
db2.AutoProduceRecordCopies(_indexTableSize, indexTable, _dataTable);
db2.AutoProduceRecordCopies(_indexTableSize, _indexTable, _dataTable);
}
void DB2StorageBase::LoadStringsFrom(std::string const& path, LocaleConstant locale, char** indexTable)
void DB2StorageBase::LoadStringsFrom(std::string const& path, LocaleConstant locale)
{
// DB2 must be already loaded using Load
if (!indexTable)
if (!_indexTable)
throw DB2FileLoadException(Trinity::StringFormat("%s was not loaded properly, cannot load strings", path.c_str()));
DB2FileLoader db2;
@@ -119,26 +119,26 @@ void DB2StorageBase::LoadStringsFrom(std::string const& path, LocaleConstant loc
// load strings from another locale db2 data
if (_loadInfo->GetStringFieldCount(true))
if (char* stringBlock = db2.AutoProduceStrings(indexTable, _indexTableSize, locale))
if (char* stringBlock = db2.AutoProduceStrings(_indexTable, _indexTableSize, locale))
_stringPool.push_back(stringBlock);
}
void DB2StorageBase::LoadFromDB(char**& indexTable)
void DB2StorageBase::LoadFromDB()
{
DB2DatabaseLoader loader(_fileName, _loadInfo);
_dataTableEx[0] = loader.Load(false, _indexTableSize, indexTable, _stringPool);
_dataTableEx[1] = loader.Load(true, _indexTableSize, indexTable, _stringPool);
_dataTableEx[0] = loader.Load(false, _indexTableSize, _indexTable, _stringPool);
_dataTableEx[1] = loader.Load(true, _indexTableSize, _indexTable, _stringPool);
_stringPool.shrink_to_fit();
}
void DB2StorageBase::LoadStringsFromDB(LocaleConstant locale, char** indexTable)
void DB2StorageBase::LoadStringsFromDB(LocaleConstant locale)
{
if (!_loadInfo->GetStringFieldCount(true))
return;
DB2DatabaseLoader loader(_fileName, _loadInfo);
loader.LoadStrings(false, locale, _indexTableSize, indexTable, _stringPool);
loader.LoadStrings(true, locale, _indexTableSize, indexTable, _stringPool);
loader.LoadStrings(false, locale, _indexTableSize, _indexTable, _stringPool);
loader.LoadStrings(true, locale, _indexTableSize, _indexTable, _stringPool);
_stringPool.shrink_to_fit();
}

View File

@@ -31,31 +31,30 @@ class TC_SHARED_API DB2StorageBase
{
public:
DB2StorageBase(char const* fileName, DB2LoadInfo const* loadInfo);
virtual ~DB2StorageBase();
DB2StorageBase(DB2StorageBase const&) = delete;
DB2StorageBase(DB2StorageBase&&) = delete;
DB2StorageBase& operator=(DB2StorageBase const&) = delete;
DB2StorageBase& operator=(DB2StorageBase&&) = delete;
~DB2StorageBase();
uint32 GetTableHash() const { return _tableHash; }
uint32 GetLayoutHash() const { return _layoutHash; }
virtual bool HasRecord(uint32 id) const = 0;
virtual void WriteRecord(uint32 id, LocaleConstant locale, ByteBuffer& buffer) const = 0;
virtual void EraseRecord(uint32 id) = 0;
bool HasRecord(uint32 id) const { return id < _indexTableSize && _indexTable[id] != nullptr; }
void WriteRecord(uint32 id, LocaleConstant locale, ByteBuffer& buffer) const;
void EraseRecord(uint32 id) { if (id < _indexTableSize) _indexTable[id] = nullptr; }
std::string const& GetFileName() const { return _fileName; }
uint32 GetFieldCount() const { return _fieldCount; }
DB2LoadInfo const* GetLoadInfo() const { return _loadInfo; }
uint32 GetNumRows() const { return _indexTableSize; }
virtual void Load(std::string const& path, LocaleConstant locale) = 0;
virtual void LoadStringsFrom(std::string const& path, LocaleConstant locale) = 0;
virtual void LoadFromDB() = 0;
virtual void LoadStringsFromDB(LocaleConstant locale) = 0;
void Load(std::string const& path, LocaleConstant locale);
void LoadStringsFrom(std::string const& path, LocaleConstant locale);
void LoadFromDB();
void LoadStringsFromDB(LocaleConstant locale);
protected:
void WriteRecordData(char const* entry, LocaleConstant locale, ByteBuffer& buffer) const;
void Load(std::string const& path, LocaleConstant locale, char**& indexTable);
void LoadStringsFrom(std::string const& path, LocaleConstant locale, char** indexTable);
void LoadFromDB(char**& indexTable);
void LoadStringsFromDB(LocaleConstant locale, char** indexTable);
uint32 _tableHash;
uint32 _layoutHash;
std::string _fileName;
@@ -64,68 +63,25 @@ protected:
char* _dataTable;
char* _dataTableEx[2];
std::vector<char*> _stringPool;
char** _indexTable;
uint32 _indexTableSize;
};
template<class T>
class DB2Storage : public DB2StorageBase
{
static_assert(std::is_standard_layout<T>::value, "T in DB2Storage must have standard layout.");
static_assert(std::is_standard_layout_v<T>, "T in DB2Storage must have standard layout.");
public:
using iterator = DBStorageIterator<T>;
DB2Storage(char const* fileName, DB2LoadInfo const* loadInfo) : DB2StorageBase(fileName, loadInfo)
{
_indexTable.AsChar = nullptr;
}
using DB2StorageBase::DB2StorageBase;
~DB2Storage()
{
delete[] _indexTable.AsChar;
}
bool HasRecord(uint32 id) const override { return id < _indexTableSize && _indexTable.AsT[id] != nullptr; }
void WriteRecord(uint32 id, LocaleConstant locale, ByteBuffer& buffer) const override
{
WriteRecordData(reinterpret_cast<char const*>(AssertEntry(id)), locale, buffer);
}
void EraseRecord(uint32 id) override { if (id < _indexTableSize) _indexTable.AsT[id] = nullptr; }
T const* LookupEntry(uint32 id) const { return (id >= _indexTableSize) ? nullptr : _indexTable.AsT[id]; }
T const* LookupEntry(uint32 id) const { return (id >= _indexTableSize) ? nullptr : reinterpret_cast<T const*>(_indexTable[id]); }
T const* AssertEntry(uint32 id) const { return ASSERT_NOTNULL(LookupEntry(id)); }
uint32 GetNumRows() const { return _indexTableSize; }
void Load(std::string const& path, LocaleConstant locale) override
{
return DB2StorageBase::Load(path, locale, _indexTable.AsChar);
}
void LoadStringsFrom(std::string const& path, LocaleConstant locale) override
{
return DB2StorageBase::LoadStringsFrom(path, locale, _indexTable.AsChar);
}
void LoadFromDB() override
{
DB2StorageBase::LoadFromDB(_indexTable.AsChar);
}
void LoadStringsFromDB(LocaleConstant locale) override
{
DB2StorageBase::LoadStringsFromDB(locale, _indexTable.AsChar);
}
iterator begin() { return iterator(_indexTable.AsT, _indexTableSize); }
iterator end() { return iterator(_indexTable.AsT, _indexTableSize, _indexTableSize); }
private:
union
{
T** AsT;
char** AsChar;
} _indexTable;
iterator begin() const { return iterator(reinterpret_cast<T const* const*>(_indexTable), _indexTableSize); }
iterator end() const { return iterator(reinterpret_cast<T const* const*>(_indexTable), _indexTableSize, _indexTableSize); }
friend class UnitTestDataLoader;
};

View File

@@ -32,7 +32,7 @@ public:
using reference = T&;
DBStorageIterator() : _index(nullptr), _pos(0), _end(0) { }
DBStorageIterator(T** index, uint32 size, uint32 pos = 0) : _index(index), _pos(pos), _end(size)
DBStorageIterator(T const* const* index, uint32 size, uint32 pos = 0) : _index(index), _pos(pos), _end(size)
{
if (_pos < _end)
{
@@ -67,7 +67,7 @@ public:
}
private:
T** _index;
T const* const* _index;
uint32 _pos;
uint32 _end;
};