diff --git a/packages/react-native/ReactCommon/react/renderer/core/PropsMacros.h b/packages/react-native/ReactCommon/react/renderer/core/PropsMacros.h index d940fd6069c..3d2e5b221d9 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/PropsMacros.h +++ b/packages/react-native/ReactCommon/react/renderer/core/PropsMacros.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include // We need to use clang pragmas inside of a macro below, @@ -23,7 +24,7 @@ ([]() constexpr->RawPropsPropNameHash { \ CLANG_PRAGMA("clang diagnostic push") \ CLANG_PRAGMA("clang diagnostic ignored \"-Wshadow\"") \ - return folly::hash::fnv32_buf(s, sizeof(s) - 1); \ + return facebook::react::fnv1a(s); \ CLANG_PRAGMA("clang diagnostic pop") \ }()) diff --git a/packages/react-native/ReactCommon/react/utils/fnv1a.h b/packages/react-native/ReactCommon/react/utils/fnv1a.h new file mode 100644 index 00000000000..fe2721d4bc0 --- /dev/null +++ b/packages/react-native/ReactCommon/react/utils/fnv1a.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +namespace facebook::react { + +/** + * FNV-1a hash function implementation. + * Implemented as described in http://www.isthe.com/chongo/tech/comp/fnv/. + * + * Please use std::hash if possible. `fnv1a` should only be used in cases + * when std::hash does not provide the needed functionality. For example, + * constexpr. + */ +constexpr uint32_t fnv1a(std::string_view string) noexcept { + constexpr uint32_t offset_basis = 2166136261; + + uint32_t hash = offset_basis; + + for (auto const& c : string) { + hash ^= static_cast(c); + // Using shifts and adds instead of multiplication with a prime number. + // This is faster when compiled with optimizations. + hash += + (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24); + } + + return hash; +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/utils/tests/fnv1aTests.cpp b/packages/react-native/ReactCommon/react/utils/tests/fnv1aTests.cpp new file mode 100644 index 00000000000..5c7b76d099a --- /dev/null +++ b/packages/react-native/ReactCommon/react/utils/tests/fnv1aTests.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +namespace facebook::react { + +TEST(fnv1aTests, testBasicHashing) { + EXPECT_EQ(fnv1a("react"), fnv1a("react")); + + EXPECT_NE(fnv1a("react"), fnv1a("tceat")); + + auto string1 = "case 1"; + auto string2 = "different string"; + EXPECT_EQ(fnv1a(string1), fnv1a(string1)); + EXPECT_NE(fnv1a(string1), fnv1a(string2)); +} + +} // namespace facebook::react