From 102c2a91cabac602432959632d1572ab54e2268f Mon Sep 17 00:00:00 2001 From: Josh Eliades Date: Tue, 29 Oct 2024 16:42:43 +1100 Subject: [PATCH 1/5] Add hashing for coordinate class --- include/mcpp/util.h | 8 ++++++++ src/util.cpp | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index e503b43..942535f 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -68,6 +68,14 @@ struct Coordinate { */ Coordinate operator-(const Coordinate& obj) const; + /** + * @brief Implements hash algorithm for Coordinate object using XOR. + * + * @param obj The Coordinate object to hash. + * @return Hash of Coordinate object. + */ + std::size_t operator()(const Coordinate& obj) const; + /** * @brief Creates a copy of the Coordinate object. * diff --git a/src/util.cpp b/src/util.cpp index f52aa55..380805a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -41,6 +41,11 @@ Coordinate Coordinate::operator-(const Coordinate& obj) const { return result; } +std::size_t Coordinate::operator()(const Coordinate& obj) const { + return std::hash()(obj.x) ^ std::hash()(obj.y) ^ + std::hash()(obj.z); +} + Coordinate Coordinate::clone() const { return Coordinate(this->x, this->y, this->z); } From f005e69c9c9e02cc77b50468155fc56945ba2662 Mon Sep 17 00:00:00 2001 From: Josh Eliades Date: Tue, 29 Oct 2024 19:14:12 +1100 Subject: [PATCH 2/5] Add hashing for coordinate class --- include/mcpp/util.h | 3 ++- src/util.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index 942535f..d425676 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -69,7 +69,8 @@ struct Coordinate { Coordinate operator-(const Coordinate& obj) const; /** - * @brief Implements hash algorithm for Coordinate object using XOR. + * @brief Implements hash algorithm for Coordinate object using XOR, bit + * shifts and prime multiplication * * @param obj The Coordinate object to hash. * @return Hash of Coordinate object. diff --git a/src/util.cpp b/src/util.cpp index 380805a..9a97ea2 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -41,9 +41,10 @@ Coordinate Coordinate::operator-(const Coordinate& obj) const { return result; } -std::size_t Coordinate::operator()(const Coordinate& obj) const { - return std::hash()(obj.x) ^ std::hash()(obj.y) ^ - std::hash()(obj.z); +std::size_t Coordinate::operator()(const mcpp::Coordinate& obj) const { + return (std::hash()(obj.x) * 31) ^ + (std::hash()(obj.y) * 37 << 1) ^ + (std::hash()(obj.z) * 41 << 2); } Coordinate Coordinate::clone() const { From 9a6135c84aae1f34065cd789776cbb277c05c0fa Mon Sep 17 00:00:00 2001 From: Josh Eliades Date: Tue, 29 Oct 2024 19:23:11 +1100 Subject: [PATCH 3/5] Fixed order of operations --- src/util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 9a97ea2..a8346d2 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -43,8 +43,8 @@ Coordinate Coordinate::operator-(const Coordinate& obj) const { std::size_t Coordinate::operator()(const mcpp::Coordinate& obj) const { return (std::hash()(obj.x) * 31) ^ - (std::hash()(obj.y) * 37 << 1) ^ - (std::hash()(obj.z) * 41 << 2); + ((std::hash()(obj.y) * 37) << 8) ^ + ((std::hash()(obj.z) * 41) << 16); } Coordinate Coordinate::clone() const { From 08a37b99dc06212bb894462084937b26859583c3 Mon Sep 17 00:00:00 2001 From: Josh Eliades Date: Wed, 4 Dec 2024 13:22:06 +1100 Subject: [PATCH 4/5] Reduced hash collisions using code from @nhatdongdang --- src/util.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index a8346d2..f516097 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -42,9 +42,14 @@ Coordinate Coordinate::operator-(const Coordinate& obj) const { } std::size_t Coordinate::operator()(const mcpp::Coordinate& obj) const { - return (std::hash()(obj.x) * 31) ^ - ((std::hash()(obj.y) * 37) << 8) ^ - ((std::hash()(obj.z) * 41) << 16); + int lower = -3e7, upper = 3e7; + size_t base = upper - lower + 1; + + // Make x,y,z non negative + size_t nx = obj.x - lower, ny = obj.y - lower, nz = obj.z - lower; + + // Use overflow instead of modding + return nx * base * base + ny * base + nz; } Coordinate Coordinate::clone() const { From 5eefa33c3a0a9c3d1b23ed0a43adcbd9435ba4ee Mon Sep 17 00:00:00 2001 From: Josh Eliades Date: Wed, 4 Dec 2024 14:13:43 +1100 Subject: [PATCH 5/5] Fixed comments for hash function --- include/mcpp/util.h | 4 ++-- src/util.cpp | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index d425676..191af2f 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -69,8 +69,8 @@ struct Coordinate { Coordinate operator-(const Coordinate& obj) const; /** - * @brief Implements hash algorithm for Coordinate object using XOR, bit - * shifts and prime multiplication + * @brief Implements hash algorithm for Coordinate object using non-negative + * mapping and weighted coordinate values. * * @param obj The Coordinate object to hash. * @return Hash of Coordinate object. diff --git a/src/util.cpp b/src/util.cpp index f516097..aa7c4e3 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -42,13 +42,16 @@ Coordinate Coordinate::operator-(const Coordinate& obj) const { } std::size_t Coordinate::operator()(const mcpp::Coordinate& obj) const { + // Minecraft coordinate bounds int lower = -3e7, upper = 3e7; size_t base = upper - lower + 1; - // Make x,y,z non negative - size_t nx = obj.x - lower, ny = obj.y - lower, nz = obj.z - lower; + // Convert coordinate attributes to non-negative values + size_t nx = obj.x - lower; + size_t ny = obj.y - lower; + size_t nz = obj.z - lower; - // Use overflow instead of modding + // Combine and weight coordinate values using the boundary range return nx * base * base + ny * base + nz; }