mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/DataStores: Devirtualize DB2Storage
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user