aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-01-23 12:45:56 +0100
committerShauren <shauren.trinity@gmail.com>2025-03-13 12:41:00 +0100
commitf5d71b2b92f334ee913baab78899f4d06fbae523 (patch)
tree83fe17973e480da444ce58a9ceebb097092c01fa /src/server
parent6de1e51a2f59deb020d7839dade76b9909cb34e4 (diff)
Core/Database: Optimize named query result field access
Diffstat (limited to 'src/server')
-rw-r--r--src/server/database/Database/QueryResult.cpp8
-rw-r--r--src/server/database/Database/QueryResult.h31
2 files changed, 31 insertions, 8 deletions
diff --git a/src/server/database/Database/QueryResult.cpp b/src/server/database/Database/QueryResult.cpp
index 3180761b81f..6edfff80b9c 100644
--- a/src/server/database/Database/QueryResult.cpp
+++ b/src/server/database/Database/QueryResult.cpp
@@ -405,7 +405,7 @@ _fields(fields)
for (uint32 i = 0; i < _fieldCount; i++)
{
InitializeDatabaseFieldMetadata(&_fieldMetadata[i], &_fields[i], i, false);
- bool success = _fieldIndexByAlias.try_emplace(_fieldMetadata[i].Alias, i).second;
+ bool success = _fieldIndexByAlias.try_emplace({ Trinity::DB::FieldLookupByAliasKey::RuntimeInit, _fieldMetadata[i].Alias }, i).second;
ASSERT(success);
_currentRow[i].SetMetadata(&_fieldMetadata[i]);
}
@@ -463,7 +463,7 @@ m_metadataResult(result)
rowSize += size;
InitializeDatabaseFieldMetadata(&m_fieldMetadata[i], &field[i], i, true);
- bool success = m_fieldIndexByAlias.try_emplace(m_fieldMetadata[i].Alias, i).second;
+ bool success = m_fieldIndexByAlias.try_emplace({ Trinity::DB::FieldLookupByAliasKey::RuntimeInit, m_fieldMetadata[i].Alias }, i).second;
ASSERT(success);
m_rBind[i].buffer_type = field[i].type;
@@ -637,7 +637,7 @@ Field const& ResultSet::operator[](std::size_t index) const
return _currentRow[index];
}
-Field const& ResultSet::operator[](std::string_view const& alias) const
+Field const& ResultSet::operator[](Trinity::DB::FieldLookupByAliasKey const& alias) const
{
auto itr = _fieldIndexByAlias.find(alias);
ASSERT(itr != _fieldIndexByAlias.end());
@@ -663,7 +663,7 @@ Field const& PreparedResultSet::operator[](std::size_t index) const
return m_rows[std::size_t(m_rowPosition) * m_fieldCount + index];
}
-Field const& PreparedResultSet::operator[](std::string_view const& alias) const
+Field const& PreparedResultSet::operator[](Trinity::DB::FieldLookupByAliasKey const& alias) const
{
ASSERT(m_rowPosition < m_rowCount);
auto itr = m_fieldIndexByAlias.find(alias);
diff --git a/src/server/database/Database/QueryResult.h b/src/server/database/Database/QueryResult.h
index 381fd9d368c..683f1eeab3c 100644
--- a/src/server/database/Database/QueryResult.h
+++ b/src/server/database/Database/QueryResult.h
@@ -20,9 +20,32 @@
#include "Define.h"
#include "DatabaseEnvFwd.h"
+#include "Hash.h"
#include <unordered_map>
#include <vector>
+namespace Trinity::DB
+{
+struct FieldLookupByAliasKey
+{
+ std::size_t HashValue; ///< Cached hash value (first field to make opeartor== return early, minimizing number of string comparisons)
+ std::string_view Alias;
+
+ // implicit constructor from string literal for users of the query result
+ consteval FieldLookupByAliasKey(char const* alias) : HashValue(HashFnv1a(alias)), Alias(alias) { }
+
+ // runtime only constructor used internally to fill alias to index mapping
+ struct RuntimeInitTag { } static inline constexpr RuntimeInit = { };
+ FieldLookupByAliasKey(RuntimeInitTag, std::string_view alias) : HashValue(HashFnv1a(alias)), Alias(std::move(alias)) { }
+
+ friend bool operator==(FieldLookupByAliasKey const& left, FieldLookupByAliasKey const& right) = default;
+
+ struct Hash { constexpr std::size_t operator()(FieldLookupByAliasKey const& k) const { return k.HashValue; } };
+};
+
+using FieldAliasToIndexMap = std::unordered_map<FieldLookupByAliasKey, std::size_t, FieldLookupByAliasKey::Hash>;
+}
+
class TC_DATABASE_API ResultSet
{
public:
@@ -35,13 +58,13 @@ class TC_DATABASE_API ResultSet
Field* Fetch() const { return _currentRow; }
Field const& operator[](std::size_t index) const;
- Field const& operator[](std::string_view const& alias) const;
+ Field const& operator[](Trinity::DB::FieldLookupByAliasKey const& alias) const;
QueryResultFieldMetadata const& GetFieldMetadata(std::size_t index) const;
protected:
std::vector<QueryResultFieldMetadata> _fieldMetadata;
- std::unordered_map<std::string_view, std::size_t> _fieldIndexByAlias;
+ Trinity::DB::FieldAliasToIndexMap _fieldIndexByAlias;
uint64 _rowCount;
Field* _currentRow;
uint32 _fieldCount;
@@ -67,13 +90,13 @@ class TC_DATABASE_API PreparedResultSet
Field* Fetch() const;
Field const& operator[](std::size_t index) const;
- Field const& operator[](std::string_view const& alias) const;
+ Field const& operator[](Trinity::DB::FieldLookupByAliasKey const& alias) const;
QueryResultFieldMetadata const& GetFieldMetadata(std::size_t index) const;
protected:
std::vector<QueryResultFieldMetadata> m_fieldMetadata;
- std::unordered_map<std::string_view, std::size_t> m_fieldIndexByAlias;
+ Trinity::DB::FieldAliasToIndexMap m_fieldIndexByAlias;
std::vector<Field> m_rows;
uint64 m_rowCount;
uint64 m_rowPosition;