mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
sdbm_hash for utils
This commit is contained in:
@@ -69,3 +69,56 @@ namespace e2d
|
||||
~noncopyable() = default;
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d { namespace utils
|
||||
{
|
||||
//
|
||||
// sdbm_hash
|
||||
//
|
||||
|
||||
namespace impl
|
||||
{
|
||||
// Inspired by:
|
||||
// http://www.cse.yorku.ca/~oz/hash.html
|
||||
|
||||
template < typename Char >
|
||||
u32 sdbm_hash_impl(u32 init, const Char* str) noexcept {
|
||||
while ( Char c = *str++ ) {
|
||||
init = c + (init << 6u) + (init << 16u) - init;
|
||||
}
|
||||
return init;
|
||||
}
|
||||
|
||||
template < typename Char >
|
||||
u32 sdbm_hash_impl(u32 init, const Char* begin, const Char* const end) noexcept {
|
||||
while ( begin != end ) {
|
||||
init = (*begin++) + (init << 6u) + (init << 16u) - init;
|
||||
}
|
||||
return init;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename Char >
|
||||
u32 sdbm_hash(const Char* str) noexcept {
|
||||
E2D_ASSERT(str);
|
||||
return impl::sdbm_hash_impl(0u, str);
|
||||
}
|
||||
|
||||
template < typename Char >
|
||||
u32 sdbm_hash(const Char* begin, const Char* const end) noexcept {
|
||||
E2D_ASSERT(begin <= end);
|
||||
return impl::sdbm_hash_impl(0u, begin, end);
|
||||
}
|
||||
|
||||
template < typename Char >
|
||||
u32 sdbm_hash(u32 init, const Char* str) noexcept {
|
||||
E2D_ASSERT(str);
|
||||
return impl::sdbm_hash_impl(init, str);
|
||||
}
|
||||
|
||||
template < typename Char >
|
||||
u32 sdbm_hash(u32 init, const Char* begin, const Char* const end) noexcept {
|
||||
E2D_ASSERT(begin <= end);
|
||||
return impl::sdbm_hash_impl(init, begin, end);
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -127,12 +127,7 @@ namespace e2d
|
||||
|
||||
template < typename Char >
|
||||
u32 basic_string_hash<Char>::calculate_hash(basic_string_view<Char> str) noexcept {
|
||||
// Inspired by:
|
||||
// http://www.cse.yorku.ca/~oz/hash.html
|
||||
u32 hash = 0;
|
||||
for ( Char c : str ) {
|
||||
hash = c + (hash << 6u) + (hash << 16u) - hash;
|
||||
}
|
||||
u32 hash = utils::sdbm_hash(str.cbegin(), str.cend());
|
||||
debug_check_collisions(hash, str);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,27 @@
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "_utils.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
TEST_CASE("utils") {
|
||||
{
|
||||
REQUIRE(utils::sdbm_hash("") == 0u);
|
||||
REQUIRE(utils::sdbm_hash(1u, "") == 1u);
|
||||
|
||||
REQUIRE(utils::sdbm_hash<char>(nullptr, nullptr) == 0u);
|
||||
REQUIRE(utils::sdbm_hash<char>(1u, nullptr, nullptr) == 1u);
|
||||
|
||||
const char* str1 = "hello";
|
||||
const char* str2 = "hello";
|
||||
|
||||
REQUIRE(utils::sdbm_hash(str1) == utils::sdbm_hash(str2));
|
||||
REQUIRE(utils::sdbm_hash(42u, str1) == utils::sdbm_hash(42u, str2));
|
||||
|
||||
REQUIRE(utils::sdbm_hash(
|
||||
str1, str1 + std::strlen(str1)
|
||||
) == utils::sdbm_hash(str2));
|
||||
REQUIRE(utils::sdbm_hash(
|
||||
42u, str1, str1 + std::strlen(str1)
|
||||
) == utils::sdbm_hash(42u, str2));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user