From be2da4fed32a1acbe32805c9a34dc9e7f698a6e1 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 23 Jan 2025 12:45:56 +0100 Subject: Core/Database: Optimize named query result field access (cherry picked from commit f5d71b2b92f334ee913baab78899f4d06fbae523) --- src/server/database/Database/QueryResult.h | 31 ++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'src/server/database/Database/QueryResult.h') 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 #include +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; +} + 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 _fieldMetadata; - std::unordered_map _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 m_fieldMetadata; - std::unordered_map m_fieldIndexByAlias; + Trinity::DB::FieldAliasToIndexMap m_fieldIndexByAlias; std::vector m_rows; uint64 m_rowCount; uint64 m_rowPosition; -- cgit v1.2.3