mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Fixed FPE in yandexConsistentHash
This commit is contained in:
parent
f149e3b436
commit
62053314bb
@ -29,11 +29,12 @@ struct YandexConsistentHashImpl
|
|||||||
static constexpr auto name = "yandexConsistentHash";
|
static constexpr auto name = "yandexConsistentHash";
|
||||||
|
|
||||||
using HashType = UInt64;
|
using HashType = UInt64;
|
||||||
/// Actually it supports UInt64, but it is effective only if n < 65536
|
/// Actually it supports UInt64, but it is efficient only if n <= 32768
|
||||||
using ResultType = UInt32;
|
using ResultType = UInt16;
|
||||||
using BucketsCountType = ResultType;
|
using BucketsType = ResultType;
|
||||||
|
static constexpr auto max_buckets = 32768;
|
||||||
|
|
||||||
static inline ResultType apply(UInt64 hash, BucketsCountType n)
|
static inline ResultType apply(UInt64 hash, BucketsType n)
|
||||||
{
|
{
|
||||||
return ConsistentHashing(hash, n);
|
return ConsistentHashing(hash, n);
|
||||||
}
|
}
|
||||||
@ -59,9 +60,10 @@ struct JumpConsistentHashImpl
|
|||||||
|
|
||||||
using HashType = UInt64;
|
using HashType = UInt64;
|
||||||
using ResultType = Int32;
|
using ResultType = Int32;
|
||||||
using BucketsCountType = ResultType;
|
using BucketsType = ResultType;
|
||||||
|
static constexpr auto max_buckets = static_cast<UInt64>(std::numeric_limits<BucketsType>::max());
|
||||||
|
|
||||||
static inline ResultType apply(UInt64 hash, BucketsCountType n)
|
static inline ResultType apply(UInt64 hash, BucketsType n)
|
||||||
{
|
{
|
||||||
return JumpConsistentHash(hash, n);
|
return JumpConsistentHash(hash, n);
|
||||||
}
|
}
|
||||||
@ -74,9 +76,10 @@ struct SumburConsistentHashImpl
|
|||||||
|
|
||||||
using HashType = UInt32;
|
using HashType = UInt32;
|
||||||
using ResultType = UInt16;
|
using ResultType = UInt16;
|
||||||
using BucketsCountType = ResultType;
|
using BucketsType = ResultType;
|
||||||
|
static constexpr auto max_buckets = static_cast<UInt64>(std::numeric_limits<BucketsType>::max());
|
||||||
|
|
||||||
static inline ResultType apply(HashType hash, BucketsCountType n)
|
static inline ResultType apply(HashType hash, BucketsType n)
|
||||||
{
|
{
|
||||||
return static_cast<ResultType>(sumburConsistentHash(hash, n));
|
return static_cast<ResultType>(sumburConsistentHash(hash, n));
|
||||||
}
|
}
|
||||||
@ -143,8 +146,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
using HashType = typename Impl::HashType;
|
using HashType = typename Impl::HashType;
|
||||||
using ResultType = typename Impl::ResultType;
|
using ResultType = typename Impl::ResultType;
|
||||||
using BucketsType = typename Impl::BucketsCountType;
|
using BucketsType = typename Impl::BucketsType;
|
||||||
static constexpr auto max_buckets = static_cast<UInt64>(std::numeric_limits<BucketsType>::max());
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline BucketsType checkBucketsRange(T buckets)
|
inline BucketsType checkBucketsRange(T buckets)
|
||||||
@ -153,7 +155,7 @@ private:
|
|||||||
throw Exception(
|
throw Exception(
|
||||||
"The second argument of function " + getName() + " (number of buckets) must be positive number", ErrorCodes::BAD_ARGUMENTS);
|
"The second argument of function " + getName() + " (number of buckets) must be positive number", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
if (unlikely(static_cast<UInt64>(buckets) > max_buckets))
|
if (unlikely(static_cast<UInt64>(buckets) > Impl::max_buckets))
|
||||||
throw Exception("The value of the second argument of function " + getName() + " (number of buckets) is not fit to "
|
throw Exception("The value of the second argument of function " + getName() + " (number of buckets) is not fit to "
|
||||||
+ DataTypeNumber<BucketsType>().getName(),
|
+ DataTypeNumber<BucketsType>().getName(),
|
||||||
ErrorCodes::BAD_ARGUMENTS);
|
ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
@ -15,5 +15,5 @@
|
|||||||
* It requires O(1) memory and cpu to calculate. So, it is faster than classic
|
* It requires O(1) memory and cpu to calculate. So, it is faster than classic
|
||||||
* consistent hashing algos with points on circle.
|
* consistent hashing algos with points on circle.
|
||||||
*/
|
*/
|
||||||
std::size_t ConsistentHashing(std::uint64_t x, std::size_t n); // Works good for n < 65536
|
std::size_t ConsistentHashing(std::uint64_t x, std::size_t n); // Works for n <= 32768
|
||||||
std::size_t ConsistentHashing(std::uint64_t lo, std::uint64_t hi, std::size_t n); // Works good for n < 4294967296
|
std::size_t ConsistentHashing(std::uint64_t lo, std::uint64_t hi, std::size_t n); // Works for n <= 2^31
|
||||||
|
Loading…
Reference in New Issue
Block a user