Add defense for builtin_clz/builtin_ctz in case that input is zero
This commit is contained in:
@ -80,6 +80,7 @@ void ObExprEstimateNdv::llc_estimate_ndv(int64_t& result, const ObString& bitmap
|
||||
}
|
||||
uint64_t ObExprEstimateNdv::llc_leading_zeros(uint64_t value, uint64_t bit_width)
|
||||
{
|
||||
OB_ASSERT(0ULL != value);
|
||||
return std::min(bit_width, static_cast<uint64_t>(__builtin_clzll(value)));
|
||||
}
|
||||
|
||||
|
||||
@ -126,8 +126,9 @@ public:
|
||||
|
||||
typedef bool (*is_type_func)(common::ObObjType type);
|
||||
|
||||
static constexpr int flag2bit(uint64_t flag)
|
||||
static int flag2bit(uint64_t flag)
|
||||
{
|
||||
OB_ASSERT(0ULL != flag);
|
||||
return static_cast<int>(__builtin_ctzll(flag));
|
||||
}
|
||||
|
||||
|
||||
@ -1561,12 +1561,14 @@ void ObHashJoinOp::calc_cache_aware_partition_count()
|
||||
int64_t tmp_partition_cnt_per_level = max_partition_count_per_level_;
|
||||
if (total_partition_cnt > tmp_partition_cnt_per_level) {
|
||||
level1_part_count_ = part_count_;
|
||||
OB_ASSERT(0 != level1_part_count_);
|
||||
level1_bit_ = __builtin_ctz(level1_part_count_);
|
||||
level2_part_count_ = total_partition_cnt / level1_part_count_;
|
||||
level2_part_count_ =
|
||||
level2_part_count_ > tmp_partition_cnt_per_level ? tmp_partition_cnt_per_level : level2_part_count_;
|
||||
} else {
|
||||
level1_part_count_ = total_partition_cnt > part_count_ ? total_partition_cnt : part_count_;
|
||||
OB_ASSERT(0 != level1_part_count_);
|
||||
level1_bit_ = __builtin_ctz(level1_part_count_);
|
||||
}
|
||||
LOG_TRACE("partition count",
|
||||
@ -2755,6 +2757,7 @@ int ObHashJoinOp::get_next_probe_partition()
|
||||
}
|
||||
} else {
|
||||
// two level
|
||||
OB_ASSERT(0 != level2_part_count_);
|
||||
int64_t level1_part_idx = (cur_full_right_partition_ >> (__builtin_ctz(level2_part_count_)));
|
||||
if (level1_part_idx < dump_part_count) {
|
||||
cur_left_hist_ = &part_histograms_[cur_full_right_partition_];
|
||||
|
||||
@ -307,6 +307,8 @@ private:
|
||||
|
||||
void set_part_count(int64_t part_shift, int64_t level1_part_count, int64_t level2_part_count)
|
||||
{
|
||||
OB_ASSERT(0 != level1_part_count);
|
||||
OB_ASSERT(0 != level2_part_count);
|
||||
part_shift_ = part_shift;
|
||||
level_one_part_count_ = level1_part_count;
|
||||
level_two_part_count_ = level2_part_count;
|
||||
|
||||
@ -19,11 +19,6 @@
|
||||
namespace oceanbase {
|
||||
namespace storage {
|
||||
|
||||
constexpr int64_t next_pow2(const int64_t x)
|
||||
{
|
||||
return x ? (1ULL << (8 * sizeof(int64_t) - __builtin_clzll(x - 1))) : 1;
|
||||
}
|
||||
|
||||
template <typename Key, typename Handle>
|
||||
class ObHandleCacheNode : public common::ObDLinkBase<ObHandleCacheNode<Key, Handle>> {
|
||||
public:
|
||||
@ -125,7 +120,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static const uint64_t BUCKET_SIZE = next_pow2(N * 2);
|
||||
static const uint64_t BUCKET_SIZE = common::next_pow2(N * 2);
|
||||
static const uint64_t MASK = BUCKET_SIZE - 1;
|
||||
CacheNode nodes_[N];
|
||||
int16_t buckets_[BUCKET_SIZE];
|
||||
|
||||
Reference in New Issue
Block a user