Created
November 26, 2021 23:49
-
-
Save sylveon/a0e0d356fc97e068e4ee5c430158ad03 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct FilenameHash | |
{ | |
using transparent_key_equal = FilenameEqual; | |
std::size_t operator()(std::wstring_view k) const | |
{ | |
std::size_t hash = Util::INITIAL_HASH_VALUE; | |
for (std::size_t i = 0; i < k.length(); ++i) | |
{ | |
if (Util::IsAscii(k[i])) | |
{ | |
// if the string is all ascii characters, avoid API calls | |
// this is much faster due to being branchless code | |
Util::HashCharacter(hash, Util::AsciiToUpper(k[i])); | |
} | |
else | |
{ | |
// when we encounter a non-ascii character, call an API to hash the rest and break out | |
SlowHash(hash, k.substr(i)); | |
break; | |
} | |
} | |
return hash; | |
} | |
private: | |
inline static void SlowHash(std::size_t &hash, std::wstring_view k) | |
{ | |
fmt::wmemory_buffer buf; | |
buf.resize(k.length()); | |
const int result = LCMapStringEx( | |
LOCALE_NAME_INVARIANT, LCMAP_UPPERCASE, | |
k.data(), wil::safe_cast<int>(k.length()), | |
buf.data(), wil::safe_cast<int>(buf.size()), | |
nullptr, nullptr, 0 | |
); | |
if (result) | |
{ | |
buf.resize(result); | |
for (const wchar_t &c : buf) | |
{ | |
Util::HashCharacter(hash, c); | |
} | |
} | |
else | |
{ | |
throw std::system_error(static_cast<int>(GetLastError()), std::system_category(), "Failed to hash string"); | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment