Copilot commented on code in PR #7750:
URL: https://github.com/apache/ignite-3/pull/7750#discussion_r2918254167


##########
modules/platforms/cpp/ignite/common/detail/Murmur3Hash.h:
##########
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+//
+// Created by erixon on 2026-03-09.
+//
+
+#pragma once
+#include <cstdint>
+
+void MurmurHash3_x64_128 ( const void * key, std::size_t len,
+                           std::uint64_t seed, void * out );

Review Comment:
   `MurmurHash3_x64_128` is declared with `std::size_t`, but this header does 
not include `<cstddef>`, so `std::size_t` may be undefined depending on include 
order. Add `#include <cstddef>` (or change the signature to use an explicitly 
included type).



##########
modules/platforms/cpp/ignite/common/detail/Murmur3Hash.cpp:
##########
@@ -0,0 +1,190 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+//
+// Created by erixon on 2026-03-09.
+//
+
+#include "Murmur3Hash.h"
+
+//-----------------------------------------------------------------------------
+// MurmurHash3 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code.
+
+// Note - The x86 and x64 versions do _not_ produce the same results, as the
+// algorithms are optimized for their respective platforms. You can still
+// compile and run any of them on any platform, but your performance with the
+// non-native version will be less than optimal.
+
+
+//-----------------------------------------------------------------------------
+// Platform-specific functions and macros
+
+// Microsoft Visual Studio
+
+#if defined(_MSC_VER)
+
+#define FORCE_INLINE   __forceinline
+
+#include <stdlib.h>
+
+#define ROTL32(x,y)    _rotl(x,y)
+#define ROTL64(x,y)    _rotl64(x,y)
+
+#define BIG_CONSTANT(x) (x)
+
+// Other compilers
+
+#else  // defined(_MSC_VER)
+
+#define        FORCE_INLINE inline __attribute__((always_inline))
+
+inline uint32_t rotl32 ( uint32_t x, int8_t r )
+{
+  return (x << r) | (x >> (32 - r));
+}
+
+inline uint64_t rotl64 ( uint64_t x, int8_t r )
+{
+  return (x << r) | (x >> (64 - r));
+}
+
+#define        ROTL32(x,y)     rotl32(x,y)
+#define ROTL64(x,y)    rotl64(x,y)
+
+#define BIG_CONSTANT(x) (x##LLU)
+
+#endif // !defined(_MSC_VER)
+
+//-----------------------------------------------------------------------------
+// Block read - if your platform needs to do endian-swapping or can only
+// handle aligned reads, do the conversion here
+
+FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
+{
+  return p[i];
+}
+
+FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
+{
+  return p[i];
+}
+
+//-----------------------------------------------------------------------------
+// Finalization mix - force all bits of a hash block to avalanche
+
+FORCE_INLINE uint32_t fmix32 ( uint32_t h )
+{
+  h ^= h >> 16;
+  h *= 0x85ebca6b;
+  h ^= h >> 13;
+  h *= 0xc2b2ae35;
+  h ^= h >> 16;
+
+  return h;
+}
+
+//----------
+
+FORCE_INLINE uint64_t fmix64 ( uint64_t k )
+{
+  k ^= k >> 33;
+  k *= BIG_CONSTANT(0xff51afd7ed558ccd);
+  k ^= k >> 33;
+  k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
+  k ^= k >> 33;
+
+  return k;
+}
+
+void MurmurHash3_x64_128 ( const void * key, std::size_t len,
+                           const uint64_t seed, void * out )
+{
+  const uint8_t * data = (const uint8_t*)key;
+  const int nblocks = len / 16;
+
+  uint64_t h1 = seed;
+  uint64_t h2 = seed;
+
+  const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
+  const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
+
+  //----------
+  // body
+
+  const uint64_t * blocks = (const uint64_t *)(data);
+
+  for(int i = 0; i < nblocks; i++)
+  {
+    uint64_t k1 = getblock64(blocks,i*2+0);
+    uint64_t k2 = getblock64(blocks,i*2+1);

Review Comment:
   This MurmurHash3 implementation does unaligned 64-bit loads by casting 
`data` (a `uint8_t*`) to `const uint64_t*` and then indexing it. On 
architectures that fault on unaligned access (and per C++ aliasing/alignment 
rules), this is undefined behavior and can crash or produce incorrect hashes. 
Consider using the reference implementation’s `getblock64` that reads via 
`std::memcpy` (or otherwise guarantees alignment) and handle endianness 
explicitly.



##########
modules/platforms/cpp/ignite/common/detail/hash_utils_test.cpp:
##########
@@ -0,0 +1,451 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <ignite/common/detail/hash_utils.h>
+#include <ignite/common/detail/string_extensions.h>
+
+#include <cmath>
+
+#include <gtest/gtest.h>
+
+using namespace ignite;
+using namespace ignite::detail;
+
+class hash_utils_bool_test : public ::testing::Test {};
+
+TEST_F(hash_utils_bool_test, true_value) {
+    ASSERT_EQ(-105209210, hash(true));
+}
+
+
+TEST_F(hash_utils_bool_test, false_value) {
+    ASSERT_EQ(686815056, hash(false));
+}
+
+template<typename T>
+struct test_case {
+    T arg;
+    std::int32_t expected;
+};
+
+template<typename T>
+void PrintTo(const test_case<T>& tc, std::ostream* os) {
+    using std::to_string;
+    using ignite::detail::to_string;
+
+    *os << "arg = " << to_string(tc.arg);
+}
+
+class hash_utils_uint8_t_test: public 
::testing::TestWithParam<test_case<std::uint8_t>> {};
+
+TEST_P(hash_utils_uint8_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uint8_t_test,
+    ::testing::Values(
+        test_case<uint8_t>{0, 686815056},
+        test_case<uint8_t>{1, -105209210},
+        test_case<uint8_t>{255, -482826348},
+        test_case<uint8_t>{127, -2036967051},
+        test_case<uint8_t>{128, 49585133},
+        test_case<uint8_t>{42, 1990634712}
+    )
+);
+
+class hash_utils_int8_t_test: public 
::testing::TestWithParam<test_case<std::int8_t>> {};
+
+TEST_P(hash_utils_int8_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_int8_t_test,
+    ::testing::Values(
+        test_case<std::int8_t>{0, 686815056},
+        test_case<std::int8_t>{1, -105209210},
+        test_case<std::int8_t>{-1, -482826348},
+        test_case<std::int8_t>{127, -2036967051},
+        test_case<std::int8_t>{-128, 49585133},
+        test_case<std::int8_t>{42, 1990634712}
+    )
+);
+
+class hash_utils_uint16_t_test: public 
::testing::TestWithParam<test_case<std::uint16_t>> {};
+
+TEST_P(hash_utils_uint16_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uint16_t_test,
+    ::testing::Values(
+        test_case<std::uint16_t>{0,1076422130},
+        test_case<std::uint16_t>{1,  1765994081},
+        test_case<std::uint16_t>{std::numeric_limits<std::uint16_t>::max(), 
22229479},
+        test_case<std::uint16_t>{42,-461853154}
+    )
+);
+
+class hash_utils_int16_t_test: public 
::testing::TestWithParam<test_case<std::int16_t>> {};
+
+TEST_P(hash_utils_int16_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_int16_t_test,
+    ::testing::Values(
+        test_case<std::int16_t>{0,1076422130},
+        test_case<std::int16_t>{1, 1765994081},
+        test_case<std::int16_t>{-1, 22229479},
+        test_case<std::int16_t>{std::numeric_limits<std::int16_t>::max(), 
-1586500059},
+        test_case<std::int16_t>{std::numeric_limits<std::int16_t>::min(), 
-667322922},
+        test_case<std::int16_t>{42,-461853154}
+    )
+);
+
+class hash_utils_uint32_t_test: public 
::testing::TestWithParam<test_case<std::uint32_t>> {};
+
+TEST_P(hash_utils_uint32_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uint32_t_test,
+    ::testing::Values(
+        test_case<std::uint32_t>{0,401375585},
+        test_case<std::uint32_t>{1,  666724619},
+        test_case<std::uint32_t>{std::numeric_limits<std::uint32_t>::max(), 
2008810410},
+        test_case<std::uint32_t>{42,872512553}
+    )
+);
+
+class hash_utils_int32_t_test: public 
::testing::TestWithParam<test_case<std::int32_t>> {};
+
+TEST_P(hash_utils_int32_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_int32_t_test,
+    ::testing::Values(
+        test_case<std::int32_t>{0, 401375585},
+        test_case<std::int32_t>{1,666724619},
+        test_case<std::int32_t>{-1,2008810410},
+        test_case<std::int32_t>{std::numeric_limits<std::int32_t>::max(), 
-1452754491},
+        test_case<std::int32_t>{std::numeric_limits<std::int32_t>::min(), 
694163409},
+        test_case<std::int32_t>{42,872512553}
+    )
+);
+
+class hash_utils_uint64_t_test: public 
::testing::TestWithParam<test_case<std::uint64_t>> {};
+
+TEST_P(hash_utils_uint64_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uint64_t_test,
+    ::testing::Values(
+        test_case<std::uint64_t>{0,-460808068},
+        test_case<std::uint64_t>{1,  -79575043},
+        test_case<std::uint64_t>{std::numeric_limits<std::uint64_t>::max(), 
-1168220407},
+        test_case<std::uint64_t>{42,1065270881}
+    )
+);
+
+class hash_utils_int64_t_test: public 
::testing::TestWithParam<test_case<std::int64_t>> {};
+
+TEST_P(hash_utils_int64_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_int64_t_test,
+    ::testing::Values(
+        test_case<std::int64_t>{0, -460808068},
+        test_case<std::int64_t>{1,-79575043},
+        test_case<std::int64_t>{-1,-1168220407},
+        test_case<std::int64_t>{std::numeric_limits<std::int64_t>::max(), 
-1230994913},
+        test_case<std::int64_t>{std::numeric_limits<std::int64_t>::min(), 
-1253265447},
+        test_case<std::int64_t>{42,1065270881}
+    )
+);
+
+class hash_utils_float_test: public ::testing::TestWithParam<test_case<float>> 
{};
+
+TEST_P(hash_utils_float_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_float_test,
+    ::testing::Values(
+        test_case<float>{0.0, 401375585},
+        test_case<float>{1.0,-132467364},
+        test_case<float>{-1.0,-2101035902},
+        test_case<float>{std::numeric_limits<float>::max(), 1780074225},
+        test_case<float>{42.0F,1227011061},
+        test_case<float>{float{M_PI},-2142471555}
+    )

Review Comment:
   This test uses `M_PI`, which is not guaranteed to be provided by `<cmath>` 
(notably on MSVC unless `_USE_MATH_DEFINES` is set before including `<cmath>`). 
Prefer a portable constant (e.g., `std::acos(-1)` in C++17, or 
`std::numbers::pi` if C++20), or define `_USE_MATH_DEFINES` similarly to 
`tuple_test.cpp`.



##########
modules/platforms/cpp/ignite/common/detail/hash_utils.h:
##########
@@ -0,0 +1,112 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+//
+
+#pragma once
+#include "big_decimal.h"
+#include "ignite_date_time.h"
+#include "ignite_time.h"
+#include "ignite_timestamp.h"
+#include "uuid.h"
+
+#include "Murmur3Hash.h"
+
+#include <cstdint>
+#include <cstring>
+#include <string>
+#include <vector>
+
+namespace ignite::detail {
+
+inline std::uint64_t murmur_original( const void * key, std::size_t len, 
std::uint64_t seed) {
+    std::uint64_t res[2];
+    MurmurHash3_x64_128(key, len, seed, res);
+
+    return res[0];
+}
+
+inline std::uint64_t hash64(std::int8_t data, std::uint64_t seed) {
+
+    return murmur_original(&data, sizeof(data), seed);
+}
+
+inline std::uint64_t hash64(std::uint8_t data, std::uint64_t seed) {
+    return murmur_original(&data, sizeof(data), seed);
+}
+
+inline std::uint64_t hash64(std::int16_t data, std::uint64_t seed) {
+    return murmur_original(&data, sizeof(data), seed);
+}
+
+inline std::uint64_t hash64(std::uint16_t data, std::uint64_t seed) {
+    return murmur_original(&data, sizeof(data), seed);
+}
+
+inline std::uint64_t hash64(std::int32_t data, std::uint64_t seed) {
+    return murmur_original(&data, sizeof(data), seed);
+}
+
+inline std::uint64_t hash64(std::uint32_t data, std::uint64_t seed) {
+    return murmur_original(&data, sizeof(data), seed);
+}
+
+inline std::uint64_t hash64(std::int64_t data, std::uint64_t seed) {
+    return murmur_original(&data, sizeof(data), seed);
+}
+
+inline std::uint64_t hash64(std::uint64_t data, std::uint64_t seed) {
+    return murmur_original(&data, sizeof(data), seed);

Review Comment:
   `hash64(...)` hashes the in-memory representation of multi-byte integers 
(and floats/doubles) directly. That makes the resulting hashes 
endianness-dependent, so the same logical value will hash differently on 
big-endian vs little-endian platforms, which breaks cross-platform determinism. 
Consider serializing the value to a fixed byte order (e.g., little-endian using 
the existing bytes utilities) before passing bytes to Murmur.
   ```suggestion
       std::uint16_t u = static_cast<std::uint16_t>(data);
       std::uint8_t buf[sizeof(u)];
       for (std::size_t i = 0; i < sizeof(u); ++i) {
           buf[i] = static_cast<std::uint8_t>((u >> (8 * i)) & 0xFF);
       }
       return murmur_original(buf, sizeof(buf), seed);
   }
   
   inline std::uint64_t hash64(std::uint16_t data, std::uint64_t seed) {
       std::uint16_t u = data;
       std::uint8_t buf[sizeof(u)];
       for (std::size_t i = 0; i < sizeof(u); ++i) {
           buf[i] = static_cast<std::uint8_t>((u >> (8 * i)) & 0xFF);
       }
       return murmur_original(buf, sizeof(buf), seed);
   }
   
   inline std::uint64_t hash64(std::int32_t data, std::uint64_t seed) {
       std::uint32_t u = static_cast<std::uint32_t>(data);
       std::uint8_t buf[sizeof(u)];
       for (std::size_t i = 0; i < sizeof(u); ++i) {
           buf[i] = static_cast<std::uint8_t>((u >> (8 * i)) & 0xFF);
       }
       return murmur_original(buf, sizeof(buf), seed);
   }
   
   inline std::uint64_t hash64(std::uint32_t data, std::uint64_t seed) {
       std::uint32_t u = data;
       std::uint8_t buf[sizeof(u)];
       for (std::size_t i = 0; i < sizeof(u); ++i) {
           buf[i] = static_cast<std::uint8_t>((u >> (8 * i)) & 0xFF);
       }
       return murmur_original(buf, sizeof(buf), seed);
   }
   
   inline std::uint64_t hash64(std::int64_t data, std::uint64_t seed) {
       std::uint64_t u = static_cast<std::uint64_t>(data);
       std::uint8_t buf[sizeof(u)];
       for (std::size_t i = 0; i < sizeof(u); ++i) {
           buf[i] = static_cast<std::uint8_t>((u >> (8 * i)) & 0xFF);
       }
       return murmur_original(buf, sizeof(buf), seed);
   }
   
   inline std::uint64_t hash64(std::uint64_t data, std::uint64_t seed) {
       std::uint64_t u = data;
       std::uint8_t buf[sizeof(u)];
       for (std::size_t i = 0; i < sizeof(u); ++i) {
           buf[i] = static_cast<std::uint8_t>((u >> (8 * i)) & 0xFF);
       }
       return murmur_original(buf, sizeof(buf), seed);
   ```



##########
modules/platforms/cpp/ignite/common/detail/hash_utils_test.cpp:
##########
@@ -0,0 +1,451 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <ignite/common/detail/hash_utils.h>
+#include <ignite/common/detail/string_extensions.h>
+
+#include <cmath>
+
+#include <gtest/gtest.h>
+
+using namespace ignite;
+using namespace ignite::detail;
+
+class hash_utils_bool_test : public ::testing::Test {};
+
+TEST_F(hash_utils_bool_test, true_value) {
+    ASSERT_EQ(-105209210, hash(true));
+}
+
+
+TEST_F(hash_utils_bool_test, false_value) {
+    ASSERT_EQ(686815056, hash(false));
+}
+
+template<typename T>
+struct test_case {
+    T arg;
+    std::int32_t expected;
+};
+
+template<typename T>
+void PrintTo(const test_case<T>& tc, std::ostream* os) {
+    using std::to_string;
+    using ignite::detail::to_string;
+
+    *os << "arg = " << to_string(tc.arg);
+}
+
+class hash_utils_uint8_t_test: public 
::testing::TestWithParam<test_case<std::uint8_t>> {};
+
+TEST_P(hash_utils_uint8_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uint8_t_test,
+    ::testing::Values(
+        test_case<uint8_t>{0, 686815056},
+        test_case<uint8_t>{1, -105209210},
+        test_case<uint8_t>{255, -482826348},
+        test_case<uint8_t>{127, -2036967051},
+        test_case<uint8_t>{128, 49585133},
+        test_case<uint8_t>{42, 1990634712}
+    )
+);
+
+class hash_utils_int8_t_test: public 
::testing::TestWithParam<test_case<std::int8_t>> {};
+
+TEST_P(hash_utils_int8_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_int8_t_test,
+    ::testing::Values(
+        test_case<std::int8_t>{0, 686815056},
+        test_case<std::int8_t>{1, -105209210},
+        test_case<std::int8_t>{-1, -482826348},
+        test_case<std::int8_t>{127, -2036967051},
+        test_case<std::int8_t>{-128, 49585133},
+        test_case<std::int8_t>{42, 1990634712}
+    )
+);
+
+class hash_utils_uint16_t_test: public 
::testing::TestWithParam<test_case<std::uint16_t>> {};
+
+TEST_P(hash_utils_uint16_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uint16_t_test,
+    ::testing::Values(
+        test_case<std::uint16_t>{0,1076422130},
+        test_case<std::uint16_t>{1,  1765994081},
+        test_case<std::uint16_t>{std::numeric_limits<std::uint16_t>::max(), 
22229479},
+        test_case<std::uint16_t>{42,-461853154}
+    )
+);
+
+class hash_utils_int16_t_test: public 
::testing::TestWithParam<test_case<std::int16_t>> {};
+
+TEST_P(hash_utils_int16_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_int16_t_test,
+    ::testing::Values(
+        test_case<std::int16_t>{0,1076422130},
+        test_case<std::int16_t>{1, 1765994081},
+        test_case<std::int16_t>{-1, 22229479},
+        test_case<std::int16_t>{std::numeric_limits<std::int16_t>::max(), 
-1586500059},
+        test_case<std::int16_t>{std::numeric_limits<std::int16_t>::min(), 
-667322922},
+        test_case<std::int16_t>{42,-461853154}
+    )
+);
+
+class hash_utils_uint32_t_test: public 
::testing::TestWithParam<test_case<std::uint32_t>> {};
+
+TEST_P(hash_utils_uint32_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uint32_t_test,
+    ::testing::Values(
+        test_case<std::uint32_t>{0,401375585},
+        test_case<std::uint32_t>{1,  666724619},
+        test_case<std::uint32_t>{std::numeric_limits<std::uint32_t>::max(), 
2008810410},
+        test_case<std::uint32_t>{42,872512553}
+    )
+);
+
+class hash_utils_int32_t_test: public 
::testing::TestWithParam<test_case<std::int32_t>> {};
+
+TEST_P(hash_utils_int32_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_int32_t_test,
+    ::testing::Values(
+        test_case<std::int32_t>{0, 401375585},
+        test_case<std::int32_t>{1,666724619},
+        test_case<std::int32_t>{-1,2008810410},
+        test_case<std::int32_t>{std::numeric_limits<std::int32_t>::max(), 
-1452754491},
+        test_case<std::int32_t>{std::numeric_limits<std::int32_t>::min(), 
694163409},
+        test_case<std::int32_t>{42,872512553}
+    )
+);
+
+class hash_utils_uint64_t_test: public 
::testing::TestWithParam<test_case<std::uint64_t>> {};
+
+TEST_P(hash_utils_uint64_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uint64_t_test,
+    ::testing::Values(
+        test_case<std::uint64_t>{0,-460808068},
+        test_case<std::uint64_t>{1,  -79575043},
+        test_case<std::uint64_t>{std::numeric_limits<std::uint64_t>::max(), 
-1168220407},
+        test_case<std::uint64_t>{42,1065270881}
+    )
+);
+
+class hash_utils_int64_t_test: public 
::testing::TestWithParam<test_case<std::int64_t>> {};
+
+TEST_P(hash_utils_int64_t_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_int64_t_test,
+    ::testing::Values(
+        test_case<std::int64_t>{0, -460808068},
+        test_case<std::int64_t>{1,-79575043},
+        test_case<std::int64_t>{-1,-1168220407},
+        test_case<std::int64_t>{std::numeric_limits<std::int64_t>::max(), 
-1230994913},
+        test_case<std::int64_t>{std::numeric_limits<std::int64_t>::min(), 
-1253265447},
+        test_case<std::int64_t>{42,1065270881}
+    )
+);
+
+class hash_utils_float_test: public ::testing::TestWithParam<test_case<float>> 
{};
+
+TEST_P(hash_utils_float_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_float_test,
+    ::testing::Values(
+        test_case<float>{0.0, 401375585},
+        test_case<float>{1.0,-132467364},
+        test_case<float>{-1.0,-2101035902},
+        test_case<float>{std::numeric_limits<float>::max(), 1780074225},
+        test_case<float>{42.0F,1227011061},
+        test_case<float>{float{M_PI},-2142471555}
+    )
+);
+
+class hash_utils_double_test: public 
::testing::TestWithParam<test_case<double>> {};
+
+TEST_P(hash_utils_double_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_double_test,
+    ::testing::Values(
+        test_case<double>{0.0, -460808068},
+        test_case<double>{1.0,-2124529649},
+        test_case<double>{-1.0,210701226},
+        test_case<double>{std::numeric_limits<double>::max(), -1921889547},
+        test_case<double>{42.0F,2109601987},
+        test_case<double>{double{M_PI},-521675661}
+    )
+);
+
+class hash_utils_big_decimal_test: public 
::testing::TestWithParam<test_case<big_decimal>> {};
+
+TEST_P(hash_utils_big_decimal_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg, 10));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_big_decimal_test,
+    ::testing::Values(
+        test_case<big_decimal>{big_decimal{0}, 686815056},
+        test_case<big_decimal>{big_decimal{1},904832652},
+        test_case<big_decimal>{big_decimal{-1},-1497790521},
+        test_case<big_decimal>{big_decimal{42},1347451647},
+        test_case<big_decimal>{big_decimal::from_double(M_PI),572053262},
+        test_case<big_decimal>{big_decimal::from_double(M_PI*-1),-2078930604}
+    )
+);
+
+class hash_utils_uuid_test: public ::testing::TestWithParam<test_case<uuid>> 
{};
+
+TEST_P(hash_utils_uuid_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_uuid_test,
+    ::testing::Values(
+        test_case<uuid>{uuid{0,0}, -177475040},
+        test_case<uuid>{uuid{420000042, 420042}, -2034825191}
+    )
+);
+
+class hash_utils_date_test: public 
::testing::TestWithParam<test_case<ignite_date>> {};
+
+TEST_P(hash_utils_date_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_date_test,
+    ::testing::Values(
+        test_case<ignite_date>{ignite_date{1970, 1, 1}, -1730003579},
+        test_case<ignite_date>{ignite_date{1905, 9, 26}, -1268080282},
+        test_case<ignite_date>{ignite_date{2036, 3, 17}, 435798353}
+    )
+);
+
+class hash_utils_time_test: public 
::testing::TestWithParam<test_case<ignite_time>> {};
+
+TEST_P(hash_utils_time_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg, 5));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_time_test,
+    ::testing::Values(
+        test_case<ignite_time>{ignite_time{0, 0}, -1321305871},
+        test_case<ignite_time>{ignite_time{0,0, 1}, -975644488},
+        test_case<ignite_time>{ignite_time{0, 0, 0, 1}, -1321305871},
+        test_case<ignite_time>{ignite_time{0, 0, 0, 10'000}, -1417871408},
+        test_case<ignite_time>{ignite_time{0, 0, 0, 10'001}, -1417871408},
+        test_case<ignite_time>{ignite_time{19, 42, 21, 42'042}, 57055814}
+    )
+);
+
+class hash_utils_date_time_test: public 
::testing::TestWithParam<test_case<ignite_date_time>> {};
+
+TEST_P(hash_utils_date_time_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg, 5));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_date_time_test,
+    ::testing::Values(
+        test_case<ignite_date_time>{ignite_date_time{{1970, 1, 1}, {0,0}}, 
-986160737},
+        test_case<ignite_date_time>{ignite_date_time{{1905, 9, 26}, {19, 42, 
21}}, -1487071575},
+        test_case<ignite_date_time>{ignite_date_time{{2036, 3, 17}, {21, 21, 
21, 12'000}}, 1007809846},
+        test_case<ignite_date_time>{ignite_date_time{{2036, 3, 17}, {21, 21, 
21, 12'001}}, 1007809846}
+    )
+);
+
+class hash_utils_timestamp_test: public 
::testing::TestWithParam<test_case<ignite_timestamp>> {};
+
+TEST_P(hash_utils_timestamp_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg, 5));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_timestamp_test,
+    ::testing::Values(
+        test_case<ignite_timestamp>{{0,0}, -1028348915},
+        test_case<ignite_timestamp>{{0, 420'000}, 789406184},
+        test_case<ignite_timestamp>{{1773221571, 21'123}, 670786278},
+        test_case<ignite_timestamp>{{1773221571, 21'000}, 670786278}
+    )
+);
+
+
+template<>
+void PrintTo(const test_case<std::string>& tc, std::ostream* os) {
+    *os << "arg = " << tc.arg;
+}
+
+class hash_utils_string_test: public 
::testing::TestWithParam<test_case<std::string>> {};
+
+TEST_P(hash_utils_string_test, simple) {
+    auto param = GetParam();
+
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    simple,
+    hash_utils_string_test,
+    ::testing::Values(
+        test_case<std::string>{"", 0},
+        test_case<std::string>{" ", -2039187927},
+        test_case<std::string>{"foo", -477838538},
+        test_case<std::string>{"foo ", 1516292748},
+        test_case<std::string>{" foo", -1406774036},
+        test_case<std::string>{"Foo", 2010420341},
+        test_case<std::string>{"bar", 1863106271},
+        test_case<std::string>{"baR", -1753335891},
+        test_case<std::string>{"the quick brown fox jumped over the lazy dog", 
1452923692},
+        test_case<std::string>{"Карл у Клары украл кораллы", -1909478343}
+    )
+);
+
+
+template<>
+void PrintTo(const test_case<std::vector<std::byte>>& tc, std::ostream* os) {
+    *os << "arg = " << "[";
+    *os << std::hex;
+    for (auto b : tc.arg) {
+         *os << "0x" << static_cast<uint32_t>(b) << ",";
+    }
+
+    *os << "]";
+}
+
+class hash_utils_bytes_test: public 
::testing::TestWithParam<test_case<std::vector<std::byte>>> {};
+
+TEST_P(hash_utils_bytes_test, simple) {
+    auto param = GetParam();
+    ASSERT_EQ(param.expected, hash(param.arg));
+}
+
+std::vector<std::byte> from_ints(std::vector<int> ints) {
+    std::vector<std::byte> res;
+    res.reserve(ints.size());
+
+    std::transform(
+        ints.begin(),
+        ints.end(),
+        std::back_insert_iterator(res),
+        [](int src) {
+            return static_cast<std::byte>(src);
+        }
+        );

Review Comment:
   `from_ints` converts `int` to `std::byte` with 
`static_cast<std::byte>(src)`. For negative values (e.g., `-1` in the test 
cases) the resulting value is implementation-defined and can vary between 
compilers/architectures. Convert via an unsigned 8-bit type first (or clamp) to 
ensure `-1` reliably becomes `0xFF`.



##########
modules/platforms/cpp/ignite/common/detail/hash_utils_test.cpp:
##########
@@ -0,0 +1,451 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <ignite/common/detail/hash_utils.h>
+#include <ignite/common/detail/string_extensions.h>
+
+#include <cmath>

Review Comment:
   This test file uses `std::numeric_limits`, `std::transform`, and 
`std::back_insert_iterator`, but it does not include the corresponding standard 
headers (`<limits>`, `<algorithm>`, `<iterator>`). Relying on transitive 
includes can cause build failures on some toolchains; add the missing includes 
explicitly.
   ```suggestion
   #include <cmath>
   #include <algorithm>
   #include <iterator>
   #include <limits>
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to