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