introduce fnv1a hashing function (#39515)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39515

changelog: [internal]

Implements FNV hashing algorithm: http://www.isthe.com/chongo/tech/comp/fnv/

Reviewed By: javache

Differential Revision: D49358327

fbshipit-source-id: b211da89ca7b6bea6ed1b0732e639bbc2de210f7
This commit is contained in:
Samuel Susla
2023-09-22 05:53:13 -07:00
committed by Facebook GitHub Bot
parent e5b62b5ecd
commit 353b31c7da
3 changed files with 62 additions and 1 deletions
@@ -8,6 +8,7 @@
#pragma once
#include <react/renderer/core/RawPropsPrimitives.h>
#include <react/utils/fnv1a.h>
#include <functional>
// 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") \
}())
@@ -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<int8_t>(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
@@ -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 <gtest/gtest.h>
#include <react/utils/fnv1a.h>
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