18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#ifndef API_BASE_UTIL_HASH_H 178bf80f4bSopenharmony_ci#define API_BASE_UTIL_HASH_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <cstdint> 208bf80f4bSopenharmony_ci 218bf80f4bSopenharmony_ci#include <base/containers/type_traits.h> 228bf80f4bSopenharmony_ci#include <base/namespace.h> 238bf80f4bSopenharmony_ci 248bf80f4bSopenharmony_ciBASE_BEGIN_NAMESPACE() 258bf80f4bSopenharmony_ciconstexpr uint64_t FNV_OFFSET_BASIS = 0xcbf29ce484222325ull; 268bf80f4bSopenharmony_ciconstexpr uint64_t FNV_PRIME = 1099511628211ull; 278bf80f4bSopenharmony_ciconstexpr uint32_t FNV_OFFSET_BASIS_32 = 0x811c9dc5u; 288bf80f4bSopenharmony_ciconstexpr uint32_t FNV_PRIME_32 = 16777619u; 298bf80f4bSopenharmony_ci 308bf80f4bSopenharmony_citemplate<typename T> 318bf80f4bSopenharmony_ciuint64_t hash(const T& value); 328bf80f4bSopenharmony_ci 338bf80f4bSopenharmony_citemplate<> 348bf80f4bSopenharmony_ciinline uint64_t hash(const uint8_t& value) 358bf80f4bSopenharmony_ci{ 368bf80f4bSopenharmony_ci return value; 378bf80f4bSopenharmony_ci} 388bf80f4bSopenharmony_citemplate<> 398bf80f4bSopenharmony_ciinline uint64_t hash(const uint16_t& value) 408bf80f4bSopenharmony_ci{ 418bf80f4bSopenharmony_ci return value; 428bf80f4bSopenharmony_ci} 438bf80f4bSopenharmony_citemplate<> 448bf80f4bSopenharmony_ciinline uint64_t hash(const uint32_t& value) 458bf80f4bSopenharmony_ci{ 468bf80f4bSopenharmony_ci return value; 478bf80f4bSopenharmony_ci} 488bf80f4bSopenharmony_citemplate<> 498bf80f4bSopenharmony_ciinline uint64_t hash(const uint64_t& value) 508bf80f4bSopenharmony_ci{ 518bf80f4bSopenharmony_ci return value; 528bf80f4bSopenharmony_ci} 538bf80f4bSopenharmony_ci#ifdef __APPLE__ 548bf80f4bSopenharmony_citemplate<> 558bf80f4bSopenharmony_ciinline uint64_t hash(const unsigned long& value) 568bf80f4bSopenharmony_ci{ 578bf80f4bSopenharmony_ci return value; 588bf80f4bSopenharmony_ci} 598bf80f4bSopenharmony_ci#endif 608bf80f4bSopenharmony_citemplate<> 618bf80f4bSopenharmony_ciinline uint64_t hash(const int8_t& value) 628bf80f4bSopenharmony_ci{ 638bf80f4bSopenharmony_ci return static_cast<uint64_t>(value); 648bf80f4bSopenharmony_ci} 658bf80f4bSopenharmony_citemplate<> 668bf80f4bSopenharmony_ciinline uint64_t hash(const int16_t& value) 678bf80f4bSopenharmony_ci{ 688bf80f4bSopenharmony_ci return static_cast<uint64_t>(value); 698bf80f4bSopenharmony_ci} 708bf80f4bSopenharmony_citemplate<> 718bf80f4bSopenharmony_ciinline uint64_t hash(const int32_t& value) 728bf80f4bSopenharmony_ci{ 738bf80f4bSopenharmony_ci return static_cast<uint64_t>(value); 748bf80f4bSopenharmony_ci} 758bf80f4bSopenharmony_citemplate<> 768bf80f4bSopenharmony_ciinline uint64_t hash(const int64_t& value) 778bf80f4bSopenharmony_ci{ 788bf80f4bSopenharmony_ci return static_cast<uint64_t>(value); 798bf80f4bSopenharmony_ci} 808bf80f4bSopenharmony_citemplate<> 818bf80f4bSopenharmony_ciinline uint64_t hash(void* const& value) 828bf80f4bSopenharmony_ci{ 838bf80f4bSopenharmony_ci return static_cast<size_t>(reinterpret_cast<uintptr_t>(value)); 848bf80f4bSopenharmony_ci} 858bf80f4bSopenharmony_citemplate<typename T> 868bf80f4bSopenharmony_ciinline uint64_t hash(T* const& value) 878bf80f4bSopenharmony_ci{ 888bf80f4bSopenharmony_ci return static_cast<size_t>(reinterpret_cast<uintptr_t>(value)); 898bf80f4bSopenharmony_ci} 908bf80f4bSopenharmony_ci 918bf80f4bSopenharmony_ciinline uint32_t FNV1a32Hash(const uint8_t* data, size_t len) 928bf80f4bSopenharmony_ci{ 938bf80f4bSopenharmony_ci // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function 948bf80f4bSopenharmony_ci uint32_t hash = FNV_OFFSET_BASIS_32; 958bf80f4bSopenharmony_ci while (len--) { 968bf80f4bSopenharmony_ci hash ^= *data; 978bf80f4bSopenharmony_ci hash *= FNV_PRIME_32; 988bf80f4bSopenharmony_ci ++data; 998bf80f4bSopenharmony_ci } 1008bf80f4bSopenharmony_ci return hash; 1018bf80f4bSopenharmony_ci} 1028bf80f4bSopenharmony_ci 1038bf80f4bSopenharmony_citemplate<class T> 1048bf80f4bSopenharmony_ciinline uint32_t FNV1a32Hash(const T* data, size_t len) 1058bf80f4bSopenharmony_ci{ 1068bf80f4bSopenharmony_ci return FNV1a32Hash(reinterpret_cast<const uint8_t*>(data), len * sizeof(T)); 1078bf80f4bSopenharmony_ci} 1088bf80f4bSopenharmony_ci 1098bf80f4bSopenharmony_citemplate<class T> 1108bf80f4bSopenharmony_ciinline uint32_t FNV1a32Hash(const T& data) 1118bf80f4bSopenharmony_ci{ 1128bf80f4bSopenharmony_ci return FNV1a32Hash(&reinterpret_cast<const uint8_t&>(data), sizeof(T)); 1138bf80f4bSopenharmony_ci} 1148bf80f4bSopenharmony_ci 1158bf80f4bSopenharmony_ciinline uint64_t FNV1aHash(const uint8_t* data, size_t len) 1168bf80f4bSopenharmony_ci{ 1178bf80f4bSopenharmony_ci // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function 1188bf80f4bSopenharmony_ci uint64_t hash = FNV_OFFSET_BASIS; 1198bf80f4bSopenharmony_ci while (len--) { 1208bf80f4bSopenharmony_ci hash ^= *data; 1218bf80f4bSopenharmony_ci hash *= FNV_PRIME; 1228bf80f4bSopenharmony_ci ++data; 1238bf80f4bSopenharmony_ci } 1248bf80f4bSopenharmony_ci return hash; 1258bf80f4bSopenharmony_ci} 1268bf80f4bSopenharmony_ci 1278bf80f4bSopenharmony_citemplate<class T> 1288bf80f4bSopenharmony_ciinline uint64_t FNV1aHash(const T* data, size_t len) 1298bf80f4bSopenharmony_ci{ 1308bf80f4bSopenharmony_ci return FNV1aHash(reinterpret_cast<const uint8_t*>(data), len * sizeof(T)); 1318bf80f4bSopenharmony_ci} 1328bf80f4bSopenharmony_ci 1338bf80f4bSopenharmony_citemplate<class T> 1348bf80f4bSopenharmony_ciinline uint64_t FNV1aHash(const T& data) 1358bf80f4bSopenharmony_ci{ 1368bf80f4bSopenharmony_ci return FNV1aHash(&reinterpret_cast<const uint8_t&>(data), sizeof(T)); 1378bf80f4bSopenharmony_ci} 1388bf80f4bSopenharmony_ci 1398bf80f4bSopenharmony_citemplate<typename T> 1408bf80f4bSopenharmony_ciinline void HashCombine(uint64_t& seed, const T& v) 1418bf80f4bSopenharmony_ci{ 1428bf80f4bSopenharmony_ci constexpr const uint64_t GOLDEN_RATIO = 0x9e3779b9; 1438bf80f4bSopenharmony_ci constexpr const uint64_t ROTL = 6; 1448bf80f4bSopenharmony_ci constexpr const uint64_t ROTR = 2; 1458bf80f4bSopenharmony_ci seed ^= hash(v) + GOLDEN_RATIO + (seed << ROTL) + (seed >> ROTR); 1468bf80f4bSopenharmony_ci} 1478bf80f4bSopenharmony_ci 1488bf80f4bSopenharmony_citemplate<typename... Rest> 1498bf80f4bSopenharmony_ciinline void HashCombine(uint64_t& seed, const Rest&... rest) 1508bf80f4bSopenharmony_ci{ 1518bf80f4bSopenharmony_ci (HashCombine(seed, rest), ...); 1528bf80f4bSopenharmony_ci} 1538bf80f4bSopenharmony_ci 1548bf80f4bSopenharmony_citemplate<typename... Rest> 1558bf80f4bSopenharmony_ciinline uint64_t Hash(Rest&&... rest) 1568bf80f4bSopenharmony_ci{ 1578bf80f4bSopenharmony_ci uint64_t seed = 0; 1588bf80f4bSopenharmony_ci (HashCombine(seed, BASE_NS::forward<Rest>(rest)), ...); 1598bf80f4bSopenharmony_ci return seed; 1608bf80f4bSopenharmony_ci} 1618bf80f4bSopenharmony_ci 1628bf80f4bSopenharmony_citemplate<typename Iter> 1638bf80f4bSopenharmony_ciinline uint64_t HashRange(Iter first, Iter last) 1648bf80f4bSopenharmony_ci{ 1658bf80f4bSopenharmony_ci uint64_t seed = 0; 1668bf80f4bSopenharmony_ci for (; first != last; ++first) { 1678bf80f4bSopenharmony_ci HashCombine(seed, *first); 1688bf80f4bSopenharmony_ci } 1698bf80f4bSopenharmony_ci 1708bf80f4bSopenharmony_ci return seed; 1718bf80f4bSopenharmony_ci} 1728bf80f4bSopenharmony_ci 1738bf80f4bSopenharmony_citemplate<typename Iter> 1748bf80f4bSopenharmony_ciinline void HashRange(uint64_t& seed, Iter first, Iter last) 1758bf80f4bSopenharmony_ci{ 1768bf80f4bSopenharmony_ci for (; first != last; ++first) { 1778bf80f4bSopenharmony_ci HashCombine(seed, *first); 1788bf80f4bSopenharmony_ci } 1798bf80f4bSopenharmony_ci} 1808bf80f4bSopenharmony_ciBASE_END_NAMESPACE() 1818bf80f4bSopenharmony_ci#endif // API_BASE_UTIL_COMPILE_TIME_HASHES_H