[FEAT MERGE] ap benchmark opt
Co-authored-by: zhenhan.gong@gmail.com <zhenhan.gong@gmail.com> Co-authored-by: skylhd <dickylhd@gmail.com> Co-authored-by: DengzhiLiu <dengzhiliu@gmail.com>
This commit is contained in:
parent
0fe3ce7c9e
commit
6bf3f38ce4
26
deps/oblib/src/common/ob_target_specific.cpp
vendored
26
deps/oblib/src/common/ob_target_specific.cpp
vendored
@ -12,36 +12,10 @@
|
||||
|
||||
#define USING_LOG_PREFIX COMMON
|
||||
|
||||
#include "ob_target_specific.h"
|
||||
#include "lib/cpu/ob_cpu_topology.h"
|
||||
#include "lib/oblog/ob_log.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
uint32_t get_supported_archs()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
if (ObCpuFlagsCache::support_sse42()) {
|
||||
result |= static_cast<uint32_t>(ObTargetArch::SSE42);
|
||||
}
|
||||
if (ObCpuFlagsCache::support_avx()) {
|
||||
result |= static_cast<uint32_t>(ObTargetArch::AVX);
|
||||
}
|
||||
if (ObCpuFlagsCache::support_avx2()) {
|
||||
result |= static_cast<uint32_t>(ObTargetArch::AVX2);
|
||||
}
|
||||
if (ObCpuFlagsCache::support_avx512()) {
|
||||
result |= static_cast<uint32_t>(ObTargetArch::AVX512);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_arch_supported(ObTargetArch arch)
|
||||
{
|
||||
static uint32_t arches = get_supported_archs();
|
||||
return arch == ObTargetArch::Default || (arches & static_cast<uint32_t>(arch));
|
||||
}
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
33
deps/oblib/src/common/ob_target_specific.h
vendored
33
deps/oblib/src/common/ob_target_specific.h
vendored
@ -14,6 +14,7 @@
|
||||
#define OCEANBASE_COMMON_OB_TARGET_SPECIFIC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "lib/cpu/ob_cpu_topology.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -36,14 +37,14 @@ bool is_arch_supported(ObTargetArch arch);
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
#define OB_AVX512_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,avx512f,avx512bw")))
|
||||
#define OB_AVX512_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,avx512f,avx512bw,avx512vl")))
|
||||
#define OB_AVX2_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2")))
|
||||
#define OB_AVX_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt,avx")))
|
||||
#define OB_SSE42_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt")))
|
||||
#define OB_DEFAULT_FUNCTION_SPECIFIC_ATTRIBUTE
|
||||
|
||||
# define OB_BEGIN_AVX512_SPECIFIC_CODE \
|
||||
_Pragma("clang attribute push(__attribute__((target(\"sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,avx512f,avx512bw\"))),apply_to=function)")
|
||||
_Pragma("clang attribute push(__attribute__((target(\"sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,avx512f,avx512bw,avx512vl\"))),apply_to=function)")
|
||||
# define OB_BEGIN_AVX2_SPECIFIC_CODE \
|
||||
_Pragma("clang attribute push(__attribute__((target(\"sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2\"))),apply_to=function)")
|
||||
# define OB_BEGIN_AVX_SPECIFIC_CODE \
|
||||
@ -56,7 +57,7 @@ bool is_arch_supported(ObTargetArch arch);
|
||||
# define OB_DUMMY_FUNCTION_DEFINITION [[maybe_unused]] void _dummy_function_definition();
|
||||
#else
|
||||
|
||||
#define OB_AVX512_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,avx512f,avx512bw,tune=native")))
|
||||
#define OB_AVX512_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,avx512f,avx512bw,avx512vl,tune=native")))
|
||||
#define OB_AVX2_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,tune=native")))
|
||||
#define OB_AVX_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt,avx,tune=native")))
|
||||
#define OB_SSE42_FUNCTION_SPECIFIC_ATTRIBUTE __attribute__((target("sse,sse2,sse3,ssse3,sse4,popcnt",tune=native)))
|
||||
@ -64,7 +65,7 @@ bool is_arch_supported(ObTargetArch arch);
|
||||
|
||||
# define OB_BEGIN_AVX512_SPECIFIC_CODE \
|
||||
_Pragma("GCC push_options") \
|
||||
_Pragma("GCC target(\"sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,avx512f,avx512bw,tune=native\")")
|
||||
_Pragma("GCC target(\"sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,avx512f,avx512bw,avx512vl,tune=native\")")
|
||||
# define OB_BEGIN_AVX2_SPECIFIC_CODE \
|
||||
_Pragma("GCC push_options") \
|
||||
_Pragma("GCC target(\"sse,sse2,sse3,ssse3,sse4,popcnt,avx,avx2,tune=native\")")
|
||||
@ -214,6 +215,30 @@ OB_DECLARE_AVX512_SPECIFIC_CODE(
|
||||
|
||||
#endif
|
||||
|
||||
OB_INLINE uint32_t get_supported_archs()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
if (ObCpuFlagsCache::support_sse42()) {
|
||||
result |= static_cast<uint32_t>(ObTargetArch::SSE42);
|
||||
}
|
||||
if (ObCpuFlagsCache::support_avx()) {
|
||||
result |= static_cast<uint32_t>(ObTargetArch::AVX);
|
||||
}
|
||||
if (ObCpuFlagsCache::support_avx2()) {
|
||||
result |= static_cast<uint32_t>(ObTargetArch::AVX2);
|
||||
}
|
||||
if (ObCpuFlagsCache::support_avx512()) {
|
||||
result |= static_cast<uint32_t>(ObTargetArch::AVX512);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OB_INLINE bool is_arch_supported(ObTargetArch arch)
|
||||
{
|
||||
static uint32_t arches = get_supported_archs();
|
||||
return arch == ObTargetArch::Default || (arches & static_cast<uint32_t>(arch));
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_COMMON_OB_TARGET_SPECIFIC_H_
|
||||
|
176
deps/oblib/src/lib/container/ob_bitmap.cpp
vendored
176
deps/oblib/src/lib/container/ob_bitmap.cpp
vendored
@ -23,9 +23,8 @@ namespace oceanbase
|
||||
namespace common
|
||||
{
|
||||
|
||||
// Transform 64-byte mask to 64-bit mask
|
||||
|
||||
OB_DECLARE_AVX512_SPECIFIC_CODE(
|
||||
// Transform 64-byte mask to 64-bit mask
|
||||
inline static uint64_t bytes64mask_to_bits64mask(
|
||||
const uint8_t *bytes64,
|
||||
const bool need_flip = false)
|
||||
@ -37,6 +36,77 @@ inline static uint64_t bytes64mask_to_bits64mask(
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline static void bitmap_get_condensed_index(
|
||||
const uint8_t *data,
|
||||
const int32_t size,
|
||||
int32_t *row_ids,
|
||||
int32_t &row_count)
|
||||
{
|
||||
int32_t offset = 0;
|
||||
const uint8_t *pos = data;
|
||||
const uint8_t *end_pos = data + size;
|
||||
const uint8_t *end_pos64 = pos + size / 64 * 64;
|
||||
row_count = 0;
|
||||
for (; pos < end_pos64; pos += 64) {
|
||||
uint64_t mask64 = bytes64mask_to_bits64mask(pos);
|
||||
__m512i start_index = _mm512_set1_epi32(offset);
|
||||
__m512i base_index = _mm512_setr_epi32(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
|
||||
base_index = _mm512_add_epi32(base_index, start_index);
|
||||
uint16_t mask16 = mask64 & 0xFFFF;
|
||||
_mm512_mask_compressstoreu_epi32(row_ids + row_count, mask16, base_index);
|
||||
row_count += popcount64(mask16);
|
||||
const __m512i constant16 = _mm512_set1_epi32(16);
|
||||
base_index = _mm512_add_epi32(base_index, constant16);
|
||||
mask16 = (mask64 >> 16) & 0xFFFF;
|
||||
_mm512_mask_compressstoreu_epi32(row_ids + row_count, mask16, base_index);
|
||||
row_count += popcount64(mask16);
|
||||
base_index = _mm512_add_epi32(base_index, constant16);
|
||||
mask16 = (mask64 >> 32) & 0xFFFF;
|
||||
_mm512_mask_compressstoreu_epi32(row_ids + row_count, mask16, base_index);
|
||||
row_count += popcount64(mask16);
|
||||
base_index = _mm512_add_epi32(base_index, constant16);
|
||||
mask16 = mask64 >> 48;
|
||||
_mm512_mask_compressstoreu_epi32(row_ids + row_count, mask16, base_index);
|
||||
row_count += popcount64(mask16);
|
||||
|
||||
offset += 64;
|
||||
}
|
||||
while (pos < end_pos) {
|
||||
if (*pos) {
|
||||
row_ids[row_count++] = pos - data;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void uint64_mask_to_bits_mask(
|
||||
const uint64_t *data,
|
||||
const int64_t size,
|
||||
uint8_t *skip)
|
||||
{
|
||||
const uint64_t *pos = data;
|
||||
const uint64_t *end_pos = data + size;
|
||||
const uint64_t *end_pos64 = data + size / 8 * 8;
|
||||
uint64_t i = 0;
|
||||
const __m512i zero64 = _mm512_setzero_si512();
|
||||
|
||||
while (pos < end_pos64) {
|
||||
__m512i v = _mm512_loadu_si512(pos);
|
||||
skip[i++] |= _mm512_cmp_epi64_mask(v, zero64, 0);
|
||||
pos += 8;
|
||||
}
|
||||
|
||||
uint64_t *skip64 = reinterpret_cast<uint64_t *>(skip);
|
||||
|
||||
while (pos < end_pos) {
|
||||
if (*pos == 0) {
|
||||
i = pos - data;
|
||||
skip64[i / 64] |= 1LU << (i % 64);
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
OB_DECLARE_AVX2_SPECIFIC_CODE(
|
||||
@ -229,7 +299,7 @@ inline static void bitmap_next_valid_idx(
|
||||
}
|
||||
|
||||
inline static void bitmap_get_row_ids(
|
||||
int64_t *row_ids,
|
||||
int32_t *row_ids,
|
||||
int64_t &row_count,
|
||||
int64_t &from,
|
||||
const int64_t to,
|
||||
@ -263,6 +333,32 @@ inline static void bitmap_get_row_ids(
|
||||
}
|
||||
}
|
||||
|
||||
inline static void bitmap_get_condensed_index(
|
||||
const uint8_t *data,
|
||||
const int32_t size,
|
||||
int32_t *row_ids,
|
||||
int32_t &row_count)
|
||||
{
|
||||
const uint8_t *pos = data;
|
||||
const uint8_t *end_pos = data + size;
|
||||
const uint8_t *end_pos64 = pos + size / 64 * 64;
|
||||
row_count = 0;
|
||||
for (; pos < end_pos64; pos += 64) {
|
||||
uint64_t mask = bytes64mask_to_bits64mask(pos);
|
||||
while (mask) {
|
||||
uint64_t index = countr_zero64(mask);
|
||||
mask = blsr64(mask);
|
||||
row_ids[row_count++] = pos - data + index;
|
||||
}
|
||||
}
|
||||
while (pos < end_pos) {
|
||||
if (*pos) {
|
||||
row_ids[row_count++] = pos - data;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void bitmap_to_bits_mask(
|
||||
const int64_t from,
|
||||
const int64_t to,
|
||||
@ -316,36 +412,6 @@ inline static void uint64_mask_to_bits_mask(
|
||||
}
|
||||
)
|
||||
|
||||
OB_DECLARE_AVX512_SPECIFIC_CODE(
|
||||
inline static void uint64_mask_to_bits_mask(
|
||||
const uint64_t *data,
|
||||
const int64_t size,
|
||||
uint8_t *skip)
|
||||
{
|
||||
const uint64_t *pos = data;
|
||||
const uint64_t *end_pos = data + size;
|
||||
const uint64_t *end_pos64 = data + size / 8 * 8;
|
||||
uint64_t i = 0;
|
||||
const __m512i zero64 = _mm512_setzero_si512();
|
||||
|
||||
while (pos < end_pos64) {
|
||||
__m512i v = _mm512_loadu_si512(pos);
|
||||
skip[i++] |= _mm512_cmp_epi64_mask(v, zero64, 0);
|
||||
pos += 8;
|
||||
}
|
||||
|
||||
uint64_t *skip64 = reinterpret_cast<uint64_t *>(skip);
|
||||
|
||||
while (pos < end_pos) {
|
||||
if (*pos == 0) {
|
||||
i = pos - data;
|
||||
skip64[i / 64] |= 1LU << (i % 64);
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
class SelectAndOp {
|
||||
public:
|
||||
OB_INLINE static uint8_t apply(uint8_t a, uint8_t b) { return a & b; }
|
||||
@ -398,8 +464,8 @@ struct SelectOpImpl
|
||||
};
|
||||
|
||||
ObBitmap::ObBitmap(ObIAllocator &allocator)
|
||||
: is_inited_(false), valid_bytes_(0), capacity_(0),
|
||||
data_(nullptr), allocator_(allocator)
|
||||
: is_inited_(false), valid_bytes_(0), capacity_(0), data_(nullptr),
|
||||
condensed_cnt_(-1), condensed_idx_(nullptr), allocator_(allocator)
|
||||
{}
|
||||
|
||||
ObBitmap::~ObBitmap()
|
||||
@ -473,7 +539,7 @@ int64_t ObBitmap::next_valid_idx(const int64_t start,
|
||||
}
|
||||
|
||||
int ObBitmap::get_row_ids(
|
||||
int64_t *row_ids,
|
||||
int32_t *row_ids,
|
||||
int64_t &row_count,
|
||||
int64_t &from,
|
||||
const int64_t to,
|
||||
@ -481,9 +547,10 @@ int ObBitmap::get_row_ids(
|
||||
const int64_t id_offset) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(from < 0 || to > valid_bytes_ || to < from || limit <= 0)) {
|
||||
if (OB_UNLIKELY(from < 0 || to > valid_bytes_ || to < from || limit <= 0 || from < id_offset)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LIB_LOG(WARN, "Invalid from or to when get row ids", K(ret), K(from), K(to), K_(valid_bytes), K(limit));
|
||||
LIB_LOG(WARN, "Invalid from or to when get row ids", K(ret), K(from), K(to), K_(valid_bytes),
|
||||
K(limit), K(id_offset));
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
} else if (common::is_arch_supported(ObTargetArch::AVX2)) {
|
||||
common::specific::avx2::bitmap_get_row_ids(row_ids, row_count, from, to, limit, id_offset, data_);
|
||||
@ -625,15 +692,14 @@ int ObBitmap::reserve(size_type capacity)
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LIB_LOG(WARN, "Failed to alloc memory for bitmap", K(ret), K(new_size));
|
||||
} else {
|
||||
if (nullptr != data_) {
|
||||
allocator_.free(data_);
|
||||
}
|
||||
destroy();
|
||||
capacity_ = new_size;
|
||||
data_ = new_data;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
valid_bytes_ = capacity;
|
||||
condensed_cnt_ = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -680,6 +746,7 @@ void ObBitmap::reuse(const bool is_all_true)
|
||||
} else {
|
||||
MEMSET(static_cast<void*>(data_), 0, valid_bytes_);
|
||||
}
|
||||
condensed_cnt_ = -1;
|
||||
}
|
||||
|
||||
int ObBitmap::set_bitmap_batch(const int64_t offset, const int64_t count, const bool value)
|
||||
@ -822,6 +889,33 @@ void ObBitmap::filter(
|
||||
#endif
|
||||
}
|
||||
|
||||
int ObBitmap::generate_condensed_index()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (nullptr == condensed_idx_) {
|
||||
void *buf = nullptr;
|
||||
if (OB_ISNULL(buf = allocator_.alloc(sizeof(int32_t) * capacity()))) {
|
||||
ret = common::OB_ALLOCATE_MEMORY_FAILED;
|
||||
LIB_LOG(WARN, "fail to alloc row_ids", K(ret), K(capacity()));
|
||||
} else {
|
||||
condensed_idx_ = reinterpret_cast<int32_t *>(buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
// enable when avx512 is more efficient
|
||||
//} else if (common::is_arch_supported(ObTargetArch::AVX512)) {
|
||||
// common::specific::avx512::bitmap_get_condensed_index(data_, valid_bytes_, condensed_idx_, condensed_cnt_);
|
||||
} else if (common::is_arch_supported(ObTargetArch::AVX2)) {
|
||||
common::specific::avx2::bitmap_get_condensed_index(data_, valid_bytes_, condensed_idx_, condensed_cnt_);
|
||||
#endif
|
||||
} else {
|
||||
common::specific::normal::bitmap_get_condensed_index(data_, valid_bytes_, condensed_idx_, condensed_cnt_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} //end namespace oceanbase
|
||||
|
||||
} //end namespace common
|
||||
|
20
deps/oblib/src/lib/container/ob_bitmap.h
vendored
20
deps/oblib/src/lib/container/ob_bitmap.h
vendored
@ -98,12 +98,16 @@ public:
|
||||
int copy_from(const ObBitmap &bitmap, const int64_t start, const int64_t count);
|
||||
void reuse(const bool is_all_true = false);
|
||||
int get_row_ids(
|
||||
int64_t *row_ids,
|
||||
int32_t *row_ids,
|
||||
int64_t &row_count,
|
||||
int64_t &from,
|
||||
const int64_t to,
|
||||
const int64_t limit,
|
||||
const int64_t id_offset = 0) const;
|
||||
int generate_condensed_index();
|
||||
OB_INLINE bool is_index_generated() { return -1 != condensed_cnt_; }
|
||||
OB_INLINE const int32_t *get_condensed_idx() { return condensed_idx_; }
|
||||
OB_INLINE int32_t get_condensed_cnt() { return condensed_cnt_; }
|
||||
|
||||
OB_INLINE size_type capacity() const
|
||||
{
|
||||
@ -154,10 +158,12 @@ private:
|
||||
|
||||
private:
|
||||
bool is_inited_;
|
||||
int64_t valid_bytes_;
|
||||
int64_t capacity_;
|
||||
int32_t valid_bytes_;
|
||||
int32_t capacity_;
|
||||
// Make sure that data_[i] can only be equal to 0x00 or 0x01 when i is from 0 to (valid_bytes_ - 1).
|
||||
uint8_t *data_;
|
||||
int32_t condensed_cnt_;
|
||||
int32_t *condensed_idx_;
|
||||
ObIAllocator &allocator_;
|
||||
};
|
||||
|
||||
@ -175,7 +181,15 @@ OB_INLINE void ObBitmap::destroy()
|
||||
{
|
||||
if (nullptr != data_) {
|
||||
allocator_.free(data_);
|
||||
data_ = nullptr;
|
||||
}
|
||||
if (nullptr != condensed_idx_) {
|
||||
allocator_.free(condensed_idx_);
|
||||
condensed_idx_ = nullptr;
|
||||
}
|
||||
valid_bytes_ = 0;
|
||||
capacity_ = 0;
|
||||
condensed_cnt_ = -1;
|
||||
}
|
||||
|
||||
OB_INLINE bool ObBitmap::empty() const
|
||||
|
@ -187,7 +187,7 @@ TEST_F(TestObBitmap, get_row_ids)
|
||||
for (int64_t i = 4090; i < 4100; ++i) {
|
||||
EXPECT_EQ(OB_SUCCESS, bitmap.set(i, true));
|
||||
}
|
||||
int64_t *row_ids = reinterpret_cast<int64_t *>(allocator_.alloc(800));
|
||||
int32_t *row_ids = reinterpret_cast<int32_t *>(allocator_.alloc(800));
|
||||
int64_t row_count = 0;
|
||||
int64_t from = 0;
|
||||
EXPECT_EQ(OB_SUCCESS, bitmap.get_row_ids(row_ids, row_count, from, 3000, INT64_MAX));
|
||||
@ -211,6 +211,7 @@ TEST_F(TestObBitmap, get_row_ids)
|
||||
EXPECT_EQ(4090 + i - 2, row_ids[i]);
|
||||
}
|
||||
|
||||
int ret = OB_SUCCESS;
|
||||
from = 0;
|
||||
EXPECT_EQ(OB_SUCCESS, bitmap.get_row_ids(row_ids, row_count, from, 8193, 10));
|
||||
EXPECT_EQ(10, row_count);
|
||||
|
@ -208,16 +208,24 @@ TEST_F(TestObMicroBlockCache, test_block_cache)
|
||||
|
||||
|
||||
// multi block io
|
||||
int64_t block_count = 0;
|
||||
ObMultiBlockIOParam multi_io_param;
|
||||
multi_io_param.micro_index_infos_ = µ_idx_infos;
|
||||
multi_io_param.start_index_ = 0;
|
||||
multi_io_param.block_count_ = micro_idx_infos.count();
|
||||
ASSERT_EQ(OB_SUCCESS, data_block_cache_->prefetch(
|
||||
MTL_ID(),
|
||||
data_idx_info.get_macro_id(),
|
||||
multi_io_param,
|
||||
context_.query_flag_.is_use_block_cache(),
|
||||
multi_io_handle));
|
||||
multi_io_param.row_header_ = micro_idx_infos.at(0).row_header_;
|
||||
multi_io_param.micro_infos_.set_allocator(&allocator_);
|
||||
multi_io_param.micro_infos_.prepare_reallocate(micro_idx_infos.count());
|
||||
while (block_count < 16 && block_count < micro_idx_infos.count()) {
|
||||
multi_io_param.micro_infos_[block_count].set(
|
||||
micro_idx_infos.at(block_count).get_block_offset(), micro_idx_infos.at(block_count).get_block_size());
|
||||
multi_io_param.data_cache_size_ += micro_idx_infos.at(block_count).get_block_size();
|
||||
multi_io_param.micro_block_count_++;
|
||||
block_count++;
|
||||
}
|
||||
ASSERT_EQ(OB_SUCCESS, data_block_cache_->prefetch_multi_block(
|
||||
MTL_ID(),
|
||||
data_idx_info.get_macro_id(),
|
||||
multi_io_param,
|
||||
context_.query_flag_.is_use_block_cache(),
|
||||
multi_io_handle));
|
||||
ASSERT_EQ(OB_SUCCESS, multi_io_handle.wait());
|
||||
const ObMultiBlockIOResult *io_result
|
||||
= reinterpret_cast<const ObMultiBlockIOResult *>(multi_io_handle.get_buffer());
|
||||
@ -225,8 +233,8 @@ TEST_F(TestObMicroBlockCache, test_block_cache)
|
||||
|
||||
int64_t idx = 0;
|
||||
ObMicroBlockData data_block_data;
|
||||
while (idx != micro_idx_infos.count()) {
|
||||
ASSERT_EQ(OB_SUCCESS, io_result->get_block_data(idx, data_block_data));
|
||||
while (idx != block_count) {
|
||||
ASSERT_EQ(OB_SUCCESS, io_result->get_block_data(idx, multi_io_param.micro_infos_[idx], data_block_data));
|
||||
ASSERT_TRUE(data_block_data.is_valid());
|
||||
ASSERT_EQ(ObMicroBlockData::DATA_BLOCK, data_block_data.type_);
|
||||
ASSERT_EQ(data_block_data.get_micro_header()->row_count_, micro_idx_infos[idx].get_row_count());
|
||||
|
@ -415,7 +415,7 @@ TEST_F(TestCGGroupByScanner, test_decide_group_size)
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.init_group_by_info());
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -441,7 +441,7 @@ TEST_F(TestCGGroupByScanner, test_decide_can_group_by)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -472,7 +472,7 @@ TEST_F(TestCGGroupByScanner, test_read_distinct)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -513,7 +513,7 @@ TEST_F(TestCGGroupByScanner, test_read_reference)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -563,7 +563,7 @@ TEST_F(TestCGGroupByScanner, test_calc_aggregate_group_by)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -642,7 +642,7 @@ TEST_F(TestCGGroupByScanner, test_calc_aggregate_group_by_with_bitmap)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
|
@ -583,8 +583,8 @@ TEST_F(TestCGScanner, test_filter)
|
||||
pd_filter.datum_buf_ = new (buf3) blocksstable::ObStorageDatum[1]();
|
||||
buf3 = allocator_.alloc(sizeof(char *) * pd_filter.batch_size_);
|
||||
pd_filter.cell_data_ptrs_ = reinterpret_cast<const char **>(buf3);
|
||||
buf3 = allocator_.alloc(sizeof(int64_t) * pd_filter.batch_size_);
|
||||
pd_filter.row_ids_ = reinterpret_cast<int64_t *>(buf3);
|
||||
buf3 = allocator_.alloc(sizeof(int32_t) * pd_filter.batch_size_);
|
||||
pd_filter.row_ids_ = reinterpret_cast<int32_t *>(buf3);
|
||||
pd_filter.skip_bit_ = to_bit_vector(allocator_.alloc(ObBitVector::memory_size(256)));
|
||||
pd_filter.is_inited_ = true;
|
||||
|
||||
|
@ -416,7 +416,7 @@ TEST_F(TestCSCGGroupByScanner, test_decide_group_size)
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.init_group_by_info());
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -442,7 +442,7 @@ TEST_F(TestCSCGGroupByScanner, test_decide_can_group_by)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -473,7 +473,7 @@ TEST_F(TestCSCGGroupByScanner, test_read_distinct)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -514,7 +514,7 @@ TEST_F(TestCSCGGroupByScanner, test_read_reference)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -560,7 +560,7 @@ TEST_F(TestCSCGGroupByScanner, test_calc_aggregate_group_by)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
@ -644,7 +644,7 @@ TEST_F(TestCSCGGroupByScanner, test_calc_aggregate_group_by_with_bitmap)
|
||||
|
||||
int64_t start = 0;
|
||||
int64_t locate_count = row_cnt_;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate(ObCSRange(start, locate_count)));
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.locate_micro_index(ObCSRange(start, locate_count)));
|
||||
int64_t group_size = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, group_by_scanner.decide_group_size(group_size));
|
||||
ASSERT_EQ(500, group_size);
|
||||
|
@ -2016,6 +2016,8 @@ int ObRootService::execute_bootstrap(const obrpc::ObBootstrapArg &arg)
|
||||
LOG_WARN("fail to set one phase commit config", K(ret));
|
||||
} else if (OB_FAIL(disable_dbms_job())) {
|
||||
LOG_WARN("failed to update _enable_dbms_job_package", K(ret));
|
||||
} else if (OB_FAIL(set_bloom_filter_ratio_config_())) {
|
||||
LOG_WARN("failed to update _bloom_filter_ratio", K(ret));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -11566,6 +11568,18 @@ int ObRootService::disable_dbms_job()
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRootService::set_bloom_filter_ratio_config_()
|
||||
{
|
||||
int64_t affected_rows = 0;
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(sql_proxy_.write("ALTER SYSTEM SET _bloom_filter_ratio = 3;", affected_rows))) {
|
||||
LOG_WARN("update _bloom_filter_ratio failed", K(ret));
|
||||
} else if (OB_FAIL(check_config_result("_bloom_filter_ratio", "3"))) {
|
||||
LOG_WARN("failed to check config same", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRootService::handle_recover_table(const obrpc::ObRecoverTableArg &arg)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -918,6 +918,7 @@ private:
|
||||
int set_cpu_quota_concurrency_config_();
|
||||
int set_enable_trace_log_();
|
||||
int disable_dbms_job();
|
||||
int set_bloom_filter_ratio_config_();
|
||||
int try_notify_switch_leader(const obrpc::ObNotifySwitchLeaderArg::SwitchLeaderComment &comment);
|
||||
|
||||
int precheck_interval_part(const obrpc::ObAlterTableArg &arg);
|
||||
|
@ -380,6 +380,10 @@ public:
|
||||
const sql::ObBitVector &skip, const sql::EvalBound &bound,
|
||||
char *agg_cell,
|
||||
const RowSelector row_sel = RowSelector{}) = 0;
|
||||
|
||||
inline virtual int add_batch_for_multi_groups(RuntimeContext &agg_ctx, AggrRowPtr *agg_rows,
|
||||
RowSelector &row_sel, const int64_t batch_size,
|
||||
const int32_t agg_col_id) = 0;
|
||||
inline virtual int add_one_row(RuntimeContext &agg_ctx, const int64_t batch_idx,
|
||||
const int64_t batch_size, const bool is_null, const char *data,
|
||||
const int32_t data_len, int32_t agg_col_idx, char *agg_cell) = 0;
|
||||
|
@ -177,6 +177,87 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int add_batch_for_multi_groups(RuntimeContext &agg_ctx, AggrRowPtr *agg_rows,
|
||||
RowSelector &row_sel, const int64_t batch_size,
|
||||
const int32_t agg_col_id) override
|
||||
{
|
||||
#define INNER_ADD(vec_tc) \
|
||||
case (vec_tc): { \
|
||||
ret = inner_add_for_multi_groups<ObFixedLengthFormat<RTCType<vec_tc>>>( \
|
||||
agg_ctx, agg_rows, row_sel, batch_size, agg_col_id, param_expr->get_vector(eval_ctx)); \
|
||||
} break
|
||||
|
||||
int ret = OB_SUCCESS;
|
||||
ObAggrInfo &aggr_info = agg_ctx.aggr_infos_.at(agg_col_id);
|
||||
ObEvalCtx &eval_ctx = agg_ctx.eval_ctx_;
|
||||
VectorFormat fmt = VEC_INVALID;
|
||||
ObExpr *param_expr = nullptr;
|
||||
Derived *derived_this = static_cast<Derived *>(this);
|
||||
#ifndef NDEBUG
|
||||
int64_t mock_skip_data = 0;
|
||||
ObBitVector *mock_skip = to_bit_vector(&mock_skip_data);
|
||||
helper::print_input_rows(row_sel, *mock_skip, sql::EvalBound(), aggr_info,
|
||||
aggr_info.is_implicit_first_aggr(), eval_ctx, this, agg_col_id);
|
||||
#endif
|
||||
if (aggr_info.is_implicit_first_aggr()) {
|
||||
fmt = aggr_info.expr_->get_format(eval_ctx);
|
||||
param_expr = aggr_info.expr_;
|
||||
} else if (aggr_info.param_exprs_.count() == 1) {
|
||||
param_expr = aggr_info.param_exprs_.at(0);
|
||||
fmt = param_expr->get_format(eval_ctx);
|
||||
}
|
||||
if (OB_ISNULL(param_expr)) { // count(*)
|
||||
for (int i = 0; OB_SUCC(ret) && i < row_sel.size(); i++) {
|
||||
int batch_idx = row_sel.index(i);
|
||||
char *agg_cell = agg_ctx.row_meta().locate_cell_payload(agg_col_id, agg_rows[batch_idx]);
|
||||
if (OB_FAIL(derived_this->add_one_row(agg_ctx, batch_idx, batch_size, false, nullptr, 0,
|
||||
agg_col_id, agg_cell))) {
|
||||
SQL_LOG(WARN, "inner add one row failed", K(ret));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
VecValueTypeClass vec_tc = param_expr->get_vec_value_tc();
|
||||
switch(fmt) {
|
||||
case common::VEC_UNIFORM: {
|
||||
ret = inner_add_for_multi_groups<ObUniformFormat<false>>(
|
||||
agg_ctx, agg_rows, row_sel, batch_size, agg_col_id, param_expr->get_vector(eval_ctx));
|
||||
break;
|
||||
}
|
||||
case common::VEC_UNIFORM_CONST: {
|
||||
ret = inner_add_for_multi_groups<ObUniformFormat<true>>(
|
||||
agg_ctx, agg_rows, row_sel, batch_size, agg_col_id, param_expr->get_vector(eval_ctx));
|
||||
break;
|
||||
}
|
||||
case common::VEC_DISCRETE: {
|
||||
ret = inner_add_for_multi_groups<ObDiscreteFormat>(
|
||||
agg_ctx, agg_rows, row_sel, batch_size, agg_col_id, param_expr->get_vector(eval_ctx));
|
||||
break;
|
||||
}
|
||||
case common::VEC_CONTINUOUS: {
|
||||
ret = inner_add_for_multi_groups<ObContinuousFormat>(
|
||||
agg_ctx, agg_rows, row_sel, batch_size, agg_col_id, param_expr->get_vector(eval_ctx));
|
||||
break;
|
||||
}
|
||||
case common::VEC_FIXED: {
|
||||
switch(vec_tc) {
|
||||
LST_DO_CODE(INNER_ADD, AGG_VEC_TC_LIST);
|
||||
default: {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_LOG(WARN, "unexpected type class", K(vec_tc));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
#undef INNER_ADD
|
||||
}
|
||||
|
||||
int collect_batch_group_results(RuntimeContext &agg_ctx, const int32_t agg_col_id,
|
||||
const int32_t cur_group_id, const int32_t output_start_idx,
|
||||
const int32_t expect_batch_size, int32_t &output_size,
|
||||
@ -290,6 +371,28 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
template <typename ColumnFmt>
|
||||
int inner_add_for_multi_groups(RuntimeContext &agg_ctx, AggrRowPtr *agg_rows, RowSelector &row_sel,
|
||||
const int64_t batch_size, const int32_t agg_col_id,
|
||||
ObIVector *ivec)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ColumnFmt *param_vec = static_cast<ColumnFmt *>(ivec);
|
||||
bool is_null = false;
|
||||
const char *payload = nullptr;
|
||||
int32_t len = 0;
|
||||
Derived *derived_this = static_cast<Derived *>(this);
|
||||
for (int i = 0; OB_SUCC(ret) && i < row_sel.size(); i++) {
|
||||
int64_t batch_idx = row_sel.index(i);
|
||||
param_vec->get_payload(batch_idx, is_null, payload, len);
|
||||
char *agg_cell = agg_ctx.row_meta().locate_cell_payload(agg_col_id, agg_rows[batch_idx]);
|
||||
if (OB_FAIL(derived_this->add_one_row(agg_ctx, batch_idx, batch_size, is_null, payload, len,
|
||||
agg_col_id, agg_cell))) {
|
||||
SQL_LOG(WARN, "inner add one row failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
template <typename ColumnFmt>
|
||||
int add_batch_rows(RuntimeContext &agg_ctx, const sql::ObBitVector &skip,
|
||||
const sql::EvalBound &bound, const ObExpr ¶m_expr,
|
||||
|
@ -27,22 +27,31 @@ int Processor::init()
|
||||
int ret = OB_SUCCESS;
|
||||
if (inited_) {
|
||||
LOG_DEBUG("already inited, do nothing");
|
||||
} else if (agg_ctx_.aggr_infos_.count() <= 0) {
|
||||
// do nothing
|
||||
} else if (OB_UNLIKELY(agg_ctx_.aggr_infos_.count() >= MAX_SUPPORTED_AGG_CNT)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
SQL_LOG(WARN, "too many aggregations, not supported", K(ret));
|
||||
} else if (OB_FAIL(aggregates_.reserve(agg_ctx_.aggr_infos_.count()))) {
|
||||
SQL_LOG(WARN, "reserved allocator failed", K(ret));
|
||||
} else if (OB_FAIL(helper::init_aggregates(agg_ctx_, allocator_, aggregates_))) {
|
||||
SQL_LOG(WARN, "init aggregates failed", K(ret));
|
||||
} else if (OB_FAIL(add_one_row_fns_.prepare_allocate(agg_ctx_.aggr_infos_.count()))) {
|
||||
SQL_LOG(WARN, "prepare allocate elements failed", K(ret));
|
||||
} else {
|
||||
clear_add_one_row_fns();
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
inited_ = true;
|
||||
if (OB_ISNULL(row_selector_ = (uint16_t *)allocator_.alloc(
|
||||
sizeof(uint16_t) * agg_ctx_.eval_ctx_.max_batch_size_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("allocate memory failed", K(ret));
|
||||
} else {
|
||||
MEMSET(row_selector_, 0, sizeof(uint16_t) * agg_ctx_.eval_ctx_.max_batch_size_);
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (agg_ctx_.aggr_infos_.count() <= 0) {
|
||||
// do nothing
|
||||
} else if (OB_UNLIKELY(agg_ctx_.aggr_infos_.count() >= MAX_SUPPORTED_AGG_CNT)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
SQL_LOG(WARN, "too many aggregations, not supported", K(ret));
|
||||
} else if (OB_FAIL(aggregates_.reserve(agg_ctx_.aggr_infos_.count()))) {
|
||||
SQL_LOG(WARN, "reserved allocator failed", K(ret));
|
||||
} else if (OB_FAIL(helper::init_aggregates(agg_ctx_, allocator_, aggregates_))) {
|
||||
SQL_LOG(WARN, "init aggregates failed", K(ret));
|
||||
} else if (OB_FAIL(add_one_row_fns_.prepare_allocate(agg_ctx_.aggr_infos_.count()))) {
|
||||
SQL_LOG(WARN, "prepare allocate elements failed", K(ret));
|
||||
} else {
|
||||
clear_add_one_row_fns();
|
||||
}
|
||||
if (OB_SUCC(ret)) { inited_ = true; }
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -80,6 +89,7 @@ void Processor::destroy()
|
||||
}
|
||||
fast_single_row_aggregates_.reset();
|
||||
allocator_.reset();
|
||||
row_selector_ = nullptr;
|
||||
inited_ = false;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
agg_ctx_(eval_ctx, tenant_id, aggr_infos, label, allocator_),
|
||||
aggregates_(allocator_, aggr_infos.count()),
|
||||
fast_single_row_aggregates_(allocator_, aggr_infos.count()), extra_rt_info_buf_(nullptr),
|
||||
cur_extra_rt_info_idx_(0), add_one_row_fns_(allocator_, aggr_infos.count())
|
||||
cur_extra_rt_info_idx_(0), add_one_row_fns_(allocator_, aggr_infos.count()), row_selector_(nullptr)
|
||||
{}
|
||||
~Processor() { destroy(); }
|
||||
int init();
|
||||
@ -70,6 +70,29 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int add_batch_for_multi_groups(const int32_t start_agg_id, const int32_t end_agg_id,
|
||||
AggrRowPtr *agg_rows, const int64_t batch_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int size = 0;
|
||||
OB_ASSERT(batch_size <= agg_ctx_.eval_ctx_.max_batch_size_);
|
||||
if (OB_ISNULL(row_selector_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_LOG(WARN, "unexpected null selector", K(ret));
|
||||
}
|
||||
for (int i = 0; OB_SUCC(ret) && i < batch_size; i++) {
|
||||
if (OB_NOT_NULL(agg_rows[i])) { row_selector_[size++] = i; }
|
||||
}
|
||||
RowSelector iter(row_selector_, size);
|
||||
for (int col_id = start_agg_id; OB_SUCC(ret) && col_id < end_agg_id; col_id++) {
|
||||
if (OB_FAIL(aggregates_.at(col_id)->add_batch_for_multi_groups(agg_ctx_, agg_rows, iter,
|
||||
batch_size, col_id))) {
|
||||
SQL_LOG(WARN, "add batch for multi groups failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int collect_group_results(const RowMeta &row_meta, const ObIArray<ObExpr *> &group_exprs,
|
||||
const int32_t output_batch_size, ObBatchRows &output_brs,
|
||||
int64_t &cur_group_id);
|
||||
@ -220,6 +243,7 @@ private:
|
||||
char *extra_rt_info_buf_;
|
||||
int32_t cur_extra_rt_info_idx_;
|
||||
ObFixedArray<add_one_row_fn, ObIAllocator> add_one_row_fns_;
|
||||
uint16_t *row_selector_;
|
||||
// ObFixedArray<typename T>
|
||||
};
|
||||
} // end aggregate
|
||||
|
@ -60,8 +60,10 @@ DEF_TO_STRING(ObVTableScanParam)
|
||||
N_WAIT, for_update_wait_timeout_,
|
||||
N_FROZEN_VERSION, frozen_version_,
|
||||
K_(is_get),
|
||||
K_(pd_storage_flag),
|
||||
KPC_(output_exprs),
|
||||
KPC_(op_filters),
|
||||
K_(table_scan_opt),
|
||||
K_(external_file_format),
|
||||
K_(external_file_location));
|
||||
J_OBJ_END();
|
||||
|
@ -266,6 +266,7 @@ ObVTableScanParam() :
|
||||
pd_storage_filters_(nullptr),
|
||||
pd_storage_flag_(false),
|
||||
row2exprs_projector_(NULL),
|
||||
table_scan_opt_(),
|
||||
ext_file_column_exprs_(NULL),
|
||||
ext_column_convert_exprs_(NULL),
|
||||
schema_guard_(NULL)
|
||||
@ -340,6 +341,7 @@ ObVTableScanParam() :
|
||||
int32_t pd_storage_flag_;
|
||||
// project storage output row to %output_exprs_
|
||||
storage::ObRow2ExprsProjector *row2exprs_projector_;
|
||||
ObTableScanOption table_scan_opt_;
|
||||
|
||||
// external table
|
||||
const sql::ExprFixedArray *ext_file_column_exprs_;
|
||||
|
@ -1112,7 +1112,11 @@ int ObTextStringResult::calc_buffer_len(int64_t res_len)
|
||||
bool has_extern = lib::is_oracle_mode(); // even oracle may not need extern for temp data
|
||||
ObMemLobExternFlags extern_flags(has_extern);
|
||||
res_len += sizeof(ObLobCommon);
|
||||
buff_len_ = ObLobLocatorV2::calc_locator_full_len(extern_flags, 0, static_cast<uint32_t>(res_len), false);
|
||||
if (has_extern) {
|
||||
buff_len_ = ObLobLocatorV2::calc_locator_full_len(extern_flags, 0, static_cast<uint32_t>(res_len), false);
|
||||
} else {
|
||||
buff_len_ = res_len; // for mysql mode temp lob, we can mock it as disk inrow lob
|
||||
}
|
||||
} else {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("Lob: out row temp lob not implemented, not support length bigger than 512M",
|
||||
@ -1193,7 +1197,10 @@ int ObTextStringResult::fill_temp_lob_header(const int64_t res_len)
|
||||
ObString rowkey_str;
|
||||
ObString empty_str;
|
||||
ObLobCommon lob_common;
|
||||
if (OB_FAIL(locator.fill(TEMP_FULL_LOB,
|
||||
if (lib::is_mysql_mode()) {
|
||||
// for mysql mode temp lob, we can mock it as disk inrow lob
|
||||
MEMCPY(buffer_, &lob_common, sizeof(ObLobCommon));
|
||||
} else if (OB_FAIL(locator.fill(TEMP_FULL_LOB,
|
||||
extern_flags,
|
||||
rowkey_str,
|
||||
&lob_common,
|
||||
|
@ -166,6 +166,10 @@ DEF_STR_WITH_CHECKER(default_table_store_format, OB_TENANT_PARAMETER, "row",
|
||||
"values: row, column, compound",
|
||||
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
||||
DEF_INT(storage_rowsets_size, OB_TENANT_PARAMETER, "8192", "(0,1048576]",
|
||||
"the row number processed by vectorized storage engine within one batch in column storage. Range: (0,1048576]",
|
||||
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
||||
DEF_TIME(weak_read_version_refresh_interval, OB_CLUSTER_PARAMETER, "100ms", "[50ms,)",
|
||||
"the time interval to refresh cluster weak read version "
|
||||
"Range: [50ms, +∞)",
|
||||
@ -1067,6 +1071,12 @@ DEF_INT(_max_ls_cnt_per_server, OB_TENANT_PARAMETER, "0", "[0, 1024]",
|
||||
"0: the cluster will adapt the max ls number according to the memory size of tenant itself",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
||||
DEF_CAP(_io_read_batch_size, OB_TENANT_PARAMETER, "0K", "[0K,16M]", "Maximum batch size in one read io request. Range:[0K,16M]",
|
||||
ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
DEF_INT(_io_read_redundant_limit_percentage, OB_TENANT_PARAMETER, "0", "[0, 99]",
|
||||
"Maximum percentage of redundant size in one read io request, redundant data means blocks in the middle of the batch that hit in cache or filtered by skipping index but must be read. Range:[0,99]",
|
||||
ObParameterAttr(Section::SSTABLE, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
||||
// TODO bin.lb: to be remove
|
||||
DEF_CAP(dtl_buffer_size, OB_CLUSTER_PARAMETER, "64K", "[4K,2M]", "to be removed",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
@ -7545,10 +7545,8 @@ int ObPartitionUtils::calc_hash_part_idx(const uint64_t val,
|
||||
partition_idx += powN;
|
||||
}
|
||||
}
|
||||
LOG_TRACE("get hash part idx", K(lbt()), K(ret), K(val), K(part_num), K(N), K(powN), K(partition_idx));
|
||||
} else {
|
||||
partition_idx = val % part_num;
|
||||
LOG_TRACE("get hash part idx", K(lbt()), K(ret), K(val), K(part_num), K(partition_idx));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -88,12 +88,6 @@ using nullsafe_cmp_initer = InitCmpSet<
|
||||
static bool g_init_cmp_set =
|
||||
Ob2DArrayConstIniter<MAX_VEC_TC, MAX_VEC_TC, nullsafe_cmp_initer>::init();
|
||||
|
||||
static bool init_row_cmp_double_func() {
|
||||
ROW_CMP_FUNCS[VEC_TC_DOUBLE][VEC_TC_FIXED_DOUBLE] = VecTCCmpCalc<VEC_TC_DOUBLE, VEC_TC_DOUBLE>::cmp;
|
||||
ROW_CMP_FUNCS[VEC_TC_FIXED_DOUBLE][VEC_TC_DOUBLE] = VecTCCmpCalc<VEC_TC_DOUBLE, VEC_TC_DOUBLE>::cmp;
|
||||
return true;
|
||||
}
|
||||
static bool g_init_row_cmp_double_func = init_row_cmp_double_func();
|
||||
|
||||
void VectorCmpExprFuncsHelper::get_cmp_set(const sql::ObDatumMeta &l_meta,
|
||||
const sql::ObDatumMeta &r_meta,
|
||||
@ -316,7 +310,6 @@ struct EvalVectorCmp
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef VECTOR_CMP_CASE
|
||||
};
|
||||
|
||||
struct EvalVectorCmpWithNull
|
||||
@ -371,8 +364,6 @@ struct EvalVectorCmp<VEC_TC_NULL, r_tc, cmp_op>: public EvalVectorCmpWithNull {}
|
||||
template<ObCmpOp cmp_op>
|
||||
struct EvalVectorCmp<VEC_TC_NULL, VEC_TC_NULL, cmp_op>: public EvalVectorCmpWithNull {};
|
||||
|
||||
#undef CALC_FORMAT
|
||||
|
||||
static sql::ObExpr::EvalVectorFunc EVAL_VECTOR_EXPR_CMP_FUNCS[MAX_VEC_TC][MAX_VEC_TC][CO_MAX];
|
||||
|
||||
template<int X, int Y, bool defined>
|
||||
@ -406,10 +397,21 @@ struct VectorExprCmpFuncIniter<X, Y, true>
|
||||
template <int X, int Y>
|
||||
using cmp_initer = VectorExprCmpFuncIniter<
|
||||
X, Y,
|
||||
VecTCCmpCalc<static_cast<VecValueTypeClass>(X), static_cast<VecValueTypeClass>(Y)>::defined_>;
|
||||
VecTCCmpCalc<static_cast<VecValueTypeClass>(X), static_cast<VecValueTypeClass>(Y)>::defined_
|
||||
&& (!is_fixed_length_vec(static_cast<VecValueTypeClass>(X))
|
||||
|| !is_fixed_length_vec(static_cast<VecValueTypeClass>(Y)))>;
|
||||
|
||||
static int g_init_eval_vector_expr_cmp_funcs =
|
||||
Ob2DArrayConstIniter<MAX_VEC_TC, MAX_VEC_TC, cmp_initer>::init();
|
||||
} // end namespace common
|
||||
} // end namespace oceanbase
|
||||
|
||||
#include "expr_cmp_func_simd.ipp"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
|
||||
sql::ObExpr::EvalVectorFunc VectorCmpExprFuncsHelper::get_eval_vector_expr_cmp_func(
|
||||
const sql::ObDatumMeta &l_meta, const sql::ObDatumMeta &r_meta, const common::ObCmpOp cmp_op)
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "common/object/ob_obj_type.h"
|
||||
#include "sql/engine/expr/ob_expr.h"
|
||||
#include "common/object/ob_obj_compare.h"
|
||||
#include "sql/engine/expr/ob_expr_between.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
|
374
src/share/vector/expr_cmp_func_simd.ipp
Normal file
374
src/share/vector/expr_cmp_func_simd.ipp
Normal file
@ -0,0 +1,374 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "expr_cmp_func.h"
|
||||
#include "share/vector/ob_fixed_length_format.h"
|
||||
#include "share/datum/ob_datum_util.h"
|
||||
#include "share/vector/ob_uniform_format.h"
|
||||
#include "share/vector/vector_basic_op.h"
|
||||
#include "common/ob_target_specific.h"
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
#include <emmintrin.h>
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
using namespace sql;
|
||||
|
||||
OB_DECLARE_AVX512_SPECIFIC_CODE(
|
||||
template <VecValueTypeClass vec_tc, int val_size, ObCmpOp cmp_op>
|
||||
static int simd_eval_vector(const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip,
|
||||
const EvalBound &bound);
|
||||
)
|
||||
|
||||
template<VecValueTypeClass l_tc, VecValueTypeClass r_tc, ObCmpOp cmp_op>
|
||||
struct FixedVectorCmp
|
||||
{
|
||||
using L_VEC_FIXED_FMT =
|
||||
typename std::conditional<is_fixed_length_vec(l_tc), ObFixedLengthFormat<RTCType<l_tc>>,
|
||||
ObVectorBase>::type;
|
||||
using R_VEC_FIXED_FMT =
|
||||
typename std::conditional<is_fixed_length_vec(r_tc), ObFixedLengthFormat<RTCType<r_tc>>,
|
||||
ObVectorBase>::type;
|
||||
using RES_VEC_FIXED_FMT = ObFixedLengthFormat<int64_t>;
|
||||
|
||||
using L_VEC_UNIFORM_FMT = ObUniformFormat<false>;
|
||||
using R_VEC_UNIFORM_FMT = ObUniformFormat<false>;
|
||||
using L_VEC_UNIFORM_CONST_FMT = ObUniformFormat<true>;
|
||||
using R_VEC_UNIFORM_CONST_FMT = ObUniformFormat<true>;
|
||||
|
||||
static int eval_vector(const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip,
|
||||
const EvalBound &bound)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(eval_cmp_operands(expr, ctx, skip, bound))) {
|
||||
LOG_WARN("eval cmp operands failed", K(ret));
|
||||
} else {
|
||||
const ObExpr &left = *expr.args_[0];
|
||||
const ObExpr &right = *expr.args_[1];
|
||||
VectorFormat left_format = left.get_format(ctx);
|
||||
VectorFormat right_format = right.get_format(ctx);
|
||||
VectorFormat res_format = expr.get_format(ctx);
|
||||
LOG_DEBUG("eval vector cmp", K(expr), K(l_tc), K(r_tc), K(cmp_op), K(bound), K(left_format),
|
||||
K(right_format), K(res_format));
|
||||
if (is_valid_format(left_format) && is_valid_format(right_format) && is_valid_format(res_format)) {
|
||||
switch(CALC_FORMAT(left_format, right_format, res_format)) {
|
||||
case CALC_FORMAT(VEC_FIXED, VEC_FIXED, VEC_FIXED): {
|
||||
bool use_simd = (l_tc == r_tc
|
||||
&& static_cast<ObFixedLengthBase *>(expr.get_vector(ctx))->get_length() == sizeof(int64_t)
|
||||
&& sizeof(RTCType<l_tc>) <= sizeof(int64_t)
|
||||
&& cmp_op != CO_CMP && !left.get_vector(ctx)->has_null()
|
||||
&& !right.get_vector(ctx)->has_null() & bound.get_all_rows_active())
|
||||
&& simd_supported(l_tc);
|
||||
LOG_DEBUG("simd used", K(l_tc), K(r_tc), K(cmp_op), K(left.get_vector(ctx)->has_null()),
|
||||
K(right.get_vector(ctx)->has_null()), K(bound.get_all_rows_active()), K(use_simd));
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
if (use_simd && common::is_arch_supported(ObTargetArch::AVX512)) {
|
||||
ret = common::specific::avx512::simd_eval_vector<l_tc, sizeof(RTCType<l_tc>), cmp_op>(
|
||||
expr, ctx, skip, bound);
|
||||
} else {
|
||||
DO_VECTOR_CMP(L_VEC_FIXED_FMT, R_VEC_FIXED_FMT, RES_VEC_FIXED_FMT);
|
||||
}
|
||||
#else
|
||||
DO_VECTOR_CMP(L_VEC_FIXED_FMT, R_VEC_FIXED_FMT, RES_VEC_FIXED_FMT);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
VECTOR_CMP_CASE(VEC_UNIFORM, VEC_FIXED, VEC_FIXED);
|
||||
VECTOR_CMP_CASE(VEC_UNIFORM, VEC_UNIFORM, VEC_FIXED);
|
||||
VECTOR_CMP_CASE(VEC_UNIFORM, VEC_UNIFORM_CONST, VEC_FIXED);
|
||||
VECTOR_CMP_CASE(VEC_UNIFORM_CONST, VEC_FIXED, VEC_FIXED);
|
||||
VECTOR_CMP_CASE(VEC_UNIFORM_CONST, VEC_UNIFORM, VEC_FIXED);
|
||||
default: {
|
||||
DO_VECTOR_CMP(ObVectorBase, ObVectorBase, ObVectorBase);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid format", K(left_format), K(right_format), K(res_format));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
static constexpr bool simd_supported(VecValueTypeClass vec_tc)
|
||||
{
|
||||
return vec_tc == VEC_TC_INTEGER
|
||||
|| vec_tc == VEC_TC_UINTEGER
|
||||
|| vec_tc == VEC_TC_FLOAT
|
||||
|| vec_tc == VEC_TC_DOUBLE
|
||||
|| vec_tc == VEC_TC_DATE
|
||||
|| vec_tc == VEC_TC_DATETIME
|
||||
|| vec_tc == VEC_TC_TIME
|
||||
|| vec_tc == VEC_TC_BIT
|
||||
|| vec_tc == VEC_TC_ENUM_SET
|
||||
|| vec_tc == VEC_TC_DEC_INT32
|
||||
|| vec_tc == VEC_TC_YEAR
|
||||
|| vec_tc == VEC_TC_INTERVAL_YM
|
||||
|| vec_tc == VEC_TC_DEC_INT64;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
OB_DECLARE_AVX512_SPECIFIC_CODE(
|
||||
template<VecValueTypeClass vec_tc, int val_size, ObCmpOp cmp_op>
|
||||
struct __simd_cmp
|
||||
{
|
||||
using ret_type = char;
|
||||
OB_INLINE char operator()(const char *left, const char *right)
|
||||
{
|
||||
return char();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
OB_INLINE void __store_cmp_results(char *dst, const T & res_mask)
|
||||
{
|
||||
static const uint64_t MASK = 0xFF;
|
||||
static const __m512i TRUE_VALUES = _mm512_set1_epi64(1);
|
||||
uint64_t res_bits = res_mask;
|
||||
for (int i = 0; i < sizeof(T); i++) {
|
||||
uint8_t store_bits = static_cast<uint8_t>(MASK & res_bits);
|
||||
res_bits >>= 8;
|
||||
__m512i store_v = _mm512_maskz_mov_epi64(store_bits, TRUE_VALUES);
|
||||
_mm512_storeu_epi64(dst, store_v);
|
||||
dst += 64;
|
||||
}
|
||||
}
|
||||
#define DEF_SIMD_INTEGER_OP(ret_size, val_size, bits, cmp_op, cmp_name) \
|
||||
template <> \
|
||||
struct __simd_cmp<VEC_TC_INTEGER, val_size, cmp_op> \
|
||||
{ \
|
||||
using ret_type = __mmask##ret_size; \
|
||||
OB_INLINE ret_type operator()(const char *left, const char *right) \
|
||||
{ \
|
||||
__m512i left_v = _mm512_loadu_epi64(left); \
|
||||
__m512i right_v = _mm512_loadu_epi64(right); \
|
||||
__mmask##ret_size res_mask = _mm512_cmp##cmp_name##_epi##bits##_mask(left_v, right_v); \
|
||||
return res_mask; \
|
||||
} \
|
||||
}; \
|
||||
template <> \
|
||||
struct __simd_cmp<VEC_TC_UINTEGER, val_size, cmp_op> \
|
||||
{ \
|
||||
using ret_type = __mmask##ret_size; \
|
||||
OB_INLINE ret_type operator()(const char *left, const char *right) \
|
||||
{ \
|
||||
__m512i left_v = _mm512_loadu_epi64(left); \
|
||||
__m512i right_v = _mm512_loadu_epi64(right); \
|
||||
__mmask##ret_size res_mask = _mm512_cmp##cmp_name##_epu##bits##_mask(left_v, right_v); \
|
||||
return res_mask; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEF_SIMD_INTEGER_OP(64, 1, 8, CO_LE, le);
|
||||
DEF_SIMD_INTEGER_OP(32, 2, 16, CO_LE, le);
|
||||
DEF_SIMD_INTEGER_OP(16, 4, 32, CO_LE, le);
|
||||
DEF_SIMD_INTEGER_OP(8, 8, 64, CO_LE, le);
|
||||
|
||||
DEF_SIMD_INTEGER_OP(64, 1, 8, CO_LT, lt);
|
||||
DEF_SIMD_INTEGER_OP(32, 2, 16, CO_LT, lt);
|
||||
DEF_SIMD_INTEGER_OP(16, 4, 32, CO_LT, lt);
|
||||
DEF_SIMD_INTEGER_OP(8, 8, 64, CO_LT, lt);
|
||||
|
||||
DEF_SIMD_INTEGER_OP(64, 1, 8, CO_EQ, eq);
|
||||
DEF_SIMD_INTEGER_OP(32, 2, 16, CO_EQ, eq);
|
||||
DEF_SIMD_INTEGER_OP(16, 4, 32, CO_EQ, eq);
|
||||
DEF_SIMD_INTEGER_OP(8, 8, 64, CO_EQ, eq);
|
||||
|
||||
DEF_SIMD_INTEGER_OP(64, 1, 8, CO_NE, neq);
|
||||
DEF_SIMD_INTEGER_OP(32, 2, 16, CO_NE, neq);
|
||||
DEF_SIMD_INTEGER_OP(16, 4, 32, CO_NE, neq);
|
||||
DEF_SIMD_INTEGER_OP(8, 8, 64, CO_NE, neq);
|
||||
|
||||
DEF_SIMD_INTEGER_OP(64, 1, 8, CO_GT, gt);
|
||||
DEF_SIMD_INTEGER_OP(32, 2, 16, CO_GT, gt);
|
||||
DEF_SIMD_INTEGER_OP(16, 4, 32, CO_GT, gt);
|
||||
DEF_SIMD_INTEGER_OP(8, 8, 64, CO_GT, gt);
|
||||
|
||||
DEF_SIMD_INTEGER_OP(64, 1, 8, CO_GE, ge);
|
||||
DEF_SIMD_INTEGER_OP(32, 2, 16, CO_GE, ge);
|
||||
DEF_SIMD_INTEGER_OP(16, 4, 32, CO_GE, ge);
|
||||
DEF_SIMD_INTEGER_OP(8, 8, 64, CO_GE, ge);
|
||||
|
||||
#define DEF_SIMD_FLOATING_OP(cmp_name, cmp_op) \
|
||||
template <> \
|
||||
struct __simd_cmp<VEC_TC_FLOAT, sizeof(float), cmp_op> \
|
||||
{ \
|
||||
using ret_type = __mmask16; \
|
||||
OB_INLINE ret_type operator()(const char *left, const char *right) \
|
||||
{ \
|
||||
__m512 left_v = _mm512_loadu_ps(left); \
|
||||
__m512 right_v = _mm512_loadu_ps(right); \
|
||||
__mmask16 res_mask = _mm512_cmp##cmp_name##_ps_mask(left_v, right_v); \
|
||||
if (cmp_op == CO_GE || cmp_op == CO_GT) { res_mask = ~res_mask; } \
|
||||
return res_mask; \
|
||||
} \
|
||||
}; \
|
||||
template <> \
|
||||
struct __simd_cmp<VEC_TC_DOUBLE, sizeof(double), cmp_op> \
|
||||
{ \
|
||||
using ret_type = __mmask8; \
|
||||
OB_INLINE ret_type operator()(const char *left, const char *right) \
|
||||
{ \
|
||||
__m512d left_v = _mm512_loadu_pd(left); \
|
||||
__m512d righ_v = _mm512_loadu_pd(right); \
|
||||
__mmask8 res_mask = _mm512_cmp##cmp_name##_pd_mask(left_v, righ_v); \
|
||||
if (cmp_op == CO_GE || cmp_op == CO_GT) { res_mask = ~res_mask; } \
|
||||
return res_mask; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEF_SIMD_FLOATING_OP(eq, CO_EQ);
|
||||
DEF_SIMD_FLOATING_OP(le, CO_LE);
|
||||
DEF_SIMD_FLOATING_OP(lt, CO_LT);
|
||||
DEF_SIMD_FLOATING_OP(neq , CO_NE);
|
||||
DEF_SIMD_FLOATING_OP(lt, CO_GE);
|
||||
DEF_SIMD_FLOATING_OP(le, CO_GT);
|
||||
|
||||
template <VecValueTypeClass vec_tc, int val_size, ObCmpOp cmp_op>
|
||||
static int simd_eval_vector(const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip,
|
||||
const EvalBound &bound)
|
||||
{
|
||||
using mask_type = typename __simd_cmp<vec_tc, val_size, cmp_op>::ret_type;
|
||||
constexpr const VecValueTypeClass calc_tc =
|
||||
(vec_tc == VEC_TC_FLOAT || vec_tc == VEC_TC_DOUBLE) ?
|
||||
vec_tc :
|
||||
(std::is_signed<RTCType<vec_tc>>::value ? VEC_TC_INTEGER : VEC_TC_UINTEGER);
|
||||
#define DO_SIMD_CMP(off) \
|
||||
do { \
|
||||
mask_type res_mask = __simd_cmp<calc_tc, val_size, cmp_op>()(left_data + offset + off * 64, \
|
||||
right_data + offset + off * 64); \
|
||||
__store_cmp_results(res_data + off * res_off_perf_unit, res_mask); \
|
||||
} while (false)
|
||||
|
||||
using ResVec = ObFixedLengthFormat<int64_t>;
|
||||
int ret = OB_SUCCESS;
|
||||
ObFixedLengthBase *left_vec = static_cast<ObFixedLengthBase *>(expr.args_[0]->get_vector(ctx));
|
||||
ObFixedLengthBase *right_vec = static_cast<ObFixedLengthBase *>(expr.args_[1]->get_vector(ctx));
|
||||
ResVec *res_vec = static_cast<ResVec *>(expr.get_vector(ctx));
|
||||
int64_t size = bound.range_size(), unit = 512 / CHAR_BIT;
|
||||
int64_t chunk = size * val_size;
|
||||
int64_t unit_cnt = chunk / unit, remain = chunk % unit;
|
||||
const char *left_data = left_vec->get_data() + bound.start() * val_size;
|
||||
const char *right_data = right_vec->get_data() + bound.start() * val_size;
|
||||
char *res_data = res_vec->get_data() + bound.start() * sizeof(int64_t);
|
||||
int32_t res_off_perf_unit = unit / val_size * sizeof(int64_t) , batch_cnt = (unit / val_size) * 8;
|
||||
int64_t output_idx = bound.start();
|
||||
int32_t offset = 0;
|
||||
LOG_DEBUG("simd cmp", K(vec_tc), K(val_size), K(cmp_op), K(bound), K(unit_cnt));
|
||||
if (remain > 0) {
|
||||
int cmp_ret = 0;
|
||||
ObObjMeta obj_meta = expr.args_[0]->obj_meta_;
|
||||
for (int i = 0; i < remain / val_size; i++) {
|
||||
VecTCCmpCalc<vec_tc, vec_tc>::cmp(obj_meta, obj_meta, left_data + offset, val_size,
|
||||
right_data + offset, val_size,
|
||||
cmp_ret); // ignore ret code
|
||||
res_vec->set_int(output_idx, get_cmp_ret<cmp_op>(cmp_ret));
|
||||
output_idx += 1;
|
||||
offset += val_size;
|
||||
res_data = res_data + sizeof(int64_t);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < unit_cnt / 8; i++) {
|
||||
LST_DO_CODE(DO_SIMD_CMP, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
output_idx += batch_cnt;
|
||||
offset += unit * 8;
|
||||
res_data = res_data + res_off_perf_unit * 8;
|
||||
}
|
||||
switch (unit_cnt % 8) {
|
||||
case 7: {
|
||||
LST_DO_CODE(DO_SIMD_CMP, 0, 1, 2, 3, 4, 5, 6);
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
LST_DO_CODE(DO_SIMD_CMP, 0, 1, 2, 3, 4, 5);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
LST_DO_CODE(DO_SIMD_CMP, 0, 1, 2, 3, 4);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
LST_DO_CODE(DO_SIMD_CMP, 0, 1, 2, 3);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
LST_DO_CODE(DO_SIMD_CMP, 0, 1, 2);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
LST_DO_CODE(DO_SIMD_CMP, 0, 1);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
LST_DO_CODE(DO_SIMD_CMP, 0);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
batch_cnt = (unit_cnt % 8) * (unit / val_size);
|
||||
output_idx += batch_cnt;
|
||||
ObBitVector &eval_flags = expr.get_evaluated_flags(ctx);
|
||||
eval_flags.set_all(bound.start(), bound.end());
|
||||
OB_ASSERT(output_idx == bound.end());
|
||||
return ret;
|
||||
};
|
||||
)
|
||||
|
||||
|
||||
|
||||
template<int X, int Y, bool defined>
|
||||
struct FixedExprCmpFuncIniter
|
||||
{
|
||||
static void init_array()
|
||||
{
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
template<int X, int Y>
|
||||
struct FixedExprCmpFuncIniter<X, Y, true>
|
||||
{
|
||||
template <ObCmpOp cmp_op>
|
||||
using EvalFunc =
|
||||
FixedVectorCmp<static_cast<VecValueTypeClass>(X), static_cast<VecValueTypeClass>(Y), cmp_op>;
|
||||
static void init_array()
|
||||
{
|
||||
auto &funcs = EVAL_VECTOR_EXPR_CMP_FUNCS;
|
||||
funcs[X][Y][CO_LE] = &EvalFunc<CO_LE>::eval_vector;
|
||||
funcs[X][Y][CO_LT] = &EvalFunc<CO_LT>::eval_vector;
|
||||
funcs[X][Y][CO_GE] = &EvalFunc<CO_GE>::eval_vector;
|
||||
funcs[X][Y][CO_GT] = &EvalFunc<CO_GT>::eval_vector;
|
||||
funcs[X][Y][CO_NE] = &EvalFunc<CO_NE>::eval_vector;
|
||||
funcs[X][Y][CO_EQ] = &EvalFunc<CO_EQ>::eval_vector;
|
||||
funcs[X][Y][CO_CMP] = &EvalFunc<CO_CMP>::eval_vector;
|
||||
}
|
||||
};
|
||||
|
||||
template <int X, int Y>
|
||||
using fixed_cmp_initer = FixedExprCmpFuncIniter<
|
||||
X, Y,
|
||||
VecTCCmpCalc<static_cast<VecValueTypeClass>(X), static_cast<VecValueTypeClass>(Y)>::defined_
|
||||
&& is_fixed_length_vec(static_cast<VecValueTypeClass>(X))
|
||||
&& is_fixed_length_vec(static_cast<VecValueTypeClass>(Y))>;
|
||||
|
||||
static int g_init_fixed_eval_vector_cmp_funcs = Ob2DArrayConstIniter<MAX_VEC_TC, MAX_VEC_TC, fixed_cmp_initer>::init();
|
||||
|
||||
} // end common
|
||||
} // end oceanbase
|
@ -36,13 +36,13 @@ public:
|
||||
uint32_t *offsets, const int64_t start_idx,
|
||||
const int64_t read_rows, char *data)
|
||||
{
|
||||
has_null_ = has_null;
|
||||
UNUSED(has_null);
|
||||
has_null_ = false;
|
||||
nulls_->reset(read_rows);
|
||||
if (has_null) {
|
||||
for (int64_t i = 0; i < read_rows; ++i) {
|
||||
if (nulls.at(start_idx + i)) {
|
||||
nulls_->set(i);
|
||||
}
|
||||
for (int64_t i = 0; i < read_rows; ++i) {
|
||||
if (nulls.at(start_idx + i)) {
|
||||
nulls_->set(i);
|
||||
has_null_ = true;
|
||||
}
|
||||
}
|
||||
offsets_ = offsets + start_idx;
|
||||
|
@ -66,6 +66,8 @@ public:
|
||||
OB_INLINE int to_row(const sql::RowMeta &row_meta, sql::ObCompactRow *stored_row,
|
||||
const uint64_t row_idx, const int64_t col_idx, const int64_t remain_size,
|
||||
const bool is_fixed_length_data, int64_t &row_size) const override final;
|
||||
DEF_VEC_READ_INTERFACES(ObContinuousFormat);
|
||||
DEF_VEC_WRITE_INTERFACES(ObContinuousFormat);
|
||||
};
|
||||
|
||||
OB_INLINE void ObContinuousFormat::get_payload(const int64_t idx,
|
||||
|
@ -81,6 +81,8 @@ public:
|
||||
OB_INLINE int to_row(const sql::RowMeta &row_meta, sql::ObCompactRow *stored_row,
|
||||
const uint64_t row_idx, const int64_t col_idx, const int64_t remain_size,
|
||||
const bool is_fixed_length_data, int64_t &row_size) const override final;
|
||||
DEF_VEC_READ_INTERFACES(ObDiscreteFormat);
|
||||
DEF_VEC_WRITE_INTERFACES(ObDiscreteFormat);
|
||||
};
|
||||
|
||||
OB_INLINE void ObDiscreteFormat::get_payload(const int64_t idx,
|
||||
|
@ -24,12 +24,24 @@ namespace common
|
||||
const int64_t size,
|
||||
const int64_t col_idx) const
|
||||
{
|
||||
for (int64_t i = 0; i < size; i++) {
|
||||
int64_t row_idx = selector[i];
|
||||
if (nulls_->at(row_idx)) {
|
||||
stored_rows[i]->set_null(row_meta, col_idx);
|
||||
} else {
|
||||
stored_rows[i]->set_cell_payload(row_meta, col_idx, data_ + len_ * row_idx, len_);
|
||||
if (row_meta.fixed_expr_reordered()) {
|
||||
const int64_t offset = row_meta.get_fixed_cell_offset(col_idx);
|
||||
for (int64_t i = 0; i < size; i++) {
|
||||
int64_t row_idx = selector[i];
|
||||
if (nulls_->at(row_idx)) {
|
||||
stored_rows[i]->set_null(row_meta, col_idx);
|
||||
} else {
|
||||
stored_rows[i]->set_fixed_cell_payload(data_ + len_ * row_idx, offset, len_);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; i < size; i++) {
|
||||
int64_t row_idx = selector[i];
|
||||
if (nulls_->at(row_idx)) {
|
||||
stored_rows[i]->set_null(row_meta, col_idx);
|
||||
} else {
|
||||
stored_rows[i]->set_cell_payload(row_meta, col_idx, data_ + len_ * row_idx, len_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,15 +41,13 @@ public:
|
||||
const int64_t fixed_len, const int64_t start_idx,
|
||||
const int64_t read_rows, char *data)
|
||||
{
|
||||
has_null_ = has_null;
|
||||
// TODO: fix deep copy bug
|
||||
//nulls_->deep_copy(nulls, start_idx, start_idx + read_rows);
|
||||
UNUSED(has_null);
|
||||
has_null_ = false;
|
||||
nulls_->reset(read_rows);
|
||||
if (has_null) {
|
||||
for (int64_t i = 0; i < read_rows; ++i) {
|
||||
if (nulls.at(start_idx + i)) {
|
||||
nulls_->set(i);
|
||||
}
|
||||
for (int64_t i = 0; i < read_rows; ++i) {
|
||||
if (nulls.at(start_idx + i)) {
|
||||
nulls_->set(i);
|
||||
has_null_ = true;
|
||||
}
|
||||
}
|
||||
len_ = static_cast<int32_t> (fixed_len);
|
||||
|
@ -77,6 +77,8 @@ public:
|
||||
const uint64_t row_idx, const int64_t col_idx, const int64_t remain_size,
|
||||
const bool is_fixed_length_data, int64_t &row_size) const override final;
|
||||
OB_INLINE int32_t type_size() const { return sizeof(ValueType); }
|
||||
DEF_VEC_READ_INTERFACES(ObFixedLengthFormat<ValueType>);
|
||||
DEF_VEC_WRITE_INTERFACES(ObFixedLengthFormat<ValueType>);
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
|
@ -51,6 +51,367 @@ namespace common
|
||||
const char *r_v, \
|
||||
const ObLength r_len, \
|
||||
int &cmp_ret
|
||||
|
||||
#define DEF_VEC_READ_INTERFACES(Derived) \
|
||||
public: \
|
||||
OB_INLINE bool is_false(const int64_t idx) const \
|
||||
{ \
|
||||
return !derived_this().is_null(idx) && 0 == get_int(idx); \
|
||||
} \
|
||||
OB_INLINE bool is_true(const int64_t idx) const \
|
||||
{ \
|
||||
return !derived_this().is_null(idx) && 0 != get_int(idx); \
|
||||
} \
|
||||
OB_INLINE int8_t get_int8(const uint64_t idx) const \
|
||||
{ \
|
||||
return get<int8_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int8_t get_tinyint(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int8_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int16_t get_smallint(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int16_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int32_t get_mediumint(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int32_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int32_t get_int32(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int32_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int64_t get_int(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint8_t get_uint8(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint8_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint8_t get_utinyint(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint8_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint16_t get_usmallint(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint16_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint32_t get_umediumint(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint32_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint32_t get_uint32(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint32_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint64_t get_uint64(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint64_t get_uint(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE float get_float(const int64_t idx) const \
|
||||
{ \
|
||||
return get<float>(idx); \
|
||||
} \
|
||||
OB_INLINE double get_double(const int64_t idx) const \
|
||||
{ \
|
||||
return get<double>(idx); \
|
||||
} \
|
||||
OB_INLINE float get_ufloat(const int64_t idx) const \
|
||||
{ \
|
||||
return get<float>(idx); \
|
||||
} \
|
||||
OB_INLINE double get_udouble(const int64_t idx) const \
|
||||
{ \
|
||||
return get<double>(idx); \
|
||||
} \
|
||||
OB_INLINE int64_t get_ext(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int64_t get_unknown(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint64_t get_bit(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE bool get_bool(const int64_t idx) \
|
||||
{ \
|
||||
return 0 != get_int(idx); \
|
||||
} \
|
||||
OB_INLINE uint64_t get_enum(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint64_t get_set(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint64_t get_enumset(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int64_t get_interval_ym(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int64_t get_interval_nmonth(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int64_t get_datetime(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int64_t get_timestamp(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int64_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int32_t get_date(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int32_t>(idx); \
|
||||
} \
|
||||
OB_INLINE int64_t get_time(const int64_t idx) const \
|
||||
{ \
|
||||
return get<int32_t>(idx); \
|
||||
} \
|
||||
OB_INLINE uint8_t get_year(const int64_t idx) const \
|
||||
{ \
|
||||
return get<uint8_t>(idx); \
|
||||
} \
|
||||
OB_INLINE const number::ObCompactNumber &get_number(const int64_t idx) const \
|
||||
{ \
|
||||
return *(reinterpret_cast<const number::ObCompactNumber *>(derived_this().get_payload(idx))); \
|
||||
} \
|
||||
OB_INLINE const ObIntervalDSValue &get_interval_ds(const int64_t idx) const \
|
||||
{ \
|
||||
return *(reinterpret_cast<const ObIntervalDSValue *>(derived_this().get_payload(idx))); \
|
||||
} \
|
||||
OB_INLINE const ObOTimestampData &get_otimestamp_tz(const int64_t idx) const \
|
||||
{ \
|
||||
return *(reinterpret_cast<const ObOTimestampData *>(derived_this().get_payload(idx))); \
|
||||
} \
|
||||
OB_INLINE ObString get_string(const int64_t idx) const \
|
||||
{ \
|
||||
const char *str = NULL; \
|
||||
ObLength len = 0; \
|
||||
derived_this().get_payload(idx, str, len); \
|
||||
return ObString(len, str); \
|
||||
} \
|
||||
OB_INLINE int get_enumset_inner(const int64_t idx, ObEnumSetInnerValue &inner_value) const \
|
||||
{ \
|
||||
int64_t pos = 0; \
|
||||
const char *payload = NULL; \
|
||||
ObLength len = 0; \
|
||||
derived_this().get_payload(idx, payload, len); \
|
||||
return inner_value.deserialize(payload, len, pos); \
|
||||
} \
|
||||
OB_INLINE ObURowIDData get_urowid(const int64_t idx) const \
|
||||
{ \
|
||||
const char *ptr = NULL; \
|
||||
ObLength len = 0; \
|
||||
derived_this().get_payload(idx, ptr, len); \
|
||||
return ObURowIDData(len, reinterpret_cast<const uint8_t *>(ptr)); \
|
||||
} \
|
||||
OB_INLINE const ObLobLocator &get_lob_locator(const int64_t idx) const \
|
||||
{ \
|
||||
return *(reinterpret_cast<const ObLobLocator *>(derived_this().get_payload(idx))); \
|
||||
} \
|
||||
OB_INLINE const ObLobCommon &get_lob_data(const int64_t idx) const \
|
||||
{ \
|
||||
return *(reinterpret_cast<const ObLobCommon *>(derived_this().get_payload(idx))); \
|
||||
} \
|
||||
OB_INLINE const ObDecimalInt *get_decimal_int(const int64_t idx) const \
|
||||
{ \
|
||||
return reinterpret_cast<const ObDecimalInt *>(derived_this().get_payload(idx)); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
const Derived &derived_this() const \
|
||||
{ \
|
||||
return *static_cast<const Derived *>(this); \
|
||||
} \
|
||||
template <typename T> \
|
||||
OB_INLINE T get(const int64_t idx) const \
|
||||
{ \
|
||||
static_assert(sizeof(T) <= sizeof(int64_t), "invalid type"); \
|
||||
return *reinterpret_cast<const T *>(derived_this().get_payload(idx)); \
|
||||
}
|
||||
|
||||
#define DEF_VEC_WRITE_INTERFACES(Derived) \
|
||||
public: \
|
||||
OB_INLINE void set_int(const int64_t idx, const int64_t v) \
|
||||
{ \
|
||||
set<int64_t>(idx, v); \
|
||||
}; \
|
||||
OB_INLINE void set_int32(const int64_t idx, const int32_t v) \
|
||||
{ \
|
||||
set<int32_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_uint(const int64_t idx, const uint64_t v) \
|
||||
{ \
|
||||
set<uint64_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_uint32(const int64_t idx, const uint32_t v) \
|
||||
{ \
|
||||
set<uint32_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_bit(const int64_t idx, const uint64_t v) \
|
||||
{ \
|
||||
set<uint64_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_bool(const int64_t idx, const bool v) \
|
||||
{ \
|
||||
set_int(idx, static_cast<int64_t>(v)); \
|
||||
} \
|
||||
OB_INLINE void set_true(const int64_t idx) \
|
||||
{ \
|
||||
set_int(idx, static_cast<int64_t>(true)); \
|
||||
} \
|
||||
OB_INLINE void set_false(const int64_t idx) \
|
||||
{ \
|
||||
set_int(idx, static_cast<int64_t>(false)); \
|
||||
} \
|
||||
OB_INLINE void set_float(const int64_t idx, const float v) \
|
||||
{ \
|
||||
set<float>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_double(const int64_t idx, const double v) \
|
||||
{ \
|
||||
set<double>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_enum(const int64_t idx, const uint64_t v) \
|
||||
{ \
|
||||
set<uint64_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_set(const int64_t idx, const uint64_t v) \
|
||||
{ \
|
||||
set<uint64_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_datetime(const int64_t idx, const int64_t v) \
|
||||
{ \
|
||||
set<int64_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_timestamp(const int64_t idx, const int64_t v) \
|
||||
{ \
|
||||
set<int64_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_time(const int64_t idx, const int64_t v) \
|
||||
{ \
|
||||
set_int(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_date(const int64_t idx, const int32_t v) \
|
||||
{ \
|
||||
set<int32_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_year(const int64_t idx, const int8_t v) \
|
||||
{ \
|
||||
set<int8_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_interval_nmonth(const int64_t idx, const int64_t v) \
|
||||
{ \
|
||||
set<int64_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_interval_ym(const int64_t idx, const int64_t v) \
|
||||
{ \
|
||||
set<int64_t>(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_interval_ds(const int64_t idx, const ObIntervalDSValue &v) \
|
||||
{ \
|
||||
derived_this().set_payload_shallow(idx, &v, v.get_store_size()); \
|
||||
} \
|
||||
OB_INLINE void set_otimestamp_tz(const int64_t idx, const ObOTimestampData &v) \
|
||||
{ \
|
||||
*(reinterpret_cast<ObOTimestampData *>(no_cv(derived_this().get_payload(idx)))) = v; \
|
||||
} \
|
||||
OB_INLINE void set_otimestamp(const int64_t idx, const ObOTimestampData &v) \
|
||||
{ \
|
||||
*(reinterpret_cast<ObOTimestampData *>(no_cv(derived_this().get_payload(idx)))) = v; \
|
||||
} \
|
||||
OB_INLINE void set_number(const int64_t idx, const number::ObNumber &num) \
|
||||
{ \
|
||||
using CptNumber = number::ObCompactNumber; \
|
||||
CptNumber *cnum = reinterpret_cast<CptNumber *>(no_cv(derived_this().get_payload(idx))); \
|
||||
cnum->desc_ = num.d_; \
|
||||
const ObLength len = num.d_.len_ * sizeof(*num.get_digits()); \
|
||||
MEMCPY(&cnum->digits_[0], num.get_digits(), len); \
|
||||
derived_this().set_payload_shallow(idx, cnum, len + sizeof(ObNumberDesc)); \
|
||||
} \
|
||||
OB_INLINE void set_number(const int64_t idx, const number::ObCompactNumber &cnum) \
|
||||
{ \
|
||||
ObLength len = \
|
||||
static_cast<uint32_t>(sizeof(cnum) + cnum.desc_.len_ * sizeof(cnum.digits_[0])); \
|
||||
derived_this().set_payload(idx, &cnum, len); \
|
||||
} \
|
||||
OB_INLINE void set_number_shallow(const int64_t idx, const number::ObCompactNumber &cnum) \
|
||||
{ \
|
||||
ObLength len = \
|
||||
static_cast<uint32_t>(sizeof(cnum) + cnum.desc_.len_ * sizeof(cnum.digits_[0])); \
|
||||
derived_this().set_payload_shallow(idx, &cnum, len); \
|
||||
} \
|
||||
OB_INLINE void set_string(const int64_t idx, const ObString &v) \
|
||||
{ \
|
||||
derived_this().set_payload_shallow(idx, v.ptr(), v.length()); \
|
||||
} \
|
||||
OB_INLINE void set_string(const int64_t idx, const char *ptr, const uint32_t len) \
|
||||
{ \
|
||||
derived_this().set_payload_shallow(idx, ptr, len); \
|
||||
} \
|
||||
OB_INLINE void set_enumset_inner(const int64_t idx, const ObString &v) \
|
||||
{ \
|
||||
set_string(idx, v); \
|
||||
} \
|
||||
OB_INLINE void set_enumset_inner(const int64_t idx, const char *ptr, const uint32_t len) \
|
||||
{ \
|
||||
set_string(idx, ptr, len); \
|
||||
} \
|
||||
OB_INLINE void set_urowid(const int64_t idx, const ObURowIDData &urowid_data) \
|
||||
{ \
|
||||
const char *ptr = reinterpret_cast<const char *>(urowid_data.rowid_content_); \
|
||||
ObLength len = static_cast<uint32_t>(urowid_data.rowid_len_); \
|
||||
derived_this().set_payload(idx, ptr, len); \
|
||||
} \
|
||||
OB_INLINE void set_urowid(const int64_t idx, const char *ptr, const int64_t size) \
|
||||
{ \
|
||||
derived_this().set_payload(idx, ptr, static_cast<uint32_t>(size)); \
|
||||
} \
|
||||
OB_INLINE void set_lob_locator(const int64_t idx, const ObLobLocator &value) \
|
||||
{ \
|
||||
derived_this().set_payload(idx, &value, static_cast<uint32_t>(value.get_total_size())); \
|
||||
} \
|
||||
OB_INLINE void set_lob_data(const int64_t idx, const ObLobCommon &value, int64_t length) \
|
||||
{ \
|
||||
derived_this().set_payload(idx, &value, static_cast<uint32_t>(length)); \
|
||||
} \
|
||||
OB_INLINE void set_decimal_int(const int64_t idx, const ObDecimalInt *decint, int32_t len) \
|
||||
{ \
|
||||
derived_this().set_payload(idx, decint, static_cast<uint32_t>(len)); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
template <typename T> \
|
||||
OB_INLINE __attribute__((always_inline)) T *no_cv(const T *ptr) const \
|
||||
{ \
|
||||
return const_cast<T *>(ptr); \
|
||||
} \
|
||||
Derived &derived_this() \
|
||||
{ \
|
||||
return *static_cast<Derived *>(this); \
|
||||
} \
|
||||
template <typename T> \
|
||||
OB_INLINE void set(const int64_t idx, const T value) \
|
||||
{ \
|
||||
static_assert(sizeof(T) <= sizeof(int64_t), "invalid type"); \
|
||||
static_cast<Derived *>(this)->set_payload(idx, &value, sizeof(T)); \
|
||||
}
|
||||
|
||||
/*
|
||||
ObIVector
|
||||
|
|
||||
@ -116,13 +477,6 @@ public:
|
||||
virtual void unset_null(const int64_t idx) = 0;
|
||||
void set_null(const sql::EvalBound &bound);
|
||||
|
||||
bool is_false(const int64_t idx) const {
|
||||
return !is_null(idx) && 0 == get_int(idx);
|
||||
}
|
||||
bool is_true(const int64_t idx) const {
|
||||
return !is_null(idx) && 0 != get_int(idx);
|
||||
}
|
||||
|
||||
virtual int default_hash(BATCH_EVAL_HASH_ARGS) const = 0;
|
||||
virtual int murmur_hash(BATCH_EVAL_HASH_ARGS) const = 0;
|
||||
// In vectorization 1.0, hash value (calculated by murmur_hash_v2) of null is inconsistent for different types.
|
||||
@ -137,88 +491,6 @@ public:
|
||||
virtual int null_first_cmp(VECTOR_ONE_COMPARE_ARGS) const = 0;
|
||||
virtual int null_last_cmp(VECTOR_ONE_COMPARE_ARGS) const = 0;
|
||||
|
||||
// Vector get idx-th value interface
|
||||
OB_INLINE int8_t get_int8(const uint64_t idx) const { return get<int8_t>(idx); }
|
||||
OB_INLINE int8_t get_tinyint(const int64_t idx) const { return get<int8_t>(idx); }
|
||||
OB_INLINE int16_t get_smallint(const int64_t idx) const { return get<int16_t>(idx); }
|
||||
OB_INLINE int32_t get_mediumint(const int64_t idx) const { return get<int32_t>(idx); }
|
||||
OB_INLINE int32_t get_int32(const int64_t idx) const { return get<int32_t>(idx); }
|
||||
OB_INLINE int64_t get_int(const int64_t idx) const { return get<int64_t>(idx); }
|
||||
OB_INLINE uint8_t get_uint8(const int64_t idx) const { return get<uint8_t>(idx); }
|
||||
OB_INLINE uint8_t get_utinyint(const int64_t idx) const { return get<uint8_t>(idx); }
|
||||
OB_INLINE uint16_t get_usmallint(const int64_t idx) const { return get<uint16_t>(idx); }
|
||||
OB_INLINE uint32_t get_umediumint(const int64_t idx) const { return get<uint32_t>(idx); }
|
||||
OB_INLINE uint32_t get_uint32(const int64_t idx) const { return get<uint32_t>(idx); }
|
||||
OB_INLINE uint64_t get_uint64(const int64_t idx) const { return get<uint64_t>(idx); }
|
||||
OB_INLINE uint64_t get_uint(const int64_t idx) const { return get<uint64_t>(idx); }
|
||||
OB_INLINE float get_float(const int64_t idx) const { return get<float>(idx); }
|
||||
OB_INLINE double get_double(const int64_t idx) const { return get<double>(idx); }
|
||||
OB_INLINE float get_ufloat(const int64_t idx) const { return get<float>(idx); }
|
||||
OB_INLINE double get_udouble(const int64_t idx) const { return get<double>(idx); }
|
||||
OB_INLINE int64_t get_ext(const int64_t idx) const { return get<int64_t>(idx); }
|
||||
OB_INLINE int64_t get_unknown(const int64_t idx) const { return get<int64_t>(idx); }
|
||||
OB_INLINE uint64_t get_bit(const int64_t idx) const { return get<uint64_t>(idx); }
|
||||
OB_INLINE bool get_bool(const int64_t idx) { return 0 != get_int(idx); }
|
||||
OB_INLINE uint64_t get_enum(const int64_t idx) const { return get<uint64_t>(idx); }
|
||||
OB_INLINE uint64_t get_set(const int64_t idx) const { return get<uint64_t>(idx); }
|
||||
OB_INLINE uint64_t get_enumset(const int64_t idx) const { return get<uint64_t>(idx); }
|
||||
OB_INLINE const number::ObCompactNumber &get_number(const int64_t idx) const;
|
||||
OB_INLINE int64_t get_interval_ym(const int64_t idx) const { return get<int64_t>(idx); }
|
||||
OB_INLINE int64_t get_interval_nmonth(const int64_t idx) const { return get<int64_t>(idx); }
|
||||
OB_INLINE const ObIntervalDSValue &get_interval_ds(const int64_t idx) const;
|
||||
OB_INLINE int64_t get_datetime(const int64_t idx) const { return get<int64_t>(idx); }
|
||||
OB_INLINE int64_t get_timestamp(const int64_t idx) const { return get<int64_t>(idx); }
|
||||
OB_INLINE int32_t get_date(const int64_t idx) const { return get<int32_t>(idx); }
|
||||
OB_INLINE int64_t get_time(const int64_t idx) const { return get<int32_t>(idx); }
|
||||
OB_INLINE uint8_t get_year(const int64_t idx) const { return get<uint8_t>(idx); }
|
||||
OB_INLINE const ObOTimestampData &get_otimestamp_tz(const int64_t idx) const;
|
||||
OB_INLINE ObString get_string(const int64_t idx) const;
|
||||
OB_INLINE int get_enumset_inner(const int64_t idx, ObEnumSetInnerValue &inner_value) const;
|
||||
OB_INLINE ObURowIDData get_urowid(const int64_t idx) const;
|
||||
OB_INLINE const ObLobLocator &get_lob_locator(const int64_t idx) const;
|
||||
OB_INLINE const ObLobCommon &get_lob_data(const int64_t idx) const;
|
||||
|
||||
OB_INLINE const ObDecimalInt *get_decimal_int(const int64_t idx) const;
|
||||
|
||||
// Vector set idx-th value interface
|
||||
OB_INLINE void set_int(const int64_t idx, const int64_t v) { set<int64_t>(idx, v); };
|
||||
OB_INLINE void set_int32(const int64_t idx, const int32_t v) { set<int32_t>(idx, v); }
|
||||
OB_INLINE void set_uint(const int64_t idx, const uint64_t v) { set<uint64_t>(idx, v); }
|
||||
OB_INLINE void set_uint32(const int64_t idx, const uint32_t v) { set<uint32_t>(idx, v); }
|
||||
OB_INLINE void set_bit(const int64_t idx, const uint64_t v) { set<uint64_t>(idx, v); }
|
||||
OB_INLINE void set_bool(const int64_t idx, const bool v) { set_int(idx, static_cast<int64_t>(v)); }
|
||||
OB_INLINE void set_true(const int64_t idx) { set_int(idx, static_cast<int64_t>(true)); }
|
||||
OB_INLINE void set_false(const int64_t idx) { set_int(idx, static_cast<int64_t>(false)); }
|
||||
OB_INLINE void set_float(const int64_t idx, const float v) { set<float>(idx, v); }
|
||||
OB_INLINE void set_double(const int64_t idx, const double v) { set<double>(idx, v); }
|
||||
OB_INLINE void set_enum(const int64_t idx, const uint64_t v) { set<uint64_t>(idx, v); }
|
||||
OB_INLINE void set_set(const int64_t idx, const uint64_t v) { set<uint64_t>(idx, v); }
|
||||
OB_INLINE void set_interval_nmonth(const int64_t idx, const int64_t interval_nmonth);
|
||||
OB_INLINE void set_interval_ym(const int64_t idx, const int64_t interval_nmonth);
|
||||
OB_INLINE void set_interval_ds(const int64_t idx, const ObIntervalDSValue &v);
|
||||
OB_INLINE void set_datetime(const int64_t idx, const int64_t v) { set<int64_t>(idx, v); }
|
||||
OB_INLINE void set_timestamp(const int64_t idx, const int64_t v) { set<int64_t>(idx, v); }
|
||||
OB_INLINE void set_otimestamp_tz(const int64_t idx, const ObOTimestampData &v);
|
||||
OB_INLINE void set_time(const int64_t idx, const int64_t v) { set_int(idx, v); }
|
||||
OB_INLINE void set_otimestamp(const int64_t idx, const ObOTimestampData &v);
|
||||
OB_INLINE void set_date(const int64_t idx, const int32_t v) { set<int32_t>(idx, v); }
|
||||
OB_INLINE void set_year(const int64_t idx, const int8_t v) { set<int8_t>(idx, v); }
|
||||
// OB_INLINE number, deep copy all number digits here.
|
||||
OB_INLINE void set_number(const int64_t idx, const number::ObNumber &num);
|
||||
// OB_INLINE compact number, deep copy all number digits too.
|
||||
OB_INLINE void set_number(const int64_t idx, const number::ObCompactNumber &cnum);
|
||||
OB_INLINE void set_number_shallow(const int64_t idx, const number::ObCompactNumber &cnum);
|
||||
OB_INLINE void set_string(const int64_t idx, const ObString &v);
|
||||
OB_INLINE void set_string(const int64_t idx, const char *ptr, const uint32_t len);
|
||||
OB_INLINE void set_enumset_inner(const int64_t idx, const ObString &v) { set_string(idx, v); }
|
||||
OB_INLINE void set_enumset_inner(const int64_t idx, const char *ptr, const uint32_t len);
|
||||
OB_INLINE void set_urowid(const int64_t idx, const ObURowIDData &urowid_data);
|
||||
OB_INLINE void set_urowid(const int64_t idx, const char *ptr, const int64_t size);
|
||||
OB_INLINE void set_lob_locator(const int64_t idx, const ObLobLocator &value);
|
||||
OB_INLINE void set_lob_data(const int64_t idx, const ObLobCommon &value, int64_t length);
|
||||
|
||||
OB_INLINE void set_decimal_int(const int64_t idx, const ObDecimalInt *decint, int32_t len);
|
||||
|
||||
// append values to this vector from idx-th column of rows
|
||||
virtual int from_rows(const sql::RowMeta &row_meta,
|
||||
const sql::ObCompactRow **stored_rows,
|
||||
@ -260,175 +532,10 @@ public:
|
||||
UNUSED(buf_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Remove const value qualification for pointer.
|
||||
template <typename T>
|
||||
OB_INLINE __attribute__((always_inline)) T *no_cv(const T *ptr) const { return const_cast<T *>(ptr); }
|
||||
|
||||
private:
|
||||
TYPE_CHECKER_DEF(is_native_ctype, bool, int8_t, int16_t, int32_t, int64_t,
|
||||
uint8_t, uint16_t, uint32_t, uint64_t,
|
||||
double, float);
|
||||
|
||||
template <typename T>
|
||||
OB_INLINE T get(const int64_t idx) const {
|
||||
static_assert(is_native_ctype<T>::value, "invalid type");
|
||||
return *(reinterpret_cast<T *>(no_cv(get_payload(idx))));
|
||||
}
|
||||
|
||||
// this interface will deep copy, if need shallow copy,
|
||||
// use other interface
|
||||
template <typename T>
|
||||
OB_INLINE void set(const int64_t idx, const T &value) {
|
||||
static_assert(is_native_ctype<T>::value, "invalid type");
|
||||
set_payload(idx, &value, sizeof(T));
|
||||
}
|
||||
#undef TYPE_CHECKER_DEF
|
||||
DEF_VEC_READ_INTERFACES(ObIVector);
|
||||
DEF_VEC_WRITE_INTERFACES(ObIVector);
|
||||
};
|
||||
|
||||
OB_INLINE const number::ObCompactNumber &ObIVector::get_number(const int64_t idx) const
|
||||
{
|
||||
return *(reinterpret_cast<const number::ObCompactNumber *>(get_payload(idx)));
|
||||
}
|
||||
|
||||
OB_INLINE const ObIntervalDSValue &ObIVector::get_interval_ds(const int64_t idx) const {
|
||||
return *(reinterpret_cast<const ObIntervalDSValue *>(get_payload(idx)));
|
||||
}
|
||||
|
||||
OB_INLINE const ObOTimestampData &ObIVector::get_otimestamp_tz(const int64_t idx) const {
|
||||
return *(reinterpret_cast<const ObOTimestampData *>(get_payload(idx)));
|
||||
}
|
||||
|
||||
OB_INLINE int ObIVector::get_enumset_inner(const int64_t idx, ObEnumSetInnerValue &inner_value) const
|
||||
{
|
||||
int64_t pos = 0;
|
||||
const char *payload = NULL;
|
||||
ObLength len = 0;
|
||||
get_payload(idx, payload, len);
|
||||
return inner_value.deserialize(payload, len, pos);
|
||||
}
|
||||
|
||||
OB_INLINE const ObLobLocator &ObIVector::get_lob_locator(const int64_t idx) const
|
||||
{
|
||||
return *(reinterpret_cast<const ObLobLocator *>(get_payload(idx)));
|
||||
}
|
||||
|
||||
OB_INLINE const ObDecimalInt *ObIVector::get_decimal_int(const int64_t idx) const
|
||||
{
|
||||
return reinterpret_cast<const ObDecimalInt *>(get_payload(idx));
|
||||
}
|
||||
|
||||
OB_INLINE const ObLobCommon &ObIVector::get_lob_data(const int64_t idx) const
|
||||
{
|
||||
return *(reinterpret_cast<const ObLobCommon *>(get_payload(idx)));
|
||||
}
|
||||
|
||||
OB_INLINE ObString ObIVector::get_string(const int64_t idx) const
|
||||
{
|
||||
const char *str = NULL;
|
||||
ObLength len = 0;
|
||||
get_payload(idx, str, len);
|
||||
return ObString(len, str);
|
||||
}
|
||||
|
||||
OB_INLINE ObURowIDData ObIVector::get_urowid(const int64_t idx) const
|
||||
{
|
||||
const char *ptr = NULL;
|
||||
ObLength len = 0;
|
||||
get_payload(idx, ptr, len);
|
||||
return ObURowIDData(len, reinterpret_cast<const uint8_t *>(ptr));
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_interval_nmonth(const int64_t idx, const int64_t v)
|
||||
{
|
||||
set<int64_t>(idx, v);
|
||||
};
|
||||
|
||||
OB_INLINE void ObIVector::set_interval_ym(const int64_t idx, const int64_t v)
|
||||
{
|
||||
set<int64_t>(idx, v);
|
||||
};
|
||||
|
||||
OB_INLINE void ObIVector::set_interval_ds(const int64_t idx, const ObIntervalDSValue &v)
|
||||
{
|
||||
set_payload_shallow(idx, &v, v.get_store_size());
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_otimestamp_tz(const int64_t idx, const ObOTimestampData &v)
|
||||
{
|
||||
*(reinterpret_cast<ObOTimestampData *>(no_cv(get_payload(idx)))) = v;
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_otimestamp(const int64_t idx, const ObOTimestampData &v)
|
||||
{
|
||||
*(reinterpret_cast<ObOTimestampData *>(no_cv(get_payload(idx)))) = v;
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_number(const int64_t idx, const number::ObNumber &num)
|
||||
{
|
||||
using CptNumber = number::ObCompactNumber;
|
||||
CptNumber *cnum = reinterpret_cast<CptNumber *>(no_cv(get_payload(idx)));
|
||||
cnum->desc_ = num.d_;
|
||||
const ObLength len = num.d_.len_ * sizeof(*num.get_digits());
|
||||
MEMCPY(&cnum->digits_[0], num.get_digits(), len);
|
||||
set_payload_shallow(idx, cnum, len + sizeof(ObNumberDesc));
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_number(const int64_t idx, const number::ObCompactNumber &cnum)
|
||||
{
|
||||
ObLength len = static_cast<uint32_t>(sizeof(cnum) + cnum.desc_.len_ * sizeof(cnum.digits_[0]));
|
||||
set_payload(idx, &cnum, len);
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_number_shallow(const int64_t idx, const number::ObCompactNumber &cnum)
|
||||
{
|
||||
ObLength len = static_cast<uint32_t>(sizeof(cnum) + cnum.desc_.len_ * sizeof(cnum.digits_[0]));
|
||||
set_payload_shallow(idx, &cnum, len);
|
||||
};
|
||||
|
||||
OB_INLINE void ObIVector::set_string(const int64_t idx, const ObString &v)
|
||||
{
|
||||
set_payload_shallow(idx, v.ptr(), v.length());
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_string(const int64_t idx, const char *ptr, const uint32_t len)
|
||||
{
|
||||
set_payload_shallow(idx, ptr, len);
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_enumset_inner(const int64_t idx, const char *ptr, const uint32_t len)
|
||||
{
|
||||
set_string(idx, ptr, len);
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_urowid(const int64_t idx, const ObURowIDData &urowid_data)
|
||||
{
|
||||
const char *ptr = reinterpret_cast<const char *>(urowid_data.rowid_content_);
|
||||
ObLength len = static_cast<uint32_t>(urowid_data.rowid_len_);
|
||||
set_payload(idx, ptr, len);
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_urowid(const int64_t idx, const char *ptr, const int64_t size)
|
||||
{
|
||||
set_payload(idx, ptr, static_cast<uint32_t>(size));
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_lob_locator(const int64_t idx, const ObLobLocator &value)
|
||||
{
|
||||
set_payload(idx, &value, static_cast<uint32_t>(value.get_total_size()));
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_lob_data(const int64_t idx, const ObLobCommon &value, int64_t length)
|
||||
{
|
||||
set_payload(idx, &value, static_cast<uint32_t>(length));
|
||||
}
|
||||
|
||||
OB_INLINE void ObIVector::set_decimal_int(const int64_t idx, const ObDecimalInt *decint, int32_t len)
|
||||
{
|
||||
set_payload(idx, decint, static_cast<uint32_t>(len));
|
||||
}
|
||||
|
||||
using IVectorPtrs = common::ObIArray<ObIVector *>;
|
||||
|
||||
}
|
||||
|
@ -108,6 +108,9 @@ public:
|
||||
OB_INLINE int to_row(const sql::RowMeta &row_meta, sql::ObCompactRow *stored_row,
|
||||
const uint64_t row_idx, const int64_t col_idx, const int64_t remain_size,
|
||||
const bool is_fixed_length_data, int64_t &row_size) const override final;
|
||||
|
||||
DEF_VEC_READ_INTERFACES(ObUniformFormat<IS_CONST>);
|
||||
DEF_VEC_WRITE_INTERFACES(ObUniformFormat<IS_CONST>);
|
||||
};
|
||||
|
||||
template<bool IS_CONST>
|
||||
|
@ -30,11 +30,11 @@ struct exist_type<T, First, Rest...> {
|
||||
static const bool value = std::is_same<T, First>::value || exist_type<T, Rest...>::value;
|
||||
};
|
||||
|
||||
#define TYPE_CHECKER_DEF(checker_name, ...) \
|
||||
template <typename T> \
|
||||
struct checker_name { \
|
||||
static constexpr bool value = exist_type<T, ##__VA_ARGS__>::value; \
|
||||
};
|
||||
// #define TYPE_CHECKER_DEF(checker_name, ...) \
|
||||
// template <typename T> \
|
||||
// struct checker_name { \
|
||||
// static constexpr bool value = exist_type<T, ##__VA_ARGS__>::value; \
|
||||
// };
|
||||
|
||||
// define VALUE_CHECK
|
||||
// eg: DEF_CHECK_VALUE(VecValueTypeClass, is_decimal_tc,
|
||||
|
@ -184,11 +184,17 @@ struct VecTCHashCalc<VEC_TC_LOB, HashMethod, hash_v2>
|
||||
const ObLobLocator *lob_locator_v1 = reinterpret_cast<const ObLobLocator *>(data);
|
||||
in_data.assign_ptr(lob_locator_v1->get_payload_ptr(), lob_locator_v1->payload_size_);
|
||||
} else if (loc.is_valid()) {
|
||||
ObTextStringIter text_iter(ObLongTextType, CS_TYPE_BINARY, raw_data, true);
|
||||
if (OB_FAIL(text_iter.init(0, NULL, &allocator))) {
|
||||
COMMON_LOG(WARN, "Lob: str iter init failed ", K(ret), K(text_iter));
|
||||
} else if (OB_FAIL(text_iter.get_full_data(in_data))) {
|
||||
COMMON_LOG(WARN, "Lob: str iter get full data failed ", K(ret), K(text_iter));
|
||||
const ObLobCommon* lob = reinterpret_cast<const ObLobCommon*>(data);
|
||||
// fast path for disk inrow lob
|
||||
if (data_len != 0 && !lob->is_mem_loc_ && lob->in_row_) {
|
||||
in_data.assign_ptr(lob->get_inrow_data_ptr(), static_cast<int32_t>(lob->get_byte_size(data_len)));
|
||||
} else {
|
||||
ObTextStringIter text_iter(ObLongTextType, CS_TYPE_BINARY, raw_data, true);
|
||||
if (OB_FAIL(text_iter.init(0, NULL, &allocator))) {
|
||||
COMMON_LOG(WARN, "Lob: str iter init failed ", K(ret), K(text_iter));
|
||||
} else if (OB_FAIL(text_iter.get_full_data(in_data))) {
|
||||
COMMON_LOG(WARN, "Lob: str iter get full data failed ", K(ret), K(text_iter));
|
||||
}
|
||||
}
|
||||
} else { // not v1 or v2 lob
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
|
@ -5111,6 +5111,8 @@ int ObStaticEngineCG::generate_tsc_flags(ObLogTableScan &op, ObTableScanSpec &sp
|
||||
LOG_WARN("failed to init tenant config", K(tenant_id));
|
||||
} else {
|
||||
const int64_t pd_level = tenant_config->_pushdown_storage_level;
|
||||
const int64_t io_read_batch_size = tenant_config->_io_read_batch_size;
|
||||
const int64_t io_read_gap_size = io_read_batch_size * tenant_config->_io_read_redundant_limit_percentage / 100;
|
||||
pd_blockscan = ObPushdownFilterUtils::is_blockscan_pushdown_enabled(pd_level);
|
||||
pd_filter = ObPushdownFilterUtils::is_filter_pushdown_enabled(pd_level);
|
||||
enable_skip_index = tenant_config->_enable_skip_index;
|
||||
@ -5120,9 +5122,15 @@ int ObStaticEngineCG::generate_tsc_flags(ObLogTableScan &op, ObTableScanSpec &sp
|
||||
ObDASScanCtDef *lookup_ctdef = spec.tsc_ctdef_.lookup_ctdef_;
|
||||
scan_ctdef.pd_expr_spec_.pd_storage_flag_.set_flags(pd_blockscan, pd_filter, enable_skip_index,
|
||||
enable_column_store, enable_prefetch_limit);
|
||||
scan_ctdef.table_scan_opt_.io_read_batch_size_ = io_read_batch_size;
|
||||
scan_ctdef.table_scan_opt_.io_read_gap_size_ = io_read_gap_size;
|
||||
scan_ctdef.table_scan_opt_.storage_rowsets_size_ = tenant_config->storage_rowsets_size;
|
||||
if (nullptr != lookup_ctdef) {
|
||||
lookup_ctdef->pd_expr_spec_.pd_storage_flag_.set_flags(pd_blockscan, pd_filter, enable_skip_index,
|
||||
enable_column_store, enable_prefetch_limit);
|
||||
lookup_ctdef->table_scan_opt_.io_read_batch_size_ = io_read_batch_size;
|
||||
lookup_ctdef->table_scan_opt_.io_read_gap_size_ = io_read_gap_size;
|
||||
lookup_ctdef->table_scan_opt_.storage_rowsets_size_ = tenant_config->storage_rowsets_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -262,6 +262,7 @@ int ObDASScanOp::init_scan_param()
|
||||
scan_param_.limit_param_ = scan_rtdef_->limit_param_;
|
||||
scan_param_.need_scn_ = scan_rtdef_->need_scn_;
|
||||
scan_param_.pd_storage_flag_ = scan_ctdef_->pd_expr_spec_.pd_storage_flag_.pd_flag_;
|
||||
scan_param_.table_scan_opt_ = scan_ctdef_->table_scan_opt_;
|
||||
scan_param_.fb_snapshot_ = scan_rtdef_->fb_snapshot_;
|
||||
scan_param_.fb_read_tx_uncommitted_ = scan_rtdef_->fb_read_tx_uncommitted_;
|
||||
if (scan_rtdef_->is_for_foreign_check_) {
|
||||
@ -1641,6 +1642,7 @@ OB_INLINE int ObLocalIndexLookupOp::init_scan_param()
|
||||
scan_param_.limit_param_ = lookup_rtdef_->limit_param_;
|
||||
scan_param_.need_scn_ = lookup_rtdef_->need_scn_;
|
||||
scan_param_.pd_storage_flag_ = lookup_ctdef_->pd_expr_spec_.pd_storage_flag_.pd_flag_;
|
||||
scan_param_.table_scan_opt_ = lookup_ctdef_->table_scan_opt_;
|
||||
scan_param_.fb_snapshot_ = lookup_rtdef_->fb_snapshot_;
|
||||
scan_param_.fb_read_tx_uncommitted_ = lookup_rtdef_->fb_read_tx_uncommitted_;
|
||||
scan_param_.ls_id_ = ls_id_;
|
||||
|
@ -1379,7 +1379,7 @@ int ObDtlVectorRowMsgWriter::init(ObDtlLinkedBuffer *buffer, uint64_t tenant_id)
|
||||
if (OB_FAIL(ObTempBlockStore::init_block_buffer(buffer->buf(), buffer->size(), blk))) {
|
||||
LOG_WARN("fail to init block buffer", K(ret));
|
||||
} else {
|
||||
block_ = static_cast<ObTempRowStore::RowBlock*>(blk);
|
||||
block_ = static_cast<ObTempRowStore::DtlRowBlock*>(blk);
|
||||
block_buffer_ = block_->get_buffer();
|
||||
write_buffer_ = buffer;
|
||||
}
|
||||
|
@ -344,10 +344,12 @@ public:
|
||||
{
|
||||
buffer->msg_type() = ObDtlMsgType::PX_VECTOR_ROW;
|
||||
}
|
||||
OB_INLINE ObTempRowStore::DtlRowBlock *get_block() { return block_; }
|
||||
OB_INLINE ObDtlLinkedBuffer *get_write_buffer() { return write_buffer_; }
|
||||
private:
|
||||
DtlWriterType type_;
|
||||
ObDtlLinkedBuffer *write_buffer_;
|
||||
ObTempRowStore::RowBlock* block_;
|
||||
ObTempRowStore::DtlRowBlock *block_;
|
||||
ObTempRowStore::ShrinkBuffer *block_buffer_;
|
||||
RowMeta row_meta_;
|
||||
int64_t row_cnt_;
|
||||
|
@ -450,15 +450,31 @@ int ObDtlVectors::append_batch(const ObIArray<ObExpr*> &exprs, const ObIArray<Ob
|
||||
switch (exprs.at(col_idx)->get_format(ctx)) {
|
||||
case VEC_FIXED : {
|
||||
ObFixedLengthBase *fixed_vec = static_cast<ObFixedLengthBase *> (vectors.at(col_idx));
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
int64_t row_idx = selector[i];
|
||||
if (fixed_vec->get_nulls()->at(row_idx)) {
|
||||
get_nulls(col_idx)->set(virtual_row_cnt);
|
||||
} else {
|
||||
memcpy(dst_data + fixed_len * (virtual_row_cnt),
|
||||
fixed_vec->get_data() + fixed_len * row_idx, fixed_len);
|
||||
if (0 == fixed_len % 8) {
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
int64_t row_idx = selector[i];
|
||||
if (fixed_vec->get_nulls()->at(row_idx)) {
|
||||
get_nulls(col_idx)->set(virtual_row_cnt);
|
||||
} else {
|
||||
int64_t base_offset = fixed_len * (virtual_row_cnt);
|
||||
for (int64_t i = 0; i < fixed_len / 8; ++i) {
|
||||
*(reinterpret_cast<int64_t *> (dst_data + sizeof(int64_t) * i + base_offset))
|
||||
= *(reinterpret_cast<int64_t *> (fixed_vec->get_data() + sizeof(int64_t) * i + fixed_len * row_idx));
|
||||
}
|
||||
}
|
||||
++virtual_row_cnt;
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
int64_t row_idx = selector[i];
|
||||
if (fixed_vec->get_nulls()->at(row_idx)) {
|
||||
get_nulls(col_idx)->set(virtual_row_cnt);
|
||||
} else {
|
||||
memcpy(dst_data + fixed_len * (virtual_row_cnt),
|
||||
fixed_vec->get_data() + fixed_len * row_idx, fixed_len);
|
||||
}
|
||||
++virtual_row_cnt;
|
||||
}
|
||||
++virtual_row_cnt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -493,15 +509,32 @@ int ObDtlVectors::append_batch(const ObIArray<ObExpr*> &exprs, const ObIArray<Ob
|
||||
}
|
||||
case VEC_UNIFORM : {
|
||||
ObUniformBase *uniform_vec = static_cast<ObUniformBase *> (vectors.at(col_idx));
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
int64_t row_idx = selector[i];
|
||||
ObDatum &cell = uniform_vec->get_datums()[row_idx];
|
||||
if (cell.is_null()) {
|
||||
get_nulls(col_idx)->set(virtual_row_cnt);
|
||||
} else {
|
||||
memcpy(dst_data + fixed_len * (virtual_row_cnt), cell.ptr_, fixed_len);
|
||||
if (0 == fixed_len % 8) {
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
int64_t row_idx = selector[i];
|
||||
ObDatum &cell = uniform_vec->get_datums()[row_idx];
|
||||
if (cell.is_null()) {
|
||||
get_nulls(col_idx)->set(virtual_row_cnt);
|
||||
} else {
|
||||
int64_t base_offset = fixed_len * (virtual_row_cnt);
|
||||
for (int64_t i = 0; i < fixed_len / 8; ++i) {
|
||||
*(reinterpret_cast<int64_t *> (dst_data + base_offset + sizeof(int64_t) * i))
|
||||
= *(reinterpret_cast<const int64_t *> (cell.ptr_ + sizeof(int64_t) * i));
|
||||
}
|
||||
}
|
||||
++virtual_row_cnt;
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
int64_t row_idx = selector[i];
|
||||
ObDatum &cell = uniform_vec->get_datums()[row_idx];
|
||||
if (cell.is_null()) {
|
||||
get_nulls(col_idx)->set(virtual_row_cnt);
|
||||
} else {
|
||||
memcpy(dst_data + fixed_len * (virtual_row_cnt), cell.ptr_, fixed_len);
|
||||
}
|
||||
++virtual_row_cnt;
|
||||
}
|
||||
++virtual_row_cnt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -182,12 +182,21 @@ int ObExtendHashTableVec<GroupRowBucket>::process_batch(const common::ObIArray<O
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
const int64_t start_idx = 0;
|
||||
int64_t processed_idx = 0;
|
||||
if (OB_FAIL(inner_process_batch(gby_exprs, child_brs, is_dumped,
|
||||
hash_values, lengths, can_append_batch,
|
||||
bloom_filter, batch_old_rows, batch_new_rows,
|
||||
agg_row_cnt, agg_group_cnt, batch_aggr_rows,
|
||||
need_reinit_vectors))) {
|
||||
hash_values, lengths, can_append_batch,
|
||||
bloom_filter, batch_old_rows, batch_new_rows,
|
||||
agg_row_cnt, agg_group_cnt, batch_aggr_rows,
|
||||
need_reinit_vectors, true, start_idx, processed_idx))) {
|
||||
LOG_WARN("failed to process batch", K(ret));
|
||||
} else if (processed_idx < child_brs.size_
|
||||
&& OB_FAIL(inner_process_batch(gby_exprs, child_brs, is_dumped,
|
||||
hash_values, lengths, can_append_batch,
|
||||
bloom_filter, batch_old_rows, batch_new_rows,
|
||||
agg_row_cnt, agg_group_cnt, batch_aggr_rows,
|
||||
need_reinit_vectors, false, processed_idx, processed_idx))) {
|
||||
LOG_WARN("failed to process batch fallback", K(ret));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -222,14 +231,19 @@ int ObExtendHashTableVec<GroupRowBucket>::inner_process_batch(const common::ObIA
|
||||
int64_t &agg_row_cnt,
|
||||
int64_t &agg_group_cnt,
|
||||
BatchAggrRowsTable *batch_aggr_rows,
|
||||
bool need_reinit_vectors)
|
||||
bool need_reinit_vectors,
|
||||
const bool probe_by_col,
|
||||
const int64_t start_idx,
|
||||
int64_t &processed_idx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t curr_idx = 0;
|
||||
while (OB_SUCC(ret) && curr_idx < child_brs.size_) {
|
||||
int64_t curr_idx = start_idx;
|
||||
bool need_fallback = false;
|
||||
while (OB_SUCC(ret) && !need_fallback && curr_idx < child_brs.size_) {
|
||||
bool batch_duplicate = false;
|
||||
new_row_selector_cnt_ = 0;
|
||||
for (; OB_SUCC(ret) && !batch_duplicate && curr_idx < child_brs.size_; ++curr_idx) {
|
||||
old_row_selector_cnt_ = 0;
|
||||
for (; OB_SUCC(ret) && curr_idx < child_brs.size_; ++curr_idx) {
|
||||
if (child_brs.skip_->at(curr_idx)
|
||||
|| is_dumped[curr_idx]
|
||||
|| (nullptr != bloom_filter
|
||||
@ -241,53 +255,60 @@ int ObExtendHashTableVec<GroupRowBucket>::inner_process_batch(const common::ObIA
|
||||
while (OB_SUCC(ret) && !find_bkt) {
|
||||
locate_buckets_[curr_idx] = const_cast<GroupRowBucket *> (&locate_next_bucket(*buckets_, hash_values[curr_idx], curr_pos));
|
||||
if (locate_buckets_[curr_idx]->is_valid()) {
|
||||
++probe_cnt_;
|
||||
++agg_row_cnt;
|
||||
bool result = true;
|
||||
ObGroupRowItemVec *it = &locate_buckets_[curr_idx]->get_item();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && result && i < gby_exprs.count(); ++i) {
|
||||
bool null_equal = (nullptr == gby_exprs.at(i));
|
||||
if (!null_equal) {
|
||||
ObIVector *r_vec = gby_exprs.at(i)->get_vector(*eval_ctx_);
|
||||
const bool l_isnull = it->is_null(i);
|
||||
const bool r_isnull = r_vec->is_null(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
result = false;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
result = true;
|
||||
} else {
|
||||
const int64_t l_len = it->get_length(group_store_.get_row_meta(), i);
|
||||
const int64_t r_len = r_vec->get_length(curr_idx);
|
||||
if (l_len == r_len
|
||||
&& 0 == memcmp(it->get_cell_payload(group_store_.get_row_meta(), i),
|
||||
r_vec->get_payload(curr_idx),
|
||||
r_len)) {
|
||||
if (probe_by_col) {
|
||||
old_row_selector_.at(old_row_selector_cnt_++) = curr_idx;
|
||||
__builtin_prefetch(&locate_buckets_[curr_idx]->get_item(),
|
||||
0, 2);
|
||||
find_bkt = true;
|
||||
} else {
|
||||
bool result = true;
|
||||
ObGroupRowItemVec *it = &locate_buckets_[curr_idx]->get_item();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && result && i < gby_exprs.count(); ++i) {
|
||||
bool null_equal = (nullptr == gby_exprs.at(i));
|
||||
if (!null_equal) {
|
||||
ObIVector *r_vec = gby_exprs.at(i)->get_vector(*eval_ctx_);
|
||||
const bool l_isnull = it->is_null(i);
|
||||
const bool r_isnull = r_vec->is_null(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
result = false;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
result = true;
|
||||
} else {
|
||||
int cmp_res = 0;
|
||||
if (OB_FAIL(r_vec->null_last_cmp(*gby_exprs.at(i), curr_idx, false,
|
||||
it->get_cell_payload(group_store_.get_row_meta(), i),
|
||||
l_len, cmp_res))) {
|
||||
LOG_WARN("failed to cmp left and right", K(ret));
|
||||
const int64_t l_len = it->get_length(group_store_.get_row_meta(), i);
|
||||
const int64_t r_len = r_vec->get_length(curr_idx);
|
||||
if (l_len == r_len
|
||||
&& 0 == memcmp(it->get_cell_payload(group_store_.get_row_meta(), i),
|
||||
r_vec->get_payload(curr_idx),
|
||||
r_len)) {
|
||||
result = true;
|
||||
} else {
|
||||
result = (0 == cmp_res);
|
||||
int cmp_res = 0;
|
||||
if (OB_FAIL(r_vec->null_last_cmp(*gby_exprs.at(i), curr_idx, false,
|
||||
it->get_cell_payload(group_store_.get_row_meta(), i),
|
||||
l_len, cmp_res))) {
|
||||
LOG_WARN("failed to cmp left and right", K(ret));
|
||||
} else {
|
||||
result = (0 == cmp_res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && result) {
|
||||
batch_old_rows[curr_idx] = it->get_aggr_row(group_store_.get_row_meta());
|
||||
if (batch_aggr_rows && batch_aggr_rows->is_valid()) {
|
||||
if (size_ > BatchAggrRowsTable::MAX_REORDER_GROUPS) {
|
||||
batch_aggr_rows->set_invalid();
|
||||
} else {
|
||||
int64_t ser_num = locate_buckets_[curr_idx]->get_bkt_seq();
|
||||
batch_aggr_rows->aggr_rows_[ser_num] = batch_old_rows[curr_idx];
|
||||
batch_aggr_rows->selectors_[ser_num][batch_aggr_rows->selectors_item_cnt_[ser_num]++] = curr_idx;
|
||||
if (OB_SUCC(ret) && result) {
|
||||
++probe_cnt_;
|
||||
++agg_row_cnt;
|
||||
batch_old_rows[curr_idx] = it->get_aggr_row(group_store_.get_row_meta());
|
||||
if (batch_aggr_rows && batch_aggr_rows->is_valid()) {
|
||||
if (size_ > BatchAggrRowsTable::MAX_REORDER_GROUPS) {
|
||||
batch_aggr_rows->set_invalid();
|
||||
} else {
|
||||
int64_t ser_num = locate_buckets_[curr_idx]->get_bkt_seq();
|
||||
batch_aggr_rows->aggr_rows_[ser_num] = batch_old_rows[curr_idx];
|
||||
batch_aggr_rows->selectors_[ser_num][batch_aggr_rows->selectors_item_cnt_[ser_num]++] = curr_idx;
|
||||
}
|
||||
}
|
||||
find_bkt = true;
|
||||
}
|
||||
find_bkt = true;
|
||||
}
|
||||
} else if (locate_buckets_[curr_idx]->is_occupyed()) {
|
||||
batch_duplicate = true;
|
||||
@ -307,6 +328,48 @@ int ObExtendHashTableVec<GroupRowBucket>::inner_process_batch(const common::ObIA
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)
|
||||
&& probe_by_col
|
||||
&& old_row_selector_cnt_ > 0) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !need_fallback && i < gby_exprs.count(); ++i) {
|
||||
if (nullptr == gby_exprs.at(i)) {
|
||||
//3 stage null equal
|
||||
continue;
|
||||
}
|
||||
col_has_null_.at(i) |= gby_exprs.at(i)->get_vector(*eval_ctx_)->has_null();
|
||||
if (OB_FAIL(col_has_null_.at(i) ?
|
||||
inner_process_column(gby_exprs, group_store_.get_row_meta(), i, need_fallback)
|
||||
: inner_process_column_not_null(gby_exprs, group_store_.get_row_meta(), i, need_fallback))) {
|
||||
LOG_WARN("failed to process column", K(ret), K(i));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (!need_fallback) {
|
||||
probe_cnt_ += old_row_selector_cnt_;
|
||||
agg_row_cnt += old_row_selector_cnt_;
|
||||
if (batch_aggr_rows && batch_aggr_rows->is_valid() && size_ > BatchAggrRowsTable::MAX_REORDER_GROUPS) {
|
||||
batch_aggr_rows->set_invalid();
|
||||
}
|
||||
for (int64_t i = 0; i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t idx = old_row_selector_.at(i);
|
||||
batch_old_rows[idx] = (static_cast<GroupRowBucket *> (locate_buckets_[idx]))->get_item().get_aggr_row(group_store_.get_row_meta());
|
||||
if (batch_aggr_rows && batch_aggr_rows->is_valid()) {
|
||||
int64_t ser_num = locate_buckets_[idx]->get_bkt_seq();
|
||||
batch_aggr_rows->aggr_rows_[ser_num] = batch_old_rows[idx];
|
||||
batch_aggr_rows->selectors_[ser_num][batch_aggr_rows->selectors_item_cnt_[ser_num]++] = idx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//reset occupyed bkt and stat
|
||||
for (int64_t i = 0; i < new_row_selector_cnt_; ++i) {
|
||||
locate_buckets_[new_row_selector_.at(i)]->set_empty();
|
||||
}
|
||||
probe_cnt_ -= new_row_selector_cnt_;
|
||||
agg_row_cnt -= new_row_selector_cnt_;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (can_append_batch
|
||||
&& new_row_selector_cnt_ > 0
|
||||
@ -318,6 +381,236 @@ int ObExtendHashTableVec<GroupRowBucket>::inner_process_batch(const common::ObIA
|
||||
new_row_selector_cnt_ = 0;
|
||||
}
|
||||
}
|
||||
processed_idx = curr_idx;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename GroupRowBucket>
|
||||
int ObExtendHashTableVec<GroupRowBucket>::inner_process_column(const common::ObIArray<ObExpr *> &gby_exprs,
|
||||
const RowMeta &row_meta,
|
||||
const int64_t col_idx,
|
||||
bool &need_fallback)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
switch (gby_exprs.at(col_idx)->get_format(*eval_ctx_)) {
|
||||
case VEC_FIXED : {
|
||||
ObFixedLengthBase *r_vec = static_cast<ObFixedLengthBase *> (gby_exprs.at(col_idx)->get_vector(*eval_ctx_));
|
||||
int64_t r_len = r_vec->get_length();
|
||||
if (row_meta.fixed_expr_reordered()) {
|
||||
const int64_t offset = row_meta.get_fixed_cell_offset(col_idx);
|
||||
if (r_len == 8) {
|
||||
for (int64_t i = 0; !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
const bool l_isnull = it->is_null(col_idx);
|
||||
const bool r_isnull = r_vec->get_nulls()->at(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
need_fallback = true;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
} else {
|
||||
need_fallback = (*(reinterpret_cast<int64_t *> (r_vec->get_data() + r_len * curr_idx))
|
||||
!= *(reinterpret_cast<const int64_t *> (it->get_fixed_cell_payload(offset))));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
const bool l_isnull = it->is_null(col_idx);
|
||||
const bool r_isnull = r_vec->get_nulls()->at(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
need_fallback = true;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
} else {
|
||||
need_fallback = (0 != memcmp(it->get_fixed_cell_payload(offset),
|
||||
r_vec->get_data() + r_len * curr_idx,
|
||||
r_len));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
const bool l_isnull = it->is_null(col_idx);
|
||||
const bool r_isnull = r_vec->get_nulls()->at(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
need_fallback = true;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
} else {
|
||||
need_fallback = (0 != memcmp(it->get_cell_payload(row_meta, col_idx),
|
||||
r_vec->get_data() + r_len * curr_idx,
|
||||
r_len));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VEC_DISCRETE : {
|
||||
ObDiscreteBase *r_vec = static_cast<ObDiscreteBase *> (gby_exprs.at(col_idx)->get_vector(*eval_ctx_));
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
const bool l_isnull = it->is_null(col_idx);
|
||||
const bool r_isnull = r_vec->get_nulls()->at(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
need_fallback = true;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
} else {
|
||||
const int64_t r_len = r_vec->get_lens()[curr_idx];
|
||||
const int64_t l_len = it->get_length(row_meta, col_idx);
|
||||
if (r_len == l_len
|
||||
&& 0 == memcmp(it->get_cell_payload(row_meta, col_idx),
|
||||
r_vec->get_ptrs()[curr_idx],
|
||||
r_len)) {
|
||||
} else {
|
||||
int cmp_res = 0;
|
||||
if (OB_FAIL(r_vec->null_last_cmp(*gby_exprs.at(col_idx), curr_idx, false,
|
||||
it->get_cell_payload(row_meta, col_idx),
|
||||
l_len, cmp_res))) {
|
||||
LOG_WARN("failed to cmp left and right", K(ret));
|
||||
} else {
|
||||
need_fallback = static_cast<bool> (cmp_res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VEC_CONTINUOUS :
|
||||
case VEC_UNIFORM :
|
||||
case VEC_UNIFORM_CONST : {
|
||||
ObIVector *r_vec = gby_exprs.at(col_idx)->get_vector(*eval_ctx_);
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
const bool l_isnull = it->is_null(col_idx);
|
||||
const bool r_isnull = r_vec->is_null(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
need_fallback = true;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
} else {
|
||||
const int64_t l_len = it->get_length(row_meta, col_idx);
|
||||
const int64_t r_len = r_vec->get_length(curr_idx);
|
||||
if (l_len == r_len
|
||||
&& 0 == memcmp(it->get_cell_payload(row_meta, col_idx),
|
||||
r_vec->get_payload(curr_idx),
|
||||
r_len)) {
|
||||
} else {
|
||||
int cmp_res = 0;
|
||||
if (OB_FAIL(r_vec->null_last_cmp(*gby_exprs.at(col_idx), curr_idx, false,
|
||||
it->get_cell_payload(row_meta, col_idx),
|
||||
l_len, cmp_res))) {
|
||||
LOG_WARN("failed to cmp left and right", K(ret));
|
||||
} else {
|
||||
need_fallback = static_cast<bool> (cmp_res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default :
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid data format", K(ret), K(gby_exprs.at(col_idx)->get_format(*eval_ctx_)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename GroupRowBucket>
|
||||
int ObExtendHashTableVec<GroupRowBucket>::inner_process_column_not_null(const common::ObIArray<ObExpr *> &gby_exprs,
|
||||
const RowMeta &row_meta,
|
||||
const int64_t col_idx,
|
||||
bool &need_fallback)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
switch (gby_exprs.at(col_idx)->get_format(*eval_ctx_)) {
|
||||
case VEC_FIXED : {
|
||||
ObFixedLengthBase *r_vec = static_cast<ObFixedLengthBase *> (gby_exprs.at(col_idx)->get_vector(*eval_ctx_));
|
||||
int64_t r_len = r_vec->get_length();
|
||||
if (row_meta.fixed_expr_reordered()) {
|
||||
const int64_t offset = row_meta.get_fixed_cell_offset(col_idx);
|
||||
if (r_len == 8) {
|
||||
for (int64_t i = 0; !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
need_fallback = (*(reinterpret_cast<int64_t *> (r_vec->get_data() + r_len * curr_idx))
|
||||
!= *(reinterpret_cast<const int64_t *> (it->get_fixed_cell_payload(offset))));
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
need_fallback = (0 != memcmp(it->get_fixed_cell_payload(offset),
|
||||
r_vec->get_data() + r_len * curr_idx,
|
||||
r_len));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
need_fallback = (0 != memcmp(it->get_cell_payload(row_meta, col_idx),
|
||||
r_vec->get_data() + r_len * curr_idx,
|
||||
r_len));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VEC_DISCRETE : {
|
||||
ObDiscreteBase *r_vec = static_cast<ObDiscreteBase *> (gby_exprs.at(col_idx)->get_vector(*eval_ctx_));
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
const int64_t r_len = r_vec->get_lens()[curr_idx];
|
||||
const int64_t l_len = it->get_length(row_meta, col_idx);
|
||||
if (r_len == l_len
|
||||
&& 0 == memcmp(it->get_cell_payload(row_meta, col_idx),
|
||||
r_vec->get_ptrs()[curr_idx],
|
||||
r_len)) {
|
||||
} else {
|
||||
int cmp_res = 0;
|
||||
if (OB_FAIL(r_vec->null_last_cmp(*gby_exprs.at(col_idx), curr_idx, false,
|
||||
it->get_cell_payload(row_meta, col_idx),
|
||||
l_len, cmp_res))) {
|
||||
LOG_WARN("failed to cmp left and right", K(ret));
|
||||
} else {
|
||||
need_fallback = static_cast<bool> (cmp_res);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VEC_CONTINUOUS :
|
||||
case VEC_UNIFORM :
|
||||
case VEC_UNIFORM_CONST : {
|
||||
ObIVector *r_vec = gby_exprs.at(col_idx)->get_vector(*eval_ctx_);
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !need_fallback && i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t curr_idx = old_row_selector_.at(i);
|
||||
ObCompactRow *it = static_cast<ObCompactRow *> (&locate_buckets_[curr_idx]->get_item());
|
||||
const int64_t l_len = it->get_length(row_meta, col_idx);
|
||||
const int64_t r_len = r_vec->get_length(curr_idx);
|
||||
if (l_len == r_len
|
||||
&& 0 == memcmp(it->get_cell_payload(row_meta, col_idx),
|
||||
r_vec->get_payload(curr_idx),
|
||||
r_len)) {
|
||||
} else {
|
||||
int cmp_res = 0;
|
||||
if (OB_FAIL(r_vec->null_last_cmp(*gby_exprs.at(col_idx), curr_idx, false,
|
||||
it->get_cell_payload(row_meta, col_idx),
|
||||
l_len, cmp_res))) {
|
||||
LOG_WARN("failed to cmp left and right", K(ret));
|
||||
} else {
|
||||
need_fallback = static_cast<bool> (cmp_res);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default :
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid data format", K(ret), K(gby_exprs.at(col_idx)->get_format(*eval_ctx_)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -352,6 +645,8 @@ int ObExtendHashTableVec<GroupRowBucket>::init(ObIAllocator *allocator,
|
||||
op_id_ = op_id;
|
||||
vector_ptrs_.set_allocator(allocator);
|
||||
new_row_selector_.set_allocator(allocator);
|
||||
old_row_selector_.set_allocator(allocator);
|
||||
col_has_null_.set_allocator(allocator);
|
||||
change_valid_idx_.set_allocator(allocator);
|
||||
if (use_sstr_aggr && OB_FAIL(sstr_aggr_.init(allocator_, *eval_ctx, gby_exprs, aggr_row_size))) {
|
||||
LOG_WARN("failed to init short string aggr", K(ret));
|
||||
@ -359,10 +654,15 @@ int ObExtendHashTableVec<GroupRowBucket>::init(ObIAllocator *allocator,
|
||||
SQL_ENG_LOG(WARN, "failed to alloc ptrs", K(ret));
|
||||
} else if (OB_FAIL(new_row_selector_.prepare_allocate(max_batch_size))) {
|
||||
SQL_ENG_LOG(WARN, "failed to alloc array", K(ret));
|
||||
} else if (OB_FAIL(old_row_selector_.prepare_allocate(max_batch_size))) {
|
||||
SQL_ENG_LOG(WARN, "failed to alloc array", K(ret));
|
||||
} else if (OB_FAIL(col_has_null_.prepare_allocate(gby_exprs.count()))) {
|
||||
SQL_ENG_LOG(WARN, "failed to alloc array", K(ret));
|
||||
} else if (OB_ISNULL(buckets_buf = allocator_.alloc(sizeof(BucketArray), mem_attr))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
SQL_ENG_LOG(WARN, "failed to allocate memory", K(ret));
|
||||
} else {
|
||||
MEMSET(&col_has_null_.at(0), 0, col_has_null_.count());
|
||||
buckets_ = new(buckets_buf)BucketArray(allocator_);
|
||||
buckets_->set_tenant_id(tenant_id_);
|
||||
initial_bucket_num_ = common::next_pow2(initial_size * SIZE_BUCKET_SCALE);
|
||||
@ -423,56 +723,17 @@ int ObExtendHashTableVec<GroupRowBucket>::set_distinct_batch(const RowMeta &row_
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
int64_t curr_idx = 0;
|
||||
while (OB_SUCC(ret) && curr_idx < batch_size) {
|
||||
bool batch_duplicate = false;
|
||||
new_row_selector_cnt_ = 0;
|
||||
for (; OB_SUCC(ret) && !batch_duplicate && curr_idx < batch_size; ++curr_idx) {
|
||||
if (OB_NOT_NULL(child_skip) && child_skip->at(curr_idx)) {
|
||||
my_skip.set(curr_idx);
|
||||
continue;
|
||||
}
|
||||
int64_t curr_pos = -1;
|
||||
bool find_bkt = false;
|
||||
while (OB_SUCC(ret) && !find_bkt) {
|
||||
locate_buckets_[curr_idx] = const_cast<GroupRowBucket *> (&locate_next_bucket(*buckets_, hash_values[curr_idx], curr_pos));
|
||||
if (locate_buckets_[curr_idx]->is_valid()) {
|
||||
bool result = false;
|
||||
RowItemType *it = &(locate_buckets_[curr_idx]->get_item());
|
||||
if (OB_FAIL(likely_equal_nullable(row_meta, static_cast<ObCompactRow&>(*it), curr_idx, result))) {
|
||||
LOG_WARN("failed to cmp", K(ret));
|
||||
} else if (result) {
|
||||
my_skip.set(curr_idx);
|
||||
find_bkt = true;
|
||||
break;
|
||||
}
|
||||
} else if (locate_buckets_[curr_idx]->is_occupyed()) {
|
||||
batch_duplicate = true;
|
||||
find_bkt = true;
|
||||
} else {
|
||||
//occupy empty bucket
|
||||
locate_buckets_[curr_idx]->set_occupyed();
|
||||
new_row_selector_.at(new_row_selector_cnt_++) = curr_idx;
|
||||
find_bkt = true;
|
||||
}
|
||||
}
|
||||
if (batch_duplicate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret) || 0 == new_row_selector_cnt_) {
|
||||
} else if (OB_FAIL(sf(vector_ptrs_, &new_row_selector_.at(0), new_row_selector_cnt_, srows_))) {
|
||||
LOG_WARN("failed to append batch", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; i < new_row_selector_cnt_; ++i) {
|
||||
int64_t idx = new_row_selector_.at(i);
|
||||
locate_buckets_[idx]->set_hash(hash_values[idx]);
|
||||
locate_buckets_[idx]->set_valid();
|
||||
locate_buckets_[idx]->set_item(static_cast<RowItemType&> (*srows_[i]));
|
||||
++size_;
|
||||
}
|
||||
new_row_selector_cnt_ = 0;
|
||||
}
|
||||
const int64_t start_idx = 0;
|
||||
int64_t processed_idx = 0;
|
||||
if (OB_FAIL(inner_process_batch(row_meta, batch_size, child_skip,
|
||||
my_skip, hash_values, sf,
|
||||
true, start_idx, processed_idx))) {
|
||||
LOG_WARN("failed to process batch", K(ret));
|
||||
} else if (processed_idx < batch_size
|
||||
&& OB_FAIL(inner_process_batch(row_meta, batch_size, child_skip,
|
||||
my_skip, hash_values, sf,
|
||||
false, processed_idx, processed_idx))) {
|
||||
LOG_WARN("failed to process batch fallback", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -484,14 +745,19 @@ int ObExtendHashTableVec<GroupRowBucket>::inner_process_batch(const RowMeta &row
|
||||
const ObBitVector *child_skip,
|
||||
ObBitVector &my_skip,
|
||||
uint64_t *hash_values,
|
||||
StoreRowFunc sf)
|
||||
StoreRowFunc sf,
|
||||
const bool probe_by_col,
|
||||
const int64_t start_idx,
|
||||
int64_t &processed_idx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t curr_idx = 0;
|
||||
while (OB_SUCC(ret) && curr_idx < batch_size) {
|
||||
int64_t curr_idx = start_idx;
|
||||
bool need_fallback = false;
|
||||
while (OB_SUCC(ret) && !need_fallback && curr_idx < batch_size) {
|
||||
bool batch_duplicate = false;
|
||||
new_row_selector_cnt_ = 0;
|
||||
for (; OB_SUCC(ret) && !batch_duplicate && curr_idx < batch_size; ++curr_idx) {
|
||||
old_row_selector_cnt_ = 0;
|
||||
for (; OB_SUCC(ret) && curr_idx < batch_size; ++curr_idx) {
|
||||
if (OB_NOT_NULL(child_skip) && child_skip->at(curr_idx)) {
|
||||
my_skip.set(curr_idx);
|
||||
continue;
|
||||
@ -501,38 +767,45 @@ int ObExtendHashTableVec<GroupRowBucket>::inner_process_batch(const RowMeta &row
|
||||
while (OB_SUCC(ret) && !find_bkt) {
|
||||
locate_buckets_[curr_idx] = const_cast<GroupRowBucket *> (&locate_next_bucket(*buckets_, hash_values[curr_idx], curr_pos));
|
||||
if (locate_buckets_[curr_idx]->is_valid()) {
|
||||
bool result = true;
|
||||
RowItemType *it = &locate_buckets_[curr_idx]->get_item();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && result && i < hash_expr_cnt_; ++i) {
|
||||
ObIVector *r_vec = gby_exprs_->at(i)->get_vector(*eval_ctx_);
|
||||
const bool l_isnull = it->is_null(i);
|
||||
const bool r_isnull = r_vec->is_null(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
result = false;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
result = true;
|
||||
} else {
|
||||
const int64_t l_len = it->get_length(row_meta, i);
|
||||
const int64_t r_len = r_vec->get_length(curr_idx);
|
||||
if (l_len == r_len && (0 == memcmp(it->get_cell_payload(row_meta, i),
|
||||
r_vec->get_payload(curr_idx),
|
||||
l_len))) {
|
||||
if (probe_by_col) {
|
||||
old_row_selector_.at(old_row_selector_cnt_++) = curr_idx;
|
||||
__builtin_prefetch(&locate_buckets_[curr_idx]->get_item(),
|
||||
0, 2);
|
||||
find_bkt = true;
|
||||
} else {
|
||||
bool result = true;
|
||||
RowItemType *it = &locate_buckets_[curr_idx]->get_item();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && result && i < hash_expr_cnt_; ++i) {
|
||||
ObIVector *r_vec = gby_exprs_->at(i)->get_vector(*eval_ctx_);
|
||||
const bool l_isnull = it->is_null(i);
|
||||
const bool r_isnull = r_vec->is_null(curr_idx);
|
||||
if (l_isnull != r_isnull) {
|
||||
result = false;
|
||||
} else if (l_isnull && r_isnull) {
|
||||
result = true;
|
||||
} else {
|
||||
int cmp_res = 0;
|
||||
if (OB_FAIL(r_vec->null_last_cmp(*gby_exprs_->at(i), curr_idx, false,
|
||||
it->get_cell_payload(row_meta, i),
|
||||
l_len, cmp_res))) {
|
||||
LOG_WARN("failed to cmp left and right", K(ret));
|
||||
const int64_t l_len = it->get_length(row_meta, i);
|
||||
const int64_t r_len = r_vec->get_length(curr_idx);
|
||||
if (l_len == r_len && (0 == memcmp(it->get_cell_payload(row_meta, i),
|
||||
r_vec->get_payload(curr_idx),
|
||||
l_len))) {
|
||||
result = true;
|
||||
} else {
|
||||
result = (0 == cmp_res);
|
||||
int cmp_res = 0;
|
||||
if (OB_FAIL(r_vec->null_last_cmp(*gby_exprs_->at(i), curr_idx, false,
|
||||
it->get_cell_payload(row_meta, i),
|
||||
l_len, cmp_res))) {
|
||||
LOG_WARN("failed to cmp left and right", K(ret));
|
||||
} else {
|
||||
result = (0 == cmp_res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && result) {
|
||||
my_skip.set(curr_idx);
|
||||
find_bkt = true;
|
||||
if (OB_SUCC(ret) && result) {
|
||||
my_skip.set(curr_idx);
|
||||
find_bkt = true;
|
||||
}
|
||||
}
|
||||
} else if (locate_buckets_[curr_idx]->is_occupyed()) {
|
||||
batch_duplicate = true;
|
||||
@ -548,6 +821,32 @@ int ObExtendHashTableVec<GroupRowBucket>::inner_process_batch(const RowMeta &row
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)
|
||||
&& probe_by_col
|
||||
&& old_row_selector_cnt_ > 0) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !need_fallback && i < hash_expr_cnt_; ++i) {
|
||||
col_has_null_.at(i) |= gby_exprs_->at(i)->get_vector(*eval_ctx_)->has_null();
|
||||
if (col_has_null_.at(i) ?
|
||||
OB_FAIL(inner_process_column(*gby_exprs_, row_meta, i, need_fallback))
|
||||
: OB_FAIL(inner_process_column_not_null(*gby_exprs_, row_meta, i, need_fallback))) {
|
||||
LOG_WARN("failed to process column", K(ret), K(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (!need_fallback) {
|
||||
for (int64_t i = 0; i < old_row_selector_cnt_; ++i) {
|
||||
const int64_t idx = old_row_selector_.at(i);
|
||||
my_skip.set(idx);
|
||||
}
|
||||
} else {
|
||||
//reset occupyed bkt and stat
|
||||
for (int64_t i = 0; i < new_row_selector_cnt_; ++i) {
|
||||
locate_buckets_[new_row_selector_.at(i)]->set_empty();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret) || 0 == new_row_selector_cnt_) {
|
||||
} else if (OB_FAIL(sf(vector_ptrs_, &new_row_selector_.at(0), new_row_selector_cnt_, srows_))) {
|
||||
LOG_WARN("failed to append batch", K(ret));
|
||||
@ -561,6 +860,7 @@ int ObExtendHashTableVec<GroupRowBucket>::inner_process_batch(const RowMeta &row
|
||||
}
|
||||
new_row_selector_cnt_ = 0;
|
||||
}
|
||||
processed_idx = curr_idx;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -622,15 +922,6 @@ void ObExtendHashTableVec<GroupRowBucket>::prefetch(const ObBatchRows &brs, uint
|
||||
__builtin_prefetch((&buckets_->at((ObGroupRowBucketBase::HASH_VAL_MASK & hash_vals[i]) & mask)),
|
||||
0/* read */, 2 /*high temp locality*/);
|
||||
}
|
||||
if (ObGroupRowBucketType::OUTLINE == GroupRowBucket::TYPE) {
|
||||
for(auto i = 0; i < brs.size_; i++) {
|
||||
if (brs.skip_->at(i)) {
|
||||
continue;
|
||||
}
|
||||
__builtin_prefetch(&buckets_->at((ObGroupRowBucketBase::HASH_VAL_MASK & hash_vals[i]) & mask).get_item(),
|
||||
0, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,7 +548,10 @@ public:
|
||||
max_batch_size_(0),
|
||||
locate_buckets_(nullptr),
|
||||
new_row_selector_(),
|
||||
old_row_selector_(),
|
||||
col_has_null_(),
|
||||
new_row_selector_cnt_(0),
|
||||
old_row_selector_cnt_(),
|
||||
change_valid_idx_(),
|
||||
change_valid_idx_cnt_(0),
|
||||
srows_(nullptr),
|
||||
@ -706,7 +709,27 @@ public:
|
||||
int64_t &agg_row_cnt,
|
||||
int64_t &agg_group_cnt,
|
||||
BatchAggrRowsTable *batch_aggr_rows,
|
||||
bool need_reinit_vectors);
|
||||
bool need_reinit_vectors,
|
||||
const bool probe_by_col,
|
||||
const int64_t start_idx,
|
||||
int64_t &processed_idx);
|
||||
int inner_process_batch(const RowMeta &row_meta,
|
||||
const int64_t batch_size,
|
||||
const ObBitVector *child_skip,
|
||||
ObBitVector &my_skip,
|
||||
uint64_t *hash_values,
|
||||
StoreRowFunc sf,
|
||||
const bool probe_by_col,
|
||||
const int64_t start_idx,
|
||||
int64_t &processed_idx);
|
||||
int inner_process_column(const common::ObIArray<ObExpr *> &gby_exprs,
|
||||
const RowMeta &row_meta,
|
||||
const int64_t col_idx,
|
||||
bool &need_fallback);
|
||||
int inner_process_column_not_null(const common::ObIArray<ObExpr *> &gby_exprs,
|
||||
const RowMeta &row_meta,
|
||||
const int64_t col_idx,
|
||||
bool &need_fallback);
|
||||
void prefetch(const ObBatchRows &brs, uint64_t *hash_vals) const;
|
||||
// Link item to hash table, extend buckets if needed.
|
||||
// (Do not check item is exist or not)
|
||||
@ -751,6 +774,9 @@ public:
|
||||
SQL_ENG_LOG(ERROR, "resize bucket array failed", K(size_), K(bucket_num), K(get_bucket_num()));
|
||||
}
|
||||
}
|
||||
if (col_has_null_.count() > 0) {
|
||||
MEMSET(&col_has_null_.at(0), 0, col_has_null_.count());
|
||||
}
|
||||
size_ = 0;
|
||||
group_store_.reset();
|
||||
iter_.reset();
|
||||
@ -781,6 +807,8 @@ public:
|
||||
sstr_aggr_.destroy();
|
||||
vector_ptrs_.destroy();
|
||||
new_row_selector_.destroy();
|
||||
old_row_selector_.destroy();
|
||||
col_has_null_.destroy();
|
||||
change_valid_idx_.destroy();
|
||||
size_ = 0;
|
||||
initial_bucket_num_ = 0;
|
||||
@ -907,7 +935,10 @@ protected:
|
||||
int64_t max_batch_size_;
|
||||
GroupRowBucket **locate_buckets_;
|
||||
common::ObFixedArray<uint16_t, common::ObIAllocator> new_row_selector_;
|
||||
common::ObFixedArray<uint16_t, common::ObIAllocator> old_row_selector_;
|
||||
common::ObFixedArray<bool, common::ObIAllocator> col_has_null_;
|
||||
int64_t new_row_selector_cnt_;
|
||||
int64_t old_row_selector_cnt_;
|
||||
common::ObFixedArray<uint16_t, common::ObIAllocator> change_valid_idx_;
|
||||
int64_t change_valid_idx_cnt_;
|
||||
ObCompactRow **srows_;
|
||||
|
@ -445,10 +445,10 @@ int ObHashGroupByVecOp::next_duplicate_data_permutation(
|
||||
const int64_t aggr_code = last_group ? MY_SPEC.dist_col_group_idxs_.count() : nth_group;
|
||||
ObExpr *aggr_code_expr = all_groupby_exprs_.at(first_idx - 1);
|
||||
ObIVector *aggr_code_col = nullptr;
|
||||
if (OB_FAIL(aggr_code_expr->init_vector_default(eval_ctx_, MY_SPEC.max_batch_size_))) {
|
||||
if (OB_FAIL(aggr_code_expr->init_vector(eval_ctx_, VEC_FIXED, MY_SPEC.max_batch_size_))) {
|
||||
LOG_WARN("failed to init vector", K(ret));
|
||||
} else {
|
||||
aggr_code_col = aggr_code_expr->get_vector(eval_ctx_);
|
||||
ObFixedLengthFormat<int64_t> *aggr_code_col = static_cast<ObFixedLengthFormat<int64_t> *> (aggr_code_expr->get_vector(eval_ctx_));
|
||||
ObBitVector &eval_flags = aggr_code_expr->get_evaluated_flags(eval_ctx_);
|
||||
for (int64_t i = 0; i < child_brs->size_; ++i) {
|
||||
if (child_brs->skip_->exist(i)) {
|
||||
@ -1010,6 +1010,8 @@ int ObHashGroupByVecOp::inner_get_next_batch(const int64_t max_row_cnt)
|
||||
all_groupby_exprs_, op_max_batch_size, brs_,
|
||||
curr_group_id_))) {
|
||||
LOG_WARN("failed to collect batch result", K(ret), K(curr_group_id_));
|
||||
} else {
|
||||
brs_.all_rows_active_ = true;
|
||||
}
|
||||
} else {
|
||||
int64_t read_rows = 0;
|
||||
@ -1025,8 +1027,21 @@ int ObHashGroupByVecOp::inner_get_next_batch(const int64_t max_row_cnt)
|
||||
} else {
|
||||
curr_group_id_ += read_rows;
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
brs_.all_rows_active_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DEBUG_LOG
|
||||
// check all_row_active_
|
||||
if (OB_SUCC(ret) && brs_.size_ > 0) {
|
||||
bool is_all_false = brs_.skip_->is_all_false(brs_.size_);
|
||||
if (is_all_false != brs_.all_rows_active_) {
|
||||
ob_abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
LOG_DEBUG("after inner_get_next_batch",
|
||||
K(get_aggr_used_size()), K(get_aggr_used_size()),
|
||||
K(get_hash_table_used_size()),
|
||||
@ -1113,16 +1128,13 @@ int ObHashGroupByVecOp::load_data_batch(int64_t max_row_cnt)
|
||||
} else if (OB_FAIL(aggr_processor_.eval_aggr_param_batch(*child_brs))) {
|
||||
LOG_WARN("fail to eval aggr param batch", K(ret), K(*child_brs));
|
||||
}
|
||||
// prefetch the result that they will be processed
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < child_brs->size_; ++j) {
|
||||
if (batch_old_rows_[j]) {
|
||||
aggr_processor_.prefetch_aggregate_row(batch_old_rows_[j]);
|
||||
}
|
||||
} // end for
|
||||
//batch calc aggr for each group
|
||||
int32_t start_agg_id = -1;
|
||||
int32_t end_agg_id = -1;
|
||||
for (int64_t i = 0; i < MY_SPEC.aggr_infos_.count(); ++i) {
|
||||
bool calc_multi_groups = (MY_SPEC.aggr_stage_ == ObThreeStageAggrStage::FIRST_STAGE
|
||||
|| MY_SPEC.aggr_stage_ == ObThreeStageAggrStage::NONE_STAGE);
|
||||
|
||||
for (int64_t i = 0; !calc_multi_groups && i < MY_SPEC.aggr_infos_.count(); ++i) {
|
||||
if (MY_SPEC.aggr_infos_.at(i).param_exprs_.count() == 1) {
|
||||
aggr_vectors_[i] = MY_SPEC.aggr_infos_.at(i).param_exprs_.at(0)->get_vector(eval_ctx_);
|
||||
} else if (MY_SPEC.aggr_infos_.at(i).is_implicit_first_aggr()) {
|
||||
@ -1132,10 +1144,16 @@ int ObHashGroupByVecOp::load_data_batch(int64_t max_row_cnt)
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (calc_multi_groups) { // do nothing
|
||||
} else if (OB_FAIL(aggr_processor_.prepare_adding_one_row())) {
|
||||
LOG_WARN("prepare add one row failed", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < child_brs->size_; i++) {
|
||||
if (OB_SUCC(ret) && calc_multi_groups) {
|
||||
if (OB_FAIL(process_multi_groups(batch_new_rows_, *child_brs))) {
|
||||
LOG_WARN("process multiple groups failed", K(ret));
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; !calc_multi_groups && OB_SUCC(ret) && i < child_brs->size_; i++) {
|
||||
if ((!batch_new_rows_[i])) {
|
||||
continue;
|
||||
}
|
||||
@ -1162,8 +1180,14 @@ int ObHashGroupByVecOp::load_data_batch(int64_t max_row_cnt)
|
||||
}
|
||||
start_agg_id = -1;
|
||||
end_agg_id = -1;
|
||||
if (!reorder_aggr_rows_ || !batch_aggr_rows_table_.is_valid()) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < child_brs->size_; i++) {
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (!reorder_aggr_rows_ || !batch_aggr_rows_table_.is_valid()) {
|
||||
if (calc_multi_groups) {
|
||||
if (OB_FAIL(process_multi_groups(batch_old_rows_, *child_brs))) {
|
||||
LOG_WARN("process multiple groups failed", K(ret));
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; !calc_multi_groups && OB_SUCC(ret) && i < child_brs->size_; i++) {
|
||||
if ((!batch_old_rows_[i])) {
|
||||
continue;
|
||||
}
|
||||
@ -1220,7 +1244,7 @@ int ObHashGroupByVecOp::load_data_batch(int64_t max_row_cnt)
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(aggr_processor_.finish_adding_one_row())) {
|
||||
} else if (!calc_multi_groups && OB_FAIL(aggr_processor_.finish_adding_one_row())) {
|
||||
LOG_WARN("finish add one row failed", K(ret));
|
||||
}
|
||||
}
|
||||
@ -1978,6 +2002,7 @@ int ObHashGroupByVecOp::by_pass_prepare_one_batch(const int64_t batch_size)
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret) || no_non_distinct_aggr_) {
|
||||
brs_.all_rows_active_ = by_pass_child_brs_->all_rows_active_;
|
||||
} else if (OB_UNLIKELY(by_pass_batch_size_ <= 0)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("by pass group row is not init", K(ret), K(by_pass_batch_size_));
|
||||
@ -2239,6 +2264,30 @@ int ObHashGroupByVecOp::bypass_add_llc_map_batch(bool ready_to_check_ndv) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObHashGroupByVecOp::process_multi_groups(aggregate::AggrRowPtr *agg_rows, const ObBatchRows &brs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int32_t start_agg_id = -1, end_agg_id = -1;
|
||||
for (int i = 0; OB_SUCC(ret) && i < brs.size_; i++) {
|
||||
if ((!agg_rows[i])) { continue; }
|
||||
if (OB_FAIL(ObGroupByVecOp::calculate_3stage_agg_info(
|
||||
agg_rows[i], local_group_rows_.get_row_meta(), i, start_agg_id, end_agg_id))) {
|
||||
LOG_WARN("calculate 3stage aggregate info failed", K(ret));
|
||||
} else if (OB_UNLIKELY(start_agg_id == -1 || end_agg_id == -1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected aggregate idx", K(ret), K(start_agg_id), K(end_agg_id));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(aggr_processor_.add_batch_for_multi_groups(start_agg_id, end_agg_id, agg_rows,
|
||||
brs.size_))) {
|
||||
LOG_WARN("failed to calculate multiple groups", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LlcEstimate::init_llc_map(common::ObArenaAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -337,6 +337,8 @@ private:
|
||||
const ObBatchRows *child_brs, ObBatchRows &my_brs,
|
||||
const int64_t batch_size, bool &insert_group_ht);
|
||||
int init_by_pass_op();
|
||||
|
||||
int process_multi_groups(aggregate::AggrRowPtr *agg_rows, const ObBatchRows &brs);
|
||||
// Alloc one batch group_row_item at a time
|
||||
static const int64_t BATCH_GROUP_ITEM_SIZE = 16;
|
||||
// const int64_t EXTEND_BKT_NUM_PUSH_DOWN = INIT_L3_CACHE_SIZE / ObExtendHashTableVec<ObGroupRowBucket>::get_sizeof_aggr_row();
|
||||
|
@ -86,6 +86,11 @@ public:
|
||||
{
|
||||
return fixed_expr_reordered() ? (project_idx(col_idx) - fixed_cnt_) : col_idx;
|
||||
}
|
||||
//make sure column is fixed reordered
|
||||
inline int64_t get_fixed_cell_offset(const int64_t col_idx) const
|
||||
{
|
||||
return fixed_offsets_[project_idx(col_idx)];
|
||||
}
|
||||
static int32_t get_row_fixed_size(const int64_t col_cnt,
|
||||
const int64_t fixed_payload_len,
|
||||
const int64_t extra_size,
|
||||
@ -238,6 +243,11 @@ struct ObCompactRow
|
||||
}
|
||||
MEMCPY(payload_ + off, payload, len);
|
||||
}
|
||||
//make sure column is fixed reordered
|
||||
inline void set_fixed_cell_payload(const char *payload, const int64_t offset, const ObLength len)
|
||||
{
|
||||
MEMCPY(payload_ + offset, payload, len);
|
||||
}
|
||||
|
||||
inline void get_cell_payload(const RowMeta &meta,
|
||||
const int64_t col_idx,
|
||||
@ -281,6 +291,11 @@ struct ObCompactRow
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
//make sure column is fixed reordered
|
||||
inline const char *get_fixed_cell_payload(const int64_t offset) const
|
||||
{
|
||||
return payload_ + offset;
|
||||
}
|
||||
|
||||
inline int64_t get_row_size() const {
|
||||
return header_.row_size_;
|
||||
|
@ -582,15 +582,6 @@ private:
|
||||
const auto &curr_bkt = buckets->at(bkt_idx);
|
||||
__builtin_prefetch(&curr_bkt, 0/* read */, 2 /*high temp locality*/);
|
||||
}
|
||||
for (int i = 0; i < batch_size; ++i) {
|
||||
int64_t bkt_idx = (hash_values_for_batch[i] & num_cnt);
|
||||
const auto &curr_bkt = buckets->at(bkt_idx);
|
||||
if ((OB_NOT_NULL(skip) && skip->at(i))
|
||||
|| !curr_bkt.check_hash(hash_values_for_batch[i])) {
|
||||
continue;
|
||||
}
|
||||
__builtin_prefetch(&curr_bkt.item_, 0/* read */, 2 /*high temp locality*/);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1220,6 +1220,7 @@ int ObPushdownFilterExecutor::init_co_filter_param(const ObTableIterParam &iter_
|
||||
int ret = OB_SUCCESS;
|
||||
const ObITableReadInfo *read_info = nullptr;
|
||||
const common::ObIArray<int32_t> *access_cgs = nullptr;
|
||||
const common::ObIArray<ObExpr *> *cg_exprs = nullptr;
|
||||
const ObIArray<uint64_t> &col_ids = get_col_ids();
|
||||
const int64_t col_count = col_ids.count();
|
||||
if (OB_UNLIKELY(!iter_param.is_valid() || nullptr == (read_info = iter_param.get_read_info())
|
||||
@ -1229,7 +1230,7 @@ int ObPushdownFilterExecutor::init_co_filter_param(const ObTableIterParam &iter_
|
||||
} else if (is_filter_node()) {
|
||||
if (0 == col_count) {
|
||||
if (OB_FAIL(init_array_param(cg_idxs_, 1))) {
|
||||
LOG_WARN("Fail to init col offsets", K(ret), K(col_count));
|
||||
LOG_WARN("Fail to init cg idxs", K(ret), K(col_count));
|
||||
} else if (OB_FAIL(cg_idxs_.push_back(OB_CS_VIRTUAL_CG_IDX))) {
|
||||
LOG_WARN("Failed to push back cg idx", K(ret));
|
||||
}
|
||||
@ -1243,10 +1244,10 @@ int ObPushdownFilterExecutor::init_co_filter_param(const ObTableIterParam &iter_
|
||||
LOG_WARN("Fail to init col offsets", K(ret), K(col_count));
|
||||
} else if (OB_FAIL(init_array_param(default_datums_, col_count))) {
|
||||
LOG_WARN("Fail to init default datums", K(ret), K(col_count));
|
||||
} else if (FALSE_IT(cg_exprs = get_cg_col_exprs())) {
|
||||
} else if (nullptr != cg_exprs && OB_FAIL(cg_col_exprs_.assign(*cg_exprs))) {
|
||||
LOG_WARN("Fail to assign cg exprs", K(ret), KPC(cg_exprs));
|
||||
} else {
|
||||
if (nullptr == cg_col_exprs_) {
|
||||
cg_col_exprs_ = get_cg_col_exprs();
|
||||
}
|
||||
access_cgs = read_info->get_cg_idxs();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < col_count; i++) {
|
||||
int32_t col_pos = -1;
|
||||
@ -1325,13 +1326,13 @@ int ObPushdownFilterExecutor::init_co_filter_param(const ObTableIterParam &iter_
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPushdownFilterExecutor::set_cg_param(const common::ObIArray<uint32_t> &cg_idxs, common::ObIArray<ObExpr *> *exprs)
|
||||
int ObPushdownFilterExecutor::set_cg_param(const common::ObIArray<uint32_t> &cg_idxs, const common::ObIArray<ObExpr *> &exprs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL((cg_idxs_.assign(cg_idxs)))) {
|
||||
LOG_WARN("Failed to assign cg_idxs", K(ret), K(cg_idxs), K(cg_idxs_));
|
||||
} else {
|
||||
cg_col_exprs_ = exprs;
|
||||
} else if (!exprs.empty() && OB_FAIL(cg_col_exprs_.assign(exprs))) {
|
||||
LOG_WARN("Failed to assign cg_exprs", K(ret), K(exprs));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1616,7 +1617,7 @@ ObPushdownFilterExecutor::ObPushdownFilterExecutor(common::ObIAllocator &alloc,
|
||||
: type_(type), need_check_row_filter_(false), filter_tree_status_(ObCommonFilterTreeStatus::NONE_FILTER),
|
||||
n_cols_(0), n_child_(0), cg_iter_idx_(INVALID_CG_ITER_IDX), skipped_rows_(0), childs_(nullptr),
|
||||
filter_bitmap_(nullptr), col_params_(alloc), col_offsets_(alloc), cg_col_offsets_(alloc), default_datums_(alloc),
|
||||
cg_idxs_(alloc), cg_col_exprs_(nullptr), allocator_(alloc), op_(op), is_rewrited_(false), filter_bool_mask_()
|
||||
cg_idxs_(alloc), cg_col_exprs_(alloc), allocator_(alloc), op_(op), is_rewrited_(false), filter_bool_mask_()
|
||||
{}
|
||||
|
||||
ObPushdownFilterExecutor::~ObPushdownFilterExecutor()
|
||||
@ -1631,7 +1632,7 @@ ObPushdownFilterExecutor::~ObPushdownFilterExecutor()
|
||||
cg_col_offsets_.reset();
|
||||
default_datums_.reset();
|
||||
cg_idxs_.reset();
|
||||
cg_col_exprs_ = nullptr;
|
||||
cg_col_exprs_.reset();
|
||||
for (uint32_t i = 0; i < n_child_; i++) {
|
||||
if (OB_NOT_NULL(childs_[i])) {
|
||||
childs_[i]->~ObPushdownFilterExecutor();
|
||||
@ -1651,7 +1652,7 @@ DEF_TO_STRING(ObPushdownFilterExecutor)
|
||||
J_KV(K_(type), K_(need_check_row_filter), K_(n_cols),
|
||||
K_(n_child), KP_(childs), KP_(filter_bitmap),
|
||||
K_(col_params), K_(default_datums), K_(col_offsets),
|
||||
K_(cg_col_offsets), K_(cg_idxs), KP_(cg_col_exprs),
|
||||
K_(cg_col_offsets), K_(cg_idxs), K_(cg_col_exprs),
|
||||
K_(is_rewrited), K_(filter_bool_mask));
|
||||
J_OBJ_END();
|
||||
return pos;
|
||||
@ -2861,7 +2862,7 @@ int PushdownFilterInfo::init(const storage::ObTableIterParam &iter_param, common
|
||||
} else if (OB_ISNULL(skip_bit_ = to_bit_vector(alloc.alloc(ObBitVector::memory_size(batch_size_))))) {
|
||||
ret = common::OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("Failed to alloc skip bit", K(ret), K_(batch_size));
|
||||
} else if (OB_ISNULL(buf = alloc.alloc(sizeof(int64_t) * batch_size_))) {
|
||||
} else if (OB_ISNULL(buf = alloc.alloc(sizeof(int32_t) * batch_size_))) {
|
||||
ret = common::OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc row_ids", K(ret), K(batch_size_));
|
||||
} else if (OB_ISNULL(len_array_buf = alloc.alloc(sizeof(uint32_t) * batch_size_))) {
|
||||
@ -2869,7 +2870,7 @@ int PushdownFilterInfo::init(const storage::ObTableIterParam &iter_param, common
|
||||
LOG_WARN("fail to alloc len_array_buf", K(ret), K_(batch_size));
|
||||
} else {
|
||||
skip_bit_->init(batch_size_);
|
||||
row_ids_ = reinterpret_cast<int64_t *>(buf);
|
||||
row_ids_ = reinterpret_cast<int32_t *>(buf);
|
||||
len_array_ = reinterpret_cast<uint32_t *>(len_array_buf);
|
||||
}
|
||||
}
|
||||
|
@ -545,12 +545,13 @@ private:
|
||||
ObPushdownFilterNode *filter_tree_;
|
||||
};
|
||||
|
||||
enum ObCommonFilterTreeStatus
|
||||
enum ObCommonFilterTreeStatus : uint8_t
|
||||
{
|
||||
NONE_FILTER = 0,
|
||||
WHITE = 1,
|
||||
SINGLE_BLACK = 2,
|
||||
MULTI_BLACK = 3
|
||||
MULTI_BLACK = 3,
|
||||
MAX_STATUS = 4
|
||||
};
|
||||
|
||||
// executor interface
|
||||
@ -620,10 +621,10 @@ public:
|
||||
OB_INLINE const common::ObFixedArray<blocksstable::ObStorageDatum, common::ObIAllocator> &get_default_datums() const
|
||||
{ return default_datums_; }
|
||||
OB_INLINE const common::ObIArray<uint32_t> &get_cg_idxs() const { return cg_idxs_; }
|
||||
OB_INLINE common::ObIArray<uint32_t> &get_cg_idxs() { return cg_idxs_; }
|
||||
virtual common::ObIArray<ObExpr *> *get_cg_col_exprs() const { return cg_col_exprs_; }
|
||||
virtual const common::ObIArray<ObExpr *> *get_cg_col_exprs() const
|
||||
{ return cg_col_exprs_.empty() ? nullptr : &cg_col_exprs_; }
|
||||
OB_INLINE bool is_cg_param_valid() const
|
||||
{ return !cg_idxs_.empty() && (nullptr == cg_col_exprs_ || cg_col_exprs_->count() <= cg_idxs_.count()); }
|
||||
{ return !cg_idxs_.empty() && cg_col_exprs_.count() <= cg_idxs_.count(); }
|
||||
OB_INLINE uint32_t get_child_count() const { return n_child_; }
|
||||
OB_INLINE int64_t get_cg_iter_idx() const { return cg_iter_idx_; }
|
||||
OB_INLINE void set_cg_iter_idx(const int64_t cg_iter_idx)
|
||||
@ -677,7 +678,7 @@ public:
|
||||
const common::ObIArray<int32_t> &output_projector,
|
||||
const bool need_padding);
|
||||
int init_co_filter_param(const storage::ObTableIterParam &iter_param, const bool need_padding);
|
||||
int set_cg_param(const common::ObIArray<uint32_t> &cg_idxs, common::ObIArray<ObExpr *> *exprs);
|
||||
int set_cg_param(const common::ObIArray<uint32_t> &cg_idxs, const common::ObIArray<ObExpr *> &exprs);
|
||||
int pull_up_common_node(
|
||||
const common::ObIArray<uint32_t> &filter_indexes,
|
||||
ObPushdownFilterExecutor *&common_filter_executor);
|
||||
@ -725,7 +726,7 @@ protected:
|
||||
common::ObFixedArray<int32_t, common::ObIAllocator> cg_col_offsets_;
|
||||
common::ObFixedArray<blocksstable::ObStorageDatum, common::ObIAllocator> default_datums_;
|
||||
common::ObFixedArray<uint32_t, common::ObIAllocator> cg_idxs_;
|
||||
common::ObIArray<ObExpr *> *cg_col_exprs_;
|
||||
common::ObFixedArray<ObExpr *, common::ObIAllocator> cg_col_exprs_;
|
||||
common::ObIAllocator &allocator_;
|
||||
ObPushdownOperator &op_;
|
||||
private:
|
||||
@ -776,7 +777,7 @@ public:
|
||||
OB_INLINE ObPushdownBlackFilterNode &get_filter_node() { return filter_; }
|
||||
OB_INLINE virtual common::ObIArray<uint64_t> &get_col_ids() override
|
||||
{ return filter_.get_col_ids(); }
|
||||
virtual common::ObIArray<ObExpr *> *get_cg_col_exprs() const override { return &filter_.column_exprs_; }
|
||||
virtual const common::ObIArray<ObExpr *> *get_cg_col_exprs() const override { return &filter_.column_exprs_; }
|
||||
OB_INLINE bool can_vectorized();
|
||||
int filter_batch(ObPushdownFilterExecutor *parent,
|
||||
const int64_t start,
|
||||
@ -921,7 +922,7 @@ public:
|
||||
OB_INLINE const ObPushdownWhiteFilterNode &get_filter_node() const { return filter_; }
|
||||
OB_INLINE virtual common::ObIArray<uint64_t> &get_col_ids() override
|
||||
{ return filter_.get_col_ids(); }
|
||||
virtual common::ObIArray<ObExpr *> *get_cg_col_exprs() const override { return &filter_.column_exprs_; }
|
||||
virtual const common::ObIArray<ObExpr *> *get_cg_col_exprs() const override { return &filter_.column_exprs_; }
|
||||
virtual int init_evaluated_datums() override;
|
||||
OB_INLINE const common::ObIArray<common::ObDatum> &get_datums() const
|
||||
{ return datum_params_; }
|
||||
@ -1247,7 +1248,7 @@ struct PushdownFilterInfo
|
||||
sql::ObPushdownFilterExecutor *filter_;
|
||||
// for black filter vectorize
|
||||
const char **cell_data_ptrs_;
|
||||
int64_t *row_ids_;
|
||||
int32_t *row_ids_;
|
||||
uint32_t *len_array_;
|
||||
common::ObBitmap *ref_bitmap_;
|
||||
sql::ObBitVector *skip_bit_;
|
||||
|
@ -92,6 +92,9 @@ public:
|
||||
inline int fill_head(int64_t size);
|
||||
inline int fill_tail(int64_t size);
|
||||
inline int compact();
|
||||
inline int64_t head_pos() const { return head_; }
|
||||
inline int64_t tail_pos() const { return tail_;}
|
||||
inline void fast_update_head(const int64_t pos) { head_ = pos; }
|
||||
TO_STRING_KV(KP_(data), K_(head), K_(tail), K_(cap));
|
||||
private:
|
||||
char *data_;
|
||||
|
@ -249,6 +249,68 @@ int ObTempRowStore::RowBlock::calc_rows_size(const IVectorPtrs &vectors,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTempRowStore::DtlRowBlock::calc_rows_size(const IVectorPtrs &vectors,
|
||||
const RowMeta &row_meta,
|
||||
const ObBatchRows &brs,
|
||||
uint32_t row_size_arr[]) {
|
||||
int ret = OB_SUCCESS;
|
||||
const int64_t fixed_row_size = row_meta.get_row_fixed_size();
|
||||
const bool reordered = row_meta.fixed_expr_reordered();
|
||||
for (int64_t i = 0; i < brs.size_; i++) {
|
||||
row_size_arr[i] = fixed_row_size;
|
||||
}
|
||||
for (int64_t col_idx = 0; OB_SUCC(ret) && col_idx < vectors.count(); col_idx++) {
|
||||
ObIVector *vec = vectors.at(col_idx);
|
||||
if (reordered && row_meta.project_idx(col_idx) < row_meta.fixed_cnt_) {
|
||||
continue;
|
||||
}
|
||||
VectorFormat format = vec->get_format();
|
||||
if (VEC_DISCRETE == format) {
|
||||
ObDiscreteBase *disc_vec = static_cast<ObDiscreteBase *>(vec);
|
||||
ObLength *lens = disc_vec->get_lens();
|
||||
for (int64_t i = 0; i < brs.size_; i++) {
|
||||
if (brs.skip_->at(i)) {
|
||||
continue;
|
||||
}
|
||||
if (!disc_vec->is_null(i)) {
|
||||
row_size_arr[i] += lens[i];
|
||||
}
|
||||
}
|
||||
} else if (VEC_CONTINUOUS == format) {
|
||||
ObContinuousBase *cont_vec = static_cast<ObContinuousBase*>(vec);
|
||||
uint32_t *offsets = cont_vec->get_offsets();
|
||||
for (int64_t i = 0; i < brs.size_; i++) {
|
||||
if (brs.skip_->at(i)) {
|
||||
continue;
|
||||
}
|
||||
row_size_arr[i] += offsets[i + 1] - offsets[i];
|
||||
}
|
||||
} else if (is_uniform_format(format)) {
|
||||
ObUniformBase *uni_vec = static_cast<ObUniformBase *>(vec);
|
||||
ObDatum *datums = uni_vec->get_datums();
|
||||
const uint16_t idx_mask = VEC_UNIFORM_CONST == format ? 0 : UINT16_MAX;
|
||||
for (int64_t i = 0; i < brs.size_; i++) {
|
||||
if (brs.skip_->at(i)) {
|
||||
continue;
|
||||
}
|
||||
if (!datums[i & idx_mask].is_null()) {
|
||||
row_size_arr[i] += datums[i & idx_mask].len_;
|
||||
}
|
||||
}
|
||||
} else if (VEC_FIXED == format) {
|
||||
ObFixedLengthBase *fixed_vec = static_cast<ObFixedLengthBase*>(vec);
|
||||
for (int64_t i = 0; i < brs.size_; i++) {
|
||||
if (brs.skip_->at(i)) {
|
||||
continue;
|
||||
}
|
||||
row_size_arr[i] += fixed_vec->get_length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObTempRowStore::Iterator::init(ObTempRowStore *store)
|
||||
{
|
||||
reset();
|
||||
|
@ -67,6 +67,14 @@ public:
|
||||
const int64_t col_idx);
|
||||
};
|
||||
|
||||
struct DtlRowBlock : public RowBlock {
|
||||
static int calc_rows_size(const IVectorPtrs &vectors,
|
||||
const RowMeta &row_meta,
|
||||
const ObBatchRows &brs,
|
||||
uint32_t row_size_arr[]);
|
||||
|
||||
};
|
||||
|
||||
const static int64_t BLOCK_SIZE = (64L << 10);
|
||||
class Iterator : public ObTempBlockStore::BlockReader
|
||||
{
|
||||
|
@ -689,6 +689,23 @@ struct ObArithOpBase : public ObArithOpRawType<char, char, char>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Res, typename Left, typename Right>
|
||||
struct ObArithTypedBase : public ObArithOpRawType<Res, Left, Right>
|
||||
{
|
||||
constexpr static bool is_raw_op_supported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static void raw_op(Res &, const Left &, const Right, Args &...args)
|
||||
{}
|
||||
static int raw_check(const Res &, const Left &, const Right &)
|
||||
{
|
||||
return common::OB_ERR_UNEXPECTED;
|
||||
}
|
||||
};
|
||||
|
||||
// Wrap arith operate with null check.
|
||||
template <typename DatumFunctor>
|
||||
struct ObWrapArithOpNullCheck: public ObArithOpBase
|
||||
@ -707,8 +724,8 @@ struct ObWrapArithOpNullCheck: public ObArithOpBase
|
||||
};
|
||||
|
||||
// Wrap arith operate with null check for vector.
|
||||
template <typename VectorFunctor>
|
||||
struct ObWrapVectorArithOpNullCheck: public ObArithOpBase
|
||||
template <typename VectorFunctor, typename Base>
|
||||
struct ObWrapVectorArithOpNullCheck: public Base
|
||||
{
|
||||
template <typename ResVector, typename LeftVector, typename RightVector, typename... Args>
|
||||
static int vector_op(ResVector &res_vec, const LeftVector &left_vec,
|
||||
@ -738,17 +755,17 @@ int def_batch_arith_op_by_datum_func(BATCH_EVAL_FUNC_ARG_DECL, Args &...args)
|
||||
BATCH_EVAL_FUNC_ARG_LIST, args...);
|
||||
}
|
||||
|
||||
template <typename VectorFunctor, typename... Args>
|
||||
template <typename VectorFunctor, typename ArithBase, typename... Args>
|
||||
int def_fixed_len_vector_arith_op_func(VECTOR_EVAL_FUNC_ARG_DECL, Args &...args)
|
||||
{
|
||||
return def_fixed_len_vector_arith_op<ObWrapVectorArithOpNullCheck<VectorFunctor>, Args...>(
|
||||
return def_fixed_len_vector_arith_op<ObWrapVectorArithOpNullCheck<VectorFunctor, ArithBase>, Args...>(
|
||||
VECTOR_EVAL_FUNC_ARG_LIST, args...);
|
||||
}
|
||||
|
||||
template <typename VectorFunctor, typename... Args>
|
||||
template <typename VectorFunctor, typename ArithBase, typename... Args>
|
||||
int def_variable_len_vector_arith_op_func(VECTOR_EVAL_FUNC_ARG_DECL, Args &...args)
|
||||
{
|
||||
return def_variable_len_vector_arith_op<ObWrapVectorArithOpNullCheck<VectorFunctor>, Args...>(
|
||||
return def_variable_len_vector_arith_op<ObWrapVectorArithOpNullCheck<VectorFunctor, ArithBase>, Args...>(
|
||||
VECTOR_EVAL_FUNC_ARG_LIST, args...);
|
||||
}
|
||||
|
||||
|
@ -3950,12 +3950,17 @@ CAST_FUNC_NAME(text, string)
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObExprStrResAlloc res_alloc(expr, ctx);
|
||||
ObTextStringIter instr_iter(in_type, in_cs_type, child_res->get_string(), has_lob_header);
|
||||
if (OB_FAIL(ObTextStringHelper::build_text_iter(instr_iter, &ctx.exec_ctx_, ctx.exec_ctx_.get_my_session(),
|
||||
const ObLobCommon& lob = child_res->get_lob_data();
|
||||
if (child_res->len_ != 0 && !lob.is_mem_loc_ && lob.in_row_ && has_lob_header) {
|
||||
data.assign_ptr(lob.get_inrow_data_ptr(), static_cast<int32_t>(lob.get_byte_size(child_res->len_)));
|
||||
} else if (OB_FAIL(ObTextStringHelper::build_text_iter(instr_iter, &ctx.exec_ctx_, ctx.exec_ctx_.get_my_session(),
|
||||
is_same_charset ? reinterpret_cast<ObIAllocator *>(&res_alloc) : &temp_allocator,
|
||||
&temp_allocator))) {
|
||||
LOG_WARN("init lob str iter failed ", K(ret), K(in_type));
|
||||
} else if (OB_FAIL(instr_iter.get_full_data(data))) {
|
||||
LOG_WARN("init lob str iter failed ", K(ret), K(in_type));
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (lib::is_oracle_mode()
|
||||
&& ob_is_clob(in_type, in_cs_type)
|
||||
&& (0 == data.length())
|
||||
|
@ -125,6 +125,15 @@ int ObExprAdd::calc_result_type2(ObExprResType &type,
|
||||
type.set_scale(ORA_NUMBER_SCALE_UNKNOWN_YET);
|
||||
type.set_precision(PRECISION_UNKNOWN_YET);
|
||||
}
|
||||
if ((ob_is_double_tc(type.get_type()) || ob_is_float_tc(type.get_type())) && type.get_scale() > 0) {
|
||||
// if result is fixed double/float, calc type's of params should also be fixed double/float
|
||||
if (ob_is_double_tc(type1.get_calc_type()) || ob_is_float_tc(type1.get_calc_type())) {
|
||||
type1.set_calc_scale(type.get_scale());
|
||||
}
|
||||
if (ob_is_double_tc(type2.get_calc_type()) || ob_is_float_tc(type2.get_calc_type())) {
|
||||
type2.set_calc_scale(type.get_scale());
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("calc_result_type2", K(scale), K(type1), K(type2), K(type), K(precision));
|
||||
return ret;
|
||||
@ -1669,7 +1678,8 @@ int ObExprAdd::add_decimal##TYPE##_oracle_vector(VECTOR_EVAL_FUNC_ARG_DECL)
|
||||
{ \
|
||||
ObNumStackOnceAlloc tmp_alloc; \
|
||||
const int64_t scale = expr.args_[0]->datum_meta_.scale_; \
|
||||
return def_fixed_len_vector_arith_op_func<ObDecimalOracleVectorAddFunc<TYPE##_t>>(VECTOR_EVAL_FUNC_ARG_LIST, scale, tmp_alloc); \
|
||||
return def_fixed_len_vector_arith_op_func<ObDecimalOracleVectorAddFunc<TYPE##_t>,\
|
||||
ObArithTypedBase<TYPE##_t, TYPE##_t, TYPE##_t>>(VECTOR_EVAL_FUNC_ARG_LIST, scale, tmp_alloc); \
|
||||
}
|
||||
|
||||
DECINC_ADD_EVAL_FUNC_ORA_DECL(int32)
|
||||
|
@ -578,7 +578,9 @@ int ObExprDiv::div_float_batch(BATCH_EVAL_FUNC_ARG_DECL)
|
||||
int ObExprDiv::div_float_vector(VECTOR_EVAL_FUNC_ARG_DECL)
|
||||
{
|
||||
const bool is_oracle = lib::is_oracle_mode();
|
||||
return def_fixed_len_vector_arith_op_func<ObFloatVectorDivFunc>(VECTOR_EVAL_FUNC_ARG_LIST, is_oracle);
|
||||
return def_fixed_len_vector_arith_op_func<ObFloatVectorDivFunc,
|
||||
ObArithTypedBase<float, float, float>>(
|
||||
VECTOR_EVAL_FUNC_ARG_LIST, is_oracle);
|
||||
}
|
||||
|
||||
|
||||
@ -677,8 +679,8 @@ int ObExprDiv::div_double_batch(BATCH_EVAL_FUNC_ARG_DECL)
|
||||
int ObExprDiv::div_double_vector(VECTOR_EVAL_FUNC_ARG_DECL)
|
||||
{
|
||||
const bool is_oracle = lib::is_oracle_mode();
|
||||
return def_fixed_len_vector_arith_op_func<ObDoubleVectorDivFunc>(VECTOR_EVAL_FUNC_ARG_LIST, expr,
|
||||
is_oracle);
|
||||
return def_fixed_len_vector_arith_op_func<ObDoubleVectorDivFunc, ObArithTypedBase<double, double, double>>(
|
||||
VECTOR_EVAL_FUNC_ARG_LIST, expr, is_oracle);
|
||||
}
|
||||
|
||||
struct ObNumberDivFunc
|
||||
@ -806,8 +808,8 @@ int ObExprDiv::div_number_batch(BATCH_EVAL_FUNC_ARG_DECL)
|
||||
int ObExprDiv::div_number_vector(VECTOR_EVAL_FUNC_ARG_DECL)
|
||||
{
|
||||
const bool is_oracle = lib::is_oracle_mode();
|
||||
return def_variable_len_vector_arith_op_func<ObNumberVectorDivFunc>(VECTOR_EVAL_FUNC_ARG_LIST, expr, ctx,
|
||||
is_oracle);
|
||||
return def_variable_len_vector_arith_op_func<ObNumberVectorDivFunc, ObArithOpBase>(
|
||||
VECTOR_EVAL_FUNC_ARG_LIST, expr, ctx, is_oracle);
|
||||
}
|
||||
|
||||
|
||||
|
@ -138,6 +138,15 @@ int ObExprMinus::calc_result_type2(ObExprResType &type,
|
||||
type.set_scale(ORA_NUMBER_SCALE_UNKNOWN_YET);
|
||||
type.set_precision(PRECISION_UNKNOWN_YET);
|
||||
}
|
||||
if ((ob_is_double_tc(type.get_type()) || ob_is_float_tc(type.get_type())) && type.get_scale() > 0) {
|
||||
// if result is fixed double/float, calc type's of params should also be fixed double/float
|
||||
if (ob_is_double_tc(type1.get_calc_type()) || ob_is_float_tc(type1.get_calc_type())) {
|
||||
type1.set_calc_scale(type.get_scale());
|
||||
}
|
||||
if (ob_is_double_tc(type2.get_calc_type()) || ob_is_float_tc(type2.get_calc_type())) {
|
||||
type2.set_calc_scale(type.get_scale());
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("calc_result_type2", K(scale), K(type1), K(type2), K(type), K(precision));
|
||||
}
|
||||
return ret;
|
||||
@ -1793,7 +1802,8 @@ int ObExprMinus::minus_decimal##TYPE##_oracle_vector(VECTOR_EVAL_FUNC_ARG_DECL)
|
||||
{ \
|
||||
ObNumStackOnceAlloc tmp_alloc; \
|
||||
const int64_t scale = expr.args_[0]->datum_meta_.scale_; \
|
||||
return def_fixed_len_vector_arith_op_func<ObDecimalOracleVectorMinusFunc<TYPE##_t>>(VECTOR_EVAL_FUNC_ARG_LIST, scale, tmp_alloc); \
|
||||
return def_fixed_len_vector_arith_op_func<ObDecimalOracleVectorMinusFunc<TYPE##_t>,\
|
||||
ObArithTypedBase<TYPE##_t, TYPE##_t, TYPE##_t>>(VECTOR_EVAL_FUNC_ARG_LIST, scale, tmp_alloc); \
|
||||
}
|
||||
|
||||
DECINC_MINUS_EVAL_FUNC_ORA_DECL(int32)
|
||||
|
@ -1335,7 +1335,8 @@ int ObExprMul::mul_decimal##RES##_##L##_##R##_oracle_vector(VECTOR_EVAL_FUNC_ARG
|
||||
{ \
|
||||
ObNumStackOnceAlloc tmp_alloc; \
|
||||
const int64_t scale = expr.args_[0]->datum_meta_.scale_ + expr.args_[1]->datum_meta_.scale_; \
|
||||
return def_fixed_len_vector_arith_op_func<ObDecimalOracleVectorMulFunc<RES##_t, L##_t, R##_t>>(VECTOR_EVAL_FUNC_ARG_LIST, scale, tmp_alloc); \
|
||||
return def_fixed_len_vector_arith_op_func<ObDecimalOracleVectorMulFunc<RES##_t, L##_t, R##_t>,\
|
||||
ObArithTypedBase<L##_t, R##_t, RES##_t>>(VECTOR_EVAL_FUNC_ARG_LIST, scale, tmp_alloc); \
|
||||
}
|
||||
|
||||
DECINC_MUL_EVAL_FUNC_ORA_DECL(int32, int32, int32)
|
||||
|
@ -6435,6 +6435,7 @@ int ObRelationalExprOperator::cg_datum_cmp_expr(const ObRawExpr &raw_expr,
|
||||
}
|
||||
CK(NULL != rt_expr.eval_func_);
|
||||
CK(NULL != rt_expr.eval_batch_func_);
|
||||
CK(NULL != rt_expr.eval_vector_func_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -392,6 +392,9 @@ int ObJoinFilterOpInput::construct_msg_details(
|
||||
"RFInFilter",
|
||||
"RFInFilter"))) {
|
||||
LOG_WARN("fail to init in hash set", K(ret));
|
||||
} else if (OB_FAIL(in_msg.sm_hash_set_.init(config.runtime_filter_max_in_num_,
|
||||
in_msg.get_tenant_id()))) {
|
||||
LOG_WARN("failed to init sm_hash_set_", K(config.runtime_filter_max_in_num_));
|
||||
} else if (OB_FAIL(in_msg.need_null_cmp_flags_.assign(spec.need_null_cmp_flags_))) {
|
||||
LOG_WARN("fail to init cmp flags", K(ret));
|
||||
} else if (OB_FAIL(in_msg.build_row_cmp_info_.assign(spec.rf_build_cmp_infos_))) {
|
||||
|
@ -140,13 +140,18 @@ ObPxTransmitOp::ObPxTransmitOp(ObExecContext &exec_ctx, const ObOpSpec &spec, Ob
|
||||
batch_param_remain_(false),
|
||||
receive_channel_ready_(false),
|
||||
data_msg_type_(dtl::ObDtlMsgType::PX_DATUM_ROW),
|
||||
disable_fast_append_(false),
|
||||
slice_info_bkts_(nullptr),
|
||||
slice_bkt_item_cnts_(nullptr),
|
||||
vectors_(&px_row_allocator_),
|
||||
selector_array_(nullptr),
|
||||
selector_cnt_(0),
|
||||
row_size_array_(nullptr),
|
||||
return_rows_(nullptr),
|
||||
use_hash_reorder_(false)
|
||||
use_hash_reorder_(false),
|
||||
fallback_array_(nullptr),
|
||||
fallback_cnt_(0),
|
||||
blocks_(nullptr),
|
||||
init_hash_reorder_struct_(false)
|
||||
{
|
||||
MEMSET(rand48_buf_, 0, sizeof(rand48_buf_));
|
||||
}
|
||||
@ -174,6 +179,7 @@ void ObPxTransmitOp::destroy()
|
||||
cur_transmit_sampled_rows_ = NULL;
|
||||
sampled_rows2transmit_.reset();
|
||||
sampled_input_rows_.~ObRADatumStore();
|
||||
meta_.reset();
|
||||
ObTransmitOp::destroy();
|
||||
}
|
||||
|
||||
@ -213,6 +219,14 @@ int ObPxTransmitOp::inner_open()
|
||||
LOG_WARN("failed to alloc return rows", K(ret), K(get_spec().max_batch_size_));
|
||||
} else if (OB_FAIL(vectors_.init(get_spec().output_.count()))) {
|
||||
LOG_WARN("failed to init vector array", K(ret));
|
||||
} else if (OB_ISNULL(fallback_array_ = static_cast<uint16_t *>
|
||||
(px_row_allocator_.alloc(get_spec().max_batch_size_ * sizeof(uint16_t))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc row size array", K(ret), K(get_spec().max_batch_size_));
|
||||
} else if (OB_ISNULL(selector_array_ = static_cast<uint16_t *>
|
||||
(px_row_allocator_.alloc(get_spec().max_batch_size_ * sizeof(uint16_t))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc row size array", K(ret), K(get_spec().max_batch_size_));
|
||||
}
|
||||
}
|
||||
rand48_buf_[0] = 0x330E; // 0x330E is the arbitrary value of srand48
|
||||
@ -226,11 +240,16 @@ int ObPxTransmitOp::inner_open()
|
||||
OZ(fetch_first_row());
|
||||
OZ(init_channel(*trans_input));
|
||||
}
|
||||
OZ(meta_.init(get_spec().output_, 0, false));
|
||||
if (OB_SUCC(ret)
|
||||
&& get_spec().use_rich_format_
|
||||
&& NULL == static_cast<const ObPxTransmitSpec &> (get_spec()).tablet_id_expr_
|
||||
&& MY_SPEC.max_batch_size_ * task_channels_.count() <= MAX_BKT_FOR_REORDER) {
|
||||
use_hash_reorder_ = true;
|
||||
if (PX_VECTOR_ROW != data_msg_type_) {
|
||||
use_hash_reorder_ = true;
|
||||
} else {
|
||||
init_hash_reorder_struct_ = true;
|
||||
}
|
||||
if (OB_ISNULL(slice_info_bkts_ = static_cast<uint16_t **>
|
||||
(px_row_allocator_.alloc(task_channels_.count() * sizeof(uint16_t *))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
@ -249,6 +268,36 @@ int ObPxTransmitOp::inner_open()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && get_spec().use_rich_format_ &&!use_hash_reorder_) {
|
||||
data_msg_type_ = PX_VECTOR_ROW;
|
||||
if (OB_ISNULL(blocks_ =
|
||||
static_cast<ObTempRowStore::DtlRowBlock **> (px_row_allocator_.alloc(task_channels_.count()
|
||||
* sizeof(ObTempRowStore::DtlRowBlock *))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc buffers", K(ret), K(task_channels_.count()));
|
||||
} else if (OB_ISNULL(heads_ = static_cast<int64_t *> (px_row_allocator_.alloc(task_channels_.count()
|
||||
* sizeof(int64_t))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc heads", K(ret), K(task_channels_.count()));
|
||||
} else if (OB_ISNULL(tails_ = static_cast<int64_t *> (px_row_allocator_.alloc(task_channels_.count()
|
||||
* sizeof(int64_t))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc tails", K(ret), K(task_channels_.count()));
|
||||
} else if (OB_ISNULL(init_pos_ = static_cast<int64_t *> (px_row_allocator_.alloc(task_channels_.count()
|
||||
* sizeof(int64_t))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc init sizes", K(ret), K(task_channels_.count()));
|
||||
} else if (OB_ISNULL(channel_unobstructeds_ = static_cast<bool *> (px_row_allocator_.alloc(task_channels_.count()
|
||||
* sizeof(bool))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc can adds", K(ret), K(task_channels_.count()));
|
||||
} else {
|
||||
memset(blocks_, 0, task_channels_.count() * sizeof(ObTempRowStore::DtlRowBlock *));
|
||||
memset(heads_, 0, task_channels_.count() * sizeof(int64_t));
|
||||
memset(tails_, 0, task_channels_.count() * sizeof(int64_t));
|
||||
memset(init_pos_, 0, task_channels_.count() * sizeof(int64_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -867,7 +916,7 @@ int ObPxTransmitOp::send_rows_in_vector(ObSliceIdxCalc &slice_calc)
|
||||
LOG_WARN("eval expr failed", K(ret));
|
||||
}
|
||||
}
|
||||
if (use_hash_reorder_) {
|
||||
if (use_hash_reorder_ || init_hash_reorder_struct_) {
|
||||
memset(slice_bkt_item_cnts_, 0, task_channels_.count() * sizeof(uint16_t));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < brs_.size_; i++) {
|
||||
@ -887,7 +936,7 @@ int ObPxTransmitOp::send_rows_in_vector(ObSliceIdxCalc &slice_calc)
|
||||
&& OB_FAIL(slice_calc.get_previous_row_tablet_id(tablet_id))) {
|
||||
LOG_WARN("failed to get previous row tablet_id", K(ret));
|
||||
}
|
||||
if (!use_hash_reorder_) {
|
||||
if (!use_hash_reorder_ && !init_hash_reorder_struct_) {
|
||||
LOG_DEBUG("[VEC2.0 PX] send rows vec without prefetch", K(i), K(slice_idx_array), K(tablet_id.get_int()));
|
||||
FOREACH_CNT_X(slice_idx, slice_idx_array, OB_SUCC(ret)) {
|
||||
if (OB_FAIL(send_row(*slice_idx, send_row_time_recorder, tablet_id.get_int(), i))) {
|
||||
@ -906,7 +955,7 @@ int ObPxTransmitOp::send_rows_in_vector(ObSliceIdxCalc &slice_calc)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && use_hash_reorder_) {
|
||||
if (OB_SUCC(ret) && (use_hash_reorder_ || init_hash_reorder_struct_)) {
|
||||
if (OB_FAIL(hash_reorder_send_batch(batch_info_guard))) {
|
||||
LOG_WARN("failed to send batch", K(ret));
|
||||
}
|
||||
@ -943,7 +992,7 @@ int ObPxTransmitOp::send_rows_in_vector(ObSliceIdxCalc &slice_calc)
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (!disable_fast_append_ && use_hash_reorder_) {
|
||||
} else if (use_hash_reorder_) {
|
||||
memset(slice_bkt_item_cnts_, 0, task_channels_.count() * sizeof(uint16_t));
|
||||
for (int64_t i = 0; i < brs_.size_; ++i) {
|
||||
if (brs_.skip_->at(i)) {
|
||||
@ -960,18 +1009,8 @@ int ObPxTransmitOp::send_rows_in_vector(ObSliceIdxCalc &slice_calc)
|
||||
if (OB_FAIL(hash_reorder_send_batch(batch_info_guard))) {
|
||||
LOG_WARN("failed to send batch", K(ret));
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < brs_.size_; i++) {
|
||||
if (brs_.skip_->at(i)) {
|
||||
continue;
|
||||
}
|
||||
batch_info_guard.set_batch_idx(i);
|
||||
metric_.count();
|
||||
int64_t slice_idx = indexes[i];
|
||||
if (OB_FAIL(send_row(indexes[i], send_row_time_recorder, tablet_id.get_int(), i))) {
|
||||
LOG_WARN("fail emit row to interm result", K(ret), K(indexes[i]));
|
||||
}
|
||||
}
|
||||
} else if (OB_FAIL(keep_order_send_batch(batch_info_guard, indexes))) {
|
||||
LOG_WARN("failed to send batch", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1006,6 +1045,102 @@ int ObPxTransmitOp::send_rows_in_vector(ObSliceIdxCalc &slice_calc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObPxTransmitOp::fill_batch_ptrs(const int64_t *indexes)
|
||||
{
|
||||
for (int64_t i = 0; i < brs_.size_; ++i) {
|
||||
if (brs_.skip_->at(i)) {
|
||||
continue;
|
||||
}
|
||||
if (ObSliceIdxCalc::DEFAULT_CHANNEL_IDX_TO_DROP_ROW == indexes[i]) {
|
||||
op_monitor_info_.otherstat_1_value_++;
|
||||
op_monitor_info_.otherstat_1_id_ = ObSqlMonitorStatIds::EXCHANGE_DROP_ROW_COUNT;
|
||||
} else {
|
||||
int64_t slice_idx = indexes[i];
|
||||
const int64_t row_size = row_size_array_[i];
|
||||
const int64_t head_pos = heads_[slice_idx];
|
||||
ObTempRowStore::DtlRowBlock *block = blocks_[slice_idx];
|
||||
if (nullptr == block
|
||||
|| !channel_unobstructeds_[slice_idx]
|
||||
|| row_size > tails_[slice_idx] - head_pos) {
|
||||
fallback_array_[fallback_cnt_++] = i;
|
||||
channel_unobstructeds_[slice_idx] = false;
|
||||
} else {
|
||||
ObCompactRow *ptr = reinterpret_cast<ObCompactRow *> (reinterpret_cast<char *> (block) + head_pos);
|
||||
return_rows_[selector_cnt_] = ptr;
|
||||
heads_[slice_idx] += row_size;
|
||||
const static int64_t MEMSET_SIZE = 128;
|
||||
while (heads_[slice_idx] > init_pos_[slice_idx]) {
|
||||
if (init_pos_[slice_idx] + MEMSET_SIZE < tails_[slice_idx]) {
|
||||
memset(reinterpret_cast<char *> (block) + init_pos_[slice_idx], 0, MEMSET_SIZE);
|
||||
init_pos_[slice_idx] += MEMSET_SIZE;
|
||||
} else {
|
||||
memset(ptr, 0, row_size);
|
||||
init_pos_[slice_idx] = heads_[slice_idx];
|
||||
}
|
||||
}
|
||||
block->cnt_ += 1;
|
||||
selector_array_[selector_cnt_++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ObPxTransmitOp::keep_order_send_batch(ObEvalCtx::BatchInfoScopeGuard &batch_info_guard, const int64_t *indexes)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t send_row_time_recorder = 0;
|
||||
ObObj tablet_id; //not used
|
||||
fallback_cnt_ = 0;
|
||||
selector_cnt_ = 0;
|
||||
if (vectors_.empty()) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < get_spec().output_.count(); ++i) {
|
||||
OZ (vectors_.push_back(get_spec().output_.at(i)->get_vector(eval_ctx_)));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(ObTempRowStore::DtlRowBlock::calc_rows_size(vectors_, meta_,
|
||||
brs_, row_size_array_))) {
|
||||
LOG_WARN("failed to calc size", K(ret));
|
||||
} else {
|
||||
fill_batch_ptrs(indexes);
|
||||
for (int64_t i = 0; i < selector_cnt_; ++i) {
|
||||
return_rows_[i]->set_row_size(row_size_array_[selector_array_[i]]);
|
||||
}
|
||||
for (int64_t idx = 0; idx < get_spec().output_.count(); ++idx) {
|
||||
vectors_.at(idx)->to_rows(meta_, return_rows_,
|
||||
selector_array_, selector_cnt_, idx);
|
||||
}
|
||||
for (int64_t idx = 0; idx < task_channels_.count(); ++idx) {
|
||||
if (nullptr != blocks_[idx]) {
|
||||
blocks_[idx]->get_buffer()->fast_update_head(heads_[idx]);
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < fallback_cnt_; i++) {
|
||||
batch_info_guard.set_batch_idx(fallback_array_[i]);
|
||||
metric_.count();
|
||||
int64_t slice_idx = indexes[fallback_array_[i]];
|
||||
ObDtlBasicChannel *channel =
|
||||
static_cast<ObDtlBasicChannel *> (task_channels_.at(slice_idx));
|
||||
ObDtlVectorRowMsgWriter &row_writer = channel->get_vector_row_writer();
|
||||
if (nullptr != row_writer.get_write_buffer()) {
|
||||
row_writer.get_write_buffer()->pos() = row_writer.used();
|
||||
}
|
||||
if (OB_FAIL(send_row(slice_idx, send_row_time_recorder, tablet_id.get_int(), fallback_array_[i]))) {
|
||||
LOG_WARN("fail emit row to interm result", K(ret), K(slice_idx));
|
||||
} else {
|
||||
blocks_[slice_idx] = static_cast<ObDtlBasicChannel *> (task_channels_.at(slice_idx))->get_vector_row_writer().get_block();
|
||||
if (nullptr != blocks_[slice_idx]) {
|
||||
heads_[slice_idx] = blocks_[slice_idx]->get_buffer()->head_pos();
|
||||
tails_[slice_idx] = blocks_[slice_idx]->get_buffer()->tail_pos();
|
||||
init_pos_[slice_idx] = heads_[slice_idx];
|
||||
channel_unobstructeds_[slice_idx] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPxTransmitOp::send_eof_row()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -1128,7 +1263,7 @@ int ObPxTransmitOp::send_row(int64_t slice_idx,
|
||||
op_monitor_info_.otherstat_1_value_++;
|
||||
op_monitor_info_.otherstat_1_id_ = ObSqlMonitorStatIds::EXCHANGE_DROP_ROW_COUNT;
|
||||
// TODO: shanting2.0. use opt when DTL 2.0 implemented.
|
||||
} else if (!is_vectorized() || disable_fast_append_) {
|
||||
} else if (!is_vectorized()) {
|
||||
is_send_row_normal = true;
|
||||
} else if (get_spec().use_rich_format_) {
|
||||
if (NULL != spec.tablet_id_expr_) {
|
||||
@ -1155,17 +1290,7 @@ int ObPxTransmitOp::send_row(int64_t slice_idx,
|
||||
break;
|
||||
}
|
||||
case dtl::ObDtlMsgType::PX_VECTOR_ROW: {
|
||||
ObDtlVectorRowMsgWriter &row_writer = channel->get_vector_row_writer();
|
||||
if (!row_writer.is_inited()) {
|
||||
is_send_row_normal = true;
|
||||
} else if (OB_FAIL(row_writer.try_append_row(spec.output_, eval_ctx_))) {
|
||||
if (OB_BUF_NOT_ENOUGH != ret) {
|
||||
LOG_WARN("failed to append row", K(ret));
|
||||
} else {
|
||||
is_send_row_normal = true;
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
is_send_row_normal = true;
|
||||
break;
|
||||
}
|
||||
case dtl::ObDtlMsgType::PX_VECTOR: {
|
||||
@ -1540,8 +1665,6 @@ void ObPxTransmitOp::init_data_msg_type(const common::ObIArray<ObExpr *> &output
|
||||
data_msg_type_ = dtl::ObDtlMsgType::PX_VECTOR_FIXED;
|
||||
} else if (3 == std::abs(err_sim)) {
|
||||
data_msg_type_ = dtl::ObDtlMsgType::PX_VECTOR;
|
||||
} else if (4 == std::abs(err_sim)) {
|
||||
disable_fast_append_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1601,7 +1724,6 @@ int ObPxTransmitOp::hash_reorder_send_batch(ObEvalCtx::BatchInfoScopeGuard &batc
|
||||
}
|
||||
break;
|
||||
}
|
||||
case dtl::ObDtlMsgType::PX_VECTOR:
|
||||
case dtl::ObDtlMsgType::PX_VECTOR_ROW: {
|
||||
for (int64_t channel_idx = 0; OB_SUCC(ret) && channel_idx < task_channels_.count(); ++channel_idx) {
|
||||
if (0 == slice_bkt_item_cnts_[channel_idx]) {
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "sql/engine/px/ob_px_basic_info.h"
|
||||
#include "sql/engine/basic/ob_ra_datum_store.h"
|
||||
#include "sql/engine/px/datahub/components/ob_dh_init_channel.h"
|
||||
#include "sql/engine/basic/ob_compact_row.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -176,6 +177,7 @@ private:
|
||||
int set_expect_range_count();
|
||||
int wait_channel_ready_msg();
|
||||
int hash_reorder_send_batch(ObEvalCtx::BatchInfoScopeGuard &batch_info_guard);
|
||||
int keep_order_send_batch(ObEvalCtx::BatchInfoScopeGuard &batch_info_guard, const int64_t *indexes);
|
||||
int64_t get_random_seq()
|
||||
{
|
||||
return nrand48(rand48_buf_) % INT16_MAX;
|
||||
@ -189,6 +191,7 @@ private:
|
||||
&& !proxy.get_transmit_use_interm_result(); }
|
||||
int try_wait_channel();
|
||||
void init_data_msg_type(const common::ObIArray<ObExpr *> &output);
|
||||
void fill_batch_ptrs(const int64_t *indexes);
|
||||
dtl::ObDtlMsgType get_data_msg_type() const { return data_msg_type_; }
|
||||
protected:
|
||||
ObArray<ObChunkDatumStore::Block *> ch_blocks_;
|
||||
@ -226,15 +229,24 @@ protected:
|
||||
unsigned short rand48_buf_[3];
|
||||
bool receive_channel_ready_;
|
||||
dtl::ObDtlMsgType data_msg_type_;
|
||||
bool disable_fast_append_;
|
||||
//slice_idx, batch_idx
|
||||
uint16_t **slice_info_bkts_;
|
||||
uint16_t *slice_bkt_item_cnts_;
|
||||
ObFixedArray<ObIVector *, common::ObIAllocator> vectors_;
|
||||
uint16_t *selector_array_;
|
||||
int64_t selector_cnt_;
|
||||
uint32_t *row_size_array_;
|
||||
ObCompactRow **return_rows_;
|
||||
bool use_hash_reorder_;
|
||||
RowMeta meta_;
|
||||
uint16_t *fallback_array_;
|
||||
int64_t fallback_cnt_;
|
||||
ObTempRowStore::DtlRowBlock **blocks_;
|
||||
int64_t *heads_;
|
||||
int64_t *tails_;
|
||||
int64_t *init_pos_; //memset from this pos
|
||||
bool *channel_unobstructeds_;
|
||||
bool init_hash_reorder_struct_;
|
||||
};
|
||||
|
||||
inline void ObPxTransmitOp::update_row(const ObExpr *expr, int64_t tablet_id)
|
||||
|
@ -154,8 +154,8 @@ int ObPxAdmission::enter_query_admission(ObSQLSessionInfo &session,
|
||||
} else if (admit_worker_count <= 0) {
|
||||
plan.inc_delayed_px_querys();
|
||||
ret = OB_ERR_INSUFFICIENT_PX_WORKER;
|
||||
LOG_INFO("It's a px query, out of px worker resource, "
|
||||
"need delay, do not need disconnect",
|
||||
LOG_INFO("This query is out of px worker resources and needs to be delayed; "
|
||||
"disconnection is unnecessary.",
|
||||
K(admit_worker_count),
|
||||
K(plan.get_px_dop()),
|
||||
K(plan.get_plan_id()),
|
||||
|
@ -27,14 +27,27 @@ using namespace obrpc;
|
||||
#define MIN_FILTER_SIZE 256
|
||||
#define MAX_BIT_COUNT 17179869184// 2^34 due to the memory single alloc limit
|
||||
#define BF_BLOCK_SIZE 256L
|
||||
#define BLOCK_MASK 255L // = size of block - 1
|
||||
#define CACHE_LINE_SIZE 64 // 64 bytes
|
||||
#define LOG_CACHE_LINE_SIZE 6 // = log2(CACHE_LINE_SIZE)
|
||||
|
||||
#define FIXED_HASH_COUNT 4
|
||||
#define LOG_HASH_COUNT 2 // = log2(FIXED_HASH_COUNT)
|
||||
#define WORD_SIZE 64 // WORD_SIZE * FIXED_HASH_COUNT = BF_BLOCK_SIZE
|
||||
#define HASH_SHIFT_MASK 63
|
||||
#define BLOCK_FILTER_HASH_MASK 0x3F3F3F3F // for each 8 bits, we only use the last 6 bits
|
||||
|
||||
class BloomFilterPrefetchOP
|
||||
{
|
||||
public:
|
||||
BloomFilterPrefetchOP(ObPxBloomFilter *bloom_filter, uint64_t *hash_values)
|
||||
: bloom_filter_(bloom_filter), hash_values_(hash_values)
|
||||
{}
|
||||
OB_INLINE int operator()(int64_t i) {
|
||||
(void)bloom_filter_->prefetch_bits_block(hash_values_[i]);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
private:
|
||||
ObPxBloomFilter *bloom_filter_;
|
||||
uint64_t *hash_values_;
|
||||
};
|
||||
|
||||
// before assign, please set allocator for channel_ids_ first
|
||||
int BloomFilterIndex::assign(const BloomFilterIndex &other)
|
||||
@ -103,6 +116,7 @@ int ObPxBloomFilter::assign(const ObPxBloomFilter &filter, int64_t tenant_id)
|
||||
set_allocator_attr(tenant_id);
|
||||
data_length_ = filter.data_length_;
|
||||
max_bit_count_ = filter.max_bit_count_;
|
||||
block_mask_ = filter.block_mask_;
|
||||
bits_count_ = filter.bits_count_;
|
||||
fpp_ = filter.fpp_;
|
||||
hash_func_count_ = filter.hash_func_count_;
|
||||
@ -140,6 +154,7 @@ int ObPxBloomFilter::init(const ObPxBloomFilter *filter)
|
||||
} else {
|
||||
data_length_ = filter->data_length_;
|
||||
max_bit_count_ = filter->max_bit_count_;
|
||||
block_mask_ = filter->block_mask_;
|
||||
bits_count_ = filter->bits_count_;
|
||||
fpp_ = filter->fpp_;
|
||||
hash_func_count_ = filter->hash_func_count_;
|
||||
@ -176,6 +191,7 @@ void ObPxBloomFilter::calc_num_of_bits()
|
||||
|
||||
// min size is block size = 256.
|
||||
bits_count_ = ((n < MIN_FILTER_SIZE) ? MIN_FILTER_SIZE : (n >= max_bit_count_) ? max_bit_count_ : n + 1);
|
||||
block_mask_ = (bits_count_ >> (LOG_HASH_COUNT + 6)) - 1;
|
||||
LOG_TRACE("calc num of bits", K(data_length_), K(fpp_), K(old_n), K(ori_n), K(bits_count_));
|
||||
}
|
||||
|
||||
@ -203,12 +219,13 @@ int ObPxBloomFilter::put(uint64_t hash)
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("the px bloom filter is not inited", K(ret));
|
||||
} else {
|
||||
uint32_t hash_high = (uint32_t)(hash >> 32);
|
||||
uint64_t block_begin = (hash & ((bits_count_ >> (LOG_HASH_COUNT + 6)) - 1)) << LOG_HASH_COUNT;
|
||||
(void)set(block_begin, 1L << (hash_high & HASH_SHIFT_MASK));
|
||||
(void)set(block_begin + 1, 1L << ((hash_high >> 8) & HASH_SHIFT_MASK));
|
||||
(void)set(block_begin + 2, 1L << ((hash_high >> 16) & HASH_SHIFT_MASK));
|
||||
(void)set(block_begin + 3, 1L << ((hash_high >> 24) & HASH_SHIFT_MASK));
|
||||
uint64_t block_begin = (hash & block_mask_) << LOG_HASH_COUNT;
|
||||
uint32_t hash_high = ((uint32_t)(hash >> 32) & BLOCK_FILTER_HASH_MASK);
|
||||
uint8_t *block_hash_vals = (uint8_t *)&hash_high;
|
||||
(void)set(block_begin, 1L << block_hash_vals[0]);
|
||||
(void)set(block_begin + 1, 1L << block_hash_vals[1]);
|
||||
(void)set(block_begin + 2, 1L << block_hash_vals[2]);
|
||||
(void)set(block_begin + 3, 1L << block_hash_vals[3]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -223,19 +240,62 @@ int ObPxBloomFilter::put_batch(ObPxBFHashArray &hash_val_array)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPxBloomFilter::put_batch(uint64_t *batch_hash_values, const EvalBound &bound,
|
||||
const ObBitVector &skip, bool &is_empty)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("the px bloom filter is not inited", K(ret));
|
||||
} else if (bound.get_all_rows_active()) {
|
||||
uint32_t hash_high = 0;
|
||||
uint8_t *block_hash_vals = (uint8_t *)&hash_high;
|
||||
for (int64_t i = bound.start(); i < bound.end(); ++i) {
|
||||
uint64_t block_begin = (batch_hash_values[i] & block_mask_) << LOG_HASH_COUNT;
|
||||
hash_high = ((uint32_t)(batch_hash_values[i] >> 32) & BLOCK_FILTER_HASH_MASK);
|
||||
(void)set(block_begin, 1L << block_hash_vals[0]);
|
||||
(void)set(block_begin + 1, 1L << block_hash_vals[1]);
|
||||
(void)set(block_begin + 2, 1L << block_hash_vals[2]);
|
||||
(void)set(block_begin + 3, 1L << block_hash_vals[3]);
|
||||
}
|
||||
if (is_empty && bound.end() - bound.start() > 0) {
|
||||
is_empty = false;
|
||||
}
|
||||
} else {
|
||||
uint32_t hash_high = 0;
|
||||
uint8_t *block_hash_vals = (uint8_t *)&hash_high;
|
||||
for (int64_t i = bound.start(); i < bound.end(); ++i) {
|
||||
if (skip.at(i)) {
|
||||
} else {
|
||||
uint64_t block_begin = (batch_hash_values[i] & block_mask_) << LOG_HASH_COUNT;
|
||||
hash_high = ((uint32_t)(batch_hash_values[i] >> 32) & BLOCK_FILTER_HASH_MASK);
|
||||
(void)set(block_begin, 1L << block_hash_vals[0]);
|
||||
(void)set(block_begin + 1, 1L << block_hash_vals[1]);
|
||||
(void)set(block_begin + 2, 1L << block_hash_vals[2]);
|
||||
(void)set(block_begin + 3, 1L << block_hash_vals[3]);
|
||||
if (is_empty) {
|
||||
is_empty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPxBloomFilter::might_contain_nonsimd(uint64_t hash, bool &is_match)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_match = true;
|
||||
uint32_t hash_high = (uint32_t)(hash >> 32);
|
||||
uint64_t block_begin = (hash & ((bits_count_ >> (LOG_HASH_COUNT + 6)) - 1)) << LOG_HASH_COUNT;
|
||||
if (!get(block_begin, 1L << (hash_high & HASH_SHIFT_MASK))) {
|
||||
uint64_t block_begin = (hash & block_mask_) << LOG_HASH_COUNT;
|
||||
uint32_t hash_high = ((uint32_t)(hash >> 32) & BLOCK_FILTER_HASH_MASK);
|
||||
uint8_t *block_hash_vals = (uint8_t *)&hash_high;
|
||||
if (!get(block_begin, 1L << block_hash_vals[0])) {
|
||||
is_match = false;
|
||||
} else if (!get(block_begin + 1, 1L << ((hash_high >> 8) & HASH_SHIFT_MASK))) {
|
||||
} else if (!get(block_begin + 1, 1L << block_hash_vals[1])) {
|
||||
is_match = false;
|
||||
} else if (!get(block_begin + 2, 1L << ((hash_high >> 16) & HASH_SHIFT_MASK))) {
|
||||
} else if (!get(block_begin + 2, 1L << block_hash_vals[2])) {
|
||||
is_match = false;
|
||||
} else if (!get(block_begin + 3, 1L << ((hash_high >> 24) & HASH_SHIFT_MASK))) {
|
||||
} else if (!get(block_begin + 3, 1L << block_hash_vals[3])) {
|
||||
is_match = false;
|
||||
}
|
||||
return ret;
|
||||
@ -266,7 +326,8 @@ int ObPxBloomFilter::merge_filter(ObPxBloomFilter *filter)
|
||||
do {
|
||||
old_v = bits_array_[i + filter->begin_idx_];
|
||||
new_v = old_v | filter->bits_array_[i];
|
||||
} while(ATOMIC_CAS(&bits_array_[i + filter->begin_idx_], old_v, new_v) != old_v);
|
||||
} while (old_v != new_v // do not write if old is equal to new
|
||||
&& ATOMIC_CAS(&bits_array_[i + filter->begin_idx_], old_v, new_v) != old_v);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -388,12 +449,6 @@ void ObPxBloomFilter::reset()
|
||||
allocator_.reset();
|
||||
}
|
||||
|
||||
void ObPxBloomFilter::prefetch_bits_block(uint64_t hash)
|
||||
{
|
||||
uint64_t block_begin = (hash & ((bits_count_ >> (LOG_HASH_COUNT + 6)) - 1)) << LOG_HASH_COUNT;
|
||||
__builtin_prefetch(&bits_array_[block_begin], 0);
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE(ObPxBloomFilter)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -452,6 +507,7 @@ OB_DEF_DESERIALIZE(ObPxBloomFilter)
|
||||
}
|
||||
}
|
||||
OB_UNIS_DECODE(max_bit_count_);
|
||||
block_mask_ = (bits_count_ >> (LOG_HASH_COUNT + 6)) - 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -475,10 +531,177 @@ OB_DEF_SERIALIZE_SIZE(ObPxBloomFilter)
|
||||
return len;
|
||||
}
|
||||
|
||||
void ObPxBloomFilter::dump_filter()
|
||||
{
|
||||
LOG_INFO("dump px bloom filter info:", K(*this));
|
||||
}
|
||||
void ObPxBloomFilter::dump_filter()
|
||||
{
|
||||
LOG_INFO("dump px bloom filter info:", K(*this));
|
||||
}
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
OB_DECLARE_DEFAULT_AND_AVX512_CODE(
|
||||
|
||||
template <bool SUPPORT_SIMD, typename ResVec>
|
||||
class BloomFilterProbeOP
|
||||
{
|
||||
public:
|
||||
BloomFilterProbeOP(ResVec *res_vec, ObPxBloomFilter *bloom_filter, int64_t *bits_array,
|
||||
int64_t block_mask, uint64_t *hash_values, int64_t &total_count,
|
||||
int64_t &filter_count)
|
||||
: res_vec_(res_vec), bloom_filter_(bloom_filter), bits_array_(bits_array),
|
||||
block_mask_(block_mask), hash_values_(hash_values), total_count_(total_count),
|
||||
filter_count_(filter_count)
|
||||
{}
|
||||
int operator()(int64_t i)
|
||||
{
|
||||
bool is_match = false;
|
||||
constexpr int64_t is_match_payload = 1;
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
if (SUPPORT_SIMD) {
|
||||
(void)common::specific::avx512::inline_might_contain_simd(bits_array_, block_mask_,
|
||||
hash_values_[i], is_match);
|
||||
} else {
|
||||
#endif
|
||||
(void)bloom_filter_->might_contain_nonsimd(hash_values_[i], is_match);
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
}
|
||||
#endif
|
||||
++total_count_;
|
||||
if (!is_match) {
|
||||
++filter_count_;
|
||||
if (std::is_same<ResVec, IntegerUniVec>::value) {
|
||||
res_vec_->set_int(i, 0);
|
||||
}
|
||||
} else {
|
||||
if (std::is_same<ResVec, IntegerUniVec>::value) {
|
||||
res_vec_->set_int(i, 1);
|
||||
} else {
|
||||
res_vec_->set_payload(i, &is_match_payload, sizeof(int64_t));
|
||||
}
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
private:
|
||||
ResVec *res_vec_;
|
||||
ObPxBloomFilter *bloom_filter_;
|
||||
int64_t *bits_array_;
|
||||
int64_t block_mask_;
|
||||
uint64_t *hash_values_;
|
||||
int64_t &total_count_;
|
||||
int64_t &filter_count_;
|
||||
};
|
||||
|
||||
template <bool ALL_ROWS_ACTIVE, bool SUPPORT_SIMD, typename ResVec>
|
||||
int inner_might_contain(ObPxBloomFilter *bloom_filter, int64_t *bits_array,
|
||||
int64_t block_mask, const ObExpr &expr, ObEvalCtx &ctx,
|
||||
const ObBitVector &skip, const EvalBound &bound,
|
||||
uint64_t *hash_values, int64_t &total_count,
|
||||
int64_t &filter_count) {
|
||||
int ret = OB_SUCCESS;
|
||||
ResVec *res_vec = static_cast<ResVec *>(expr.get_vector(ctx));
|
||||
static const int64_t is_match_payload = 1;
|
||||
bool is_match = true;
|
||||
if (std::is_same<ResVec, IntegerFixedVec>::value) {
|
||||
IntegerFixedVec *int_fixed_vec = reinterpret_cast<IntegerFixedVec *>(res_vec);
|
||||
uint64_t *data = reinterpret_cast<uint64_t *>(int_fixed_vec->get_data());
|
||||
MEMSET(data + bound.start(), 0, (bound.range_size() * res_vec->get_length(0)));
|
||||
}
|
||||
|
||||
if (ALL_ROWS_ACTIVE) {
|
||||
total_count += bound.end() - bound.start();
|
||||
for (int64_t i = bound.start(); i < bound.end(); ++i) {
|
||||
(void)bloom_filter->prefetch_bits_block(hash_values[i]);
|
||||
}
|
||||
for (int64_t i = bound.start(); i < bound.end(); ++i) {
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
if (SUPPORT_SIMD) {
|
||||
(void)specific::avx512::inline_might_contain_simd(bits_array, block_mask, hash_values[i],
|
||||
is_match);
|
||||
} else {
|
||||
#endif
|
||||
(void)bloom_filter->might_contain_nonsimd(hash_values[i], is_match);
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
}
|
||||
#endif
|
||||
if (!is_match) {
|
||||
filter_count += 1;
|
||||
if (std::is_same<ResVec, IntegerUniVec>::value) {
|
||||
res_vec->set_int(i, 0);
|
||||
}
|
||||
} else {
|
||||
if (std::is_same<ResVec, IntegerUniVec>::value) {
|
||||
res_vec->set_int(i, 1);
|
||||
} else {
|
||||
res_vec->set_payload(i, &is_match_payload, sizeof(int64_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BloomFilterPrefetchOP prefetch_op(bloom_filter, hash_values);
|
||||
BloomFilterProbeOP<SUPPORT_SIMD, ResVec> probe_op(res_vec, bloom_filter, bits_array, block_mask,
|
||||
hash_values, total_count, filter_count);
|
||||
(void)ObBitVector::flip_foreach(skip, bound, prefetch_op);
|
||||
(void)ObBitVector::flip_foreach(skip, bound, probe_op);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
)
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
|
||||
#define BLOOM_FILTER_DISPATCH_ALL_ROWS_ACTIVATE(function, all_rows_active, support_simd, \
|
||||
res_format) \
|
||||
if (all_rows_active) { \
|
||||
BLOOM_FILTER_DISPATCH_SIMD(function, true, support_simd, res_format) \
|
||||
} else { \
|
||||
BLOOM_FILTER_DISPATCH_SIMD(function, false, support_simd, res_format) \
|
||||
}
|
||||
|
||||
#define BLOOM_FILTER_DISPATCH_SIMD(function, all_rows_active, support_simd, res_format) \
|
||||
if (support_simd) { \
|
||||
BLOOM_FILTER_DISPATCH_RES_FORMAT(function, all_rows_active, true, res_format) \
|
||||
} else { \
|
||||
BLOOM_FILTER_DISPATCH_RES_FORMAT(function, all_rows_active, false, res_format) \
|
||||
}
|
||||
|
||||
#define BLOOM_FILTER_DISPATCH_RES_FORMAT(function, all_rows_active, support_simd, res_format) \
|
||||
if (res_format == VEC_FIXED) { \
|
||||
ret = function<all_rows_active, support_simd, IntegerFixedVec>( \
|
||||
this, bits_array_, block_mask_, expr, ctx, skip, bound, hash_values, total_count, \
|
||||
filter_count); \
|
||||
} else { \
|
||||
ret = function<all_rows_active, support_simd, IntegerUniVec>( \
|
||||
this, bits_array_, block_mask_, expr, ctx, skip, bound, hash_values, total_count, \
|
||||
filter_count); \
|
||||
}
|
||||
|
||||
int ObPxBloomFilter::might_contain_vector(const ObExpr &expr, ObEvalCtx &ctx,
|
||||
const ObBitVector &skip, const EvalBound &bound,
|
||||
uint64_t *hash_values, int64_t &total_count,
|
||||
int64_t &filter_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool all_rows_active = bound.get_all_rows_active();
|
||||
VectorFormat res_format = expr.get_format(ctx);
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
if (common::is_arch_supported(ObTargetArch::AVX512)) {
|
||||
constexpr bool support_simd = true;
|
||||
BLOOM_FILTER_DISPATCH_ALL_ROWS_ACTIVATE(common::specific::avx512::inner_might_contain,
|
||||
all_rows_active, support_simd, res_format)
|
||||
} else {
|
||||
#endif
|
||||
constexpr bool support_simd = false;
|
||||
BLOOM_FILTER_DISPATCH_ALL_ROWS_ACTIVATE(common::specific::normal::inner_might_contain,
|
||||
all_rows_active, support_simd, res_format)
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-------------------------------------分割线----------------------------
|
||||
int ObPxBFStaticInfo::init(int64_t tenant_id, int64_t filter_id,
|
||||
int64_t server_id, bool is_shared,
|
||||
|
@ -19,6 +19,13 @@
|
||||
#include "lib/lock/ob_spin_lock.h"
|
||||
#include "share/config/ob_server_config.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
#include "common/ob_target_specific.h"
|
||||
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
#include <emmintrin.h>
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
#ifndef __SQL_ENG_PX_BLOOM_FILTER_H__
|
||||
#define __SQL_ENG_PX_BLOOM_FILTER_H__
|
||||
|
||||
@ -27,6 +34,8 @@ namespace oceanbase
|
||||
namespace sql
|
||||
{
|
||||
|
||||
#define LOG_HASH_COUNT 2 // = log2(FIXED_HASH_COUNT)
|
||||
|
||||
typedef common::ObSEArray<uint64_t, 128> ObPxBFHashArray;
|
||||
|
||||
struct BloomFilterReceiveCount
|
||||
@ -66,8 +75,12 @@ public:
|
||||
inline int might_contain(uint64_t hash, bool &is_match) {
|
||||
return (this->*might_contain_)(hash, is_match);
|
||||
}
|
||||
int might_contain_vector(const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip,
|
||||
const EvalBound &bound, uint64_t *hash_values, int64_t &total_count,
|
||||
int64_t &filter_count);
|
||||
int put(uint64_t hash);
|
||||
int put_batch(ObPxBFHashArray &hash_val_array);
|
||||
int put_batch(uint64_t *batch_hash_values, const EvalBound &bound, const ObBitVector &skip, bool &is_empty);
|
||||
int merge_filter(ObPxBloomFilter *filter);
|
||||
int64_t get_value_true_count() const { return true_count_; };
|
||||
void dump_filter(); //for debug
|
||||
@ -88,13 +101,18 @@ public:
|
||||
void set_end_idx(int64_t idx) { end_idx_ = idx; }
|
||||
int64_t get_begin_idx() const { return begin_idx_; }
|
||||
int64_t get_end_idx() const { return end_idx_; }
|
||||
void prefetch_bits_block(uint64_t hash);
|
||||
inline void prefetch_bits_block(uint64_t hash)
|
||||
{
|
||||
uint64_t block_begin = (hash & block_mask_) << LOG_HASH_COUNT;
|
||||
__builtin_prefetch(&bits_array_[block_begin], 0);
|
||||
}
|
||||
typedef int (ObPxBloomFilter::*GetFunc)(uint64_t hash, bool &is_match);
|
||||
int generate_receive_count_array(int64_t piece_size);
|
||||
void reset();
|
||||
int assign(const ObPxBloomFilter &filter, int64_t tenant_id);
|
||||
int regenerate();
|
||||
void set_allocator_attr(int64_t tenant_id);
|
||||
int might_contain_nonsimd(uint64_t hash, bool &is_match);
|
||||
TO_STRING_KV(K_(data_length), K_(bits_count), K_(fpp), K_(hash_func_count), K_(is_inited),
|
||||
K_(bits_array_length), K_(true_count));
|
||||
private:
|
||||
@ -103,9 +121,12 @@ private:
|
||||
void calc_num_of_hash_func();
|
||||
void calc_num_of_bits();
|
||||
void align_max_bit_count(int64_t max_filter_size);
|
||||
int might_contain_nonsimd(uint64_t hash, bool &is_match);
|
||||
int might_contain_simd(uint64_t hash, bool &is_match);
|
||||
|
||||
#ifdef unittest_bloom_filter
|
||||
int might_contain_batch(uint64_t *hash_values, int64_t batch_size);
|
||||
#endif
|
||||
|
||||
private:
|
||||
int64_t data_length_; //原始数据长度
|
||||
int64_t max_bit_count_; // max filter size, default 2GB, so the max bit count = 17179869184;
|
||||
@ -127,6 +148,7 @@ public:
|
||||
int64_t px_bf_recieve_size_; // 预期应该收到的个数
|
||||
volatile int64_t px_bf_merge_filter_count_; // 当前持有filter, 做merge filter操作的线程个数
|
||||
ObArray<BloomFilterReceiveCount> receive_count_array_;
|
||||
int64_t block_mask_; // for locating block
|
||||
DISALLOW_COPY_AND_ASSIGN(ObPxBloomFilter);
|
||||
};
|
||||
|
||||
@ -307,7 +329,58 @@ private:
|
||||
int process_px_bloom_filter_data();
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
|
||||
namespace common
|
||||
{
|
||||
OB_DECLARE_AVX512_SPECIFIC_CODE(OB_INLINE void inline_might_contain_simd(
|
||||
int64_t *bits_array, int64_t block_mask, uint64_t hash, bool &is_match) {
|
||||
static const __m256i HASH_VALUES_MASK = _mm256_set_epi64x(24, 16, 8, 0);
|
||||
uint32_t hash_high = (uint32_t)(hash >> 32);
|
||||
uint64_t block_begin = (hash & block_mask) << LOG_HASH_COUNT;
|
||||
__m256i bit_ones = _mm256_set1_epi64x(1);
|
||||
__m256i hash_values = _mm256_set1_epi64x(hash_high);
|
||||
hash_values = _mm256_srlv_epi64(hash_values, HASH_VALUES_MASK);
|
||||
hash_values = _mm256_rolv_epi64(bit_ones, hash_values);
|
||||
__m256i bf_values = _mm256_load_si256(reinterpret_cast<__m256i *>(&bits_array[block_begin]));
|
||||
is_match = 1 == _mm256_testz_si256(~bf_values, hash_values);
|
||||
})
|
||||
|
||||
#ifdef unittest_bloom_filter
|
||||
OB_DECLARE_AVX512_SPECIFIC_CODE(void might_contain_batch_simd(
|
||||
sql::ObPxBloomFilter *bloom_filter, int64_t *bits_array, int64_t block_mask, uint64_t *hash_values,
|
||||
const int64_t &batch_size) {
|
||||
bool is_match;
|
||||
for (int64_t i = 0; i < batch_size; ++i) {
|
||||
common::specific::avx512::inline_might_contain_simd(bits_array, block_mask, hash_values[i],
|
||||
is_match);
|
||||
}
|
||||
})
|
||||
#endif
|
||||
} // namespace common
|
||||
|
||||
namespace sql {
|
||||
#ifdef unittest_bloom_filter
|
||||
int ObPxBloomFilter::might_contain_batch(uint64_t *hash_values, int64_t batch_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_match;
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
if (common::is_arch_supported(ObTargetArch::AVX512)) {
|
||||
common::specific::avx512::might_contain_batch_simd(this, bits_array_, block_mask_, hash_values,
|
||||
batch_size);
|
||||
} else {
|
||||
#endif
|
||||
for (int64_t i = 0; i < batch_size; ++i) {
|
||||
might_contain_nonsimd(hash_values[i], is_match);
|
||||
}
|
||||
#if OB_USE_MULTITARGET_CODE
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
} // namespace sql
|
||||
|
||||
} //end oceanbase
|
||||
#endif
|
||||
|
@ -26,15 +26,7 @@ int ObPxBloomFilter::might_contain_simd(uint64_t hash, bool &is_match)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
#if defined(__x86_64__)
|
||||
static const __m256i HASH_VALUES_MASK = _mm256_set_epi64x(24, 16, 8, 0);
|
||||
uint32_t hash_high = (uint32_t)(hash >> 32);
|
||||
uint64_t block_begin = (hash & ((bits_count_ >> (LOG_HASH_COUNT + 6)) - 1)) << LOG_HASH_COUNT;
|
||||
__m256i bit_ones = _mm256_set1_epi64x(1);
|
||||
__m256i hash_values = _mm256_set1_epi64x(hash_high);
|
||||
hash_values = _mm256_srlv_epi64(hash_values, HASH_VALUES_MASK);
|
||||
hash_values = _mm256_rolv_epi64(bit_ones, hash_values);
|
||||
__m256i bf_values = _mm256_load_si256(reinterpret_cast<__m256i *>(&bits_array_[block_begin]));
|
||||
is_match = 1 == _mm256_testz_si256(~bf_values, hash_values);
|
||||
specific::avx512::inline_might_contain_simd(bits_array_, block_mask_, hash, is_match);
|
||||
#else
|
||||
ret = might_contain_nonsimd(hash, is_match);
|
||||
#endif
|
||||
|
@ -755,8 +755,26 @@ int ObRFBloomFilterMsg::fill_vec_result(ResVec *res_vec, const ObBitVector &skip
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_match = true;
|
||||
const int64_t is_match_payload = 1; // for VEC_FIXED set set_payload, always 1
|
||||
if (OB_FAIL(ObBitVector::flip_foreach(
|
||||
static const int64_t is_match_payload = 1; // for set_payload, always 1
|
||||
if (bound.get_all_rows_active()) {
|
||||
for (int64_t i = bound.start(); i < bound.end(); ++i) {
|
||||
(void)bloom_filter_.prefetch_bits_block(hash_values[i]);
|
||||
}
|
||||
for (int64_t i = bound.start(); i < bound.end(); ++i) {
|
||||
(void)bloom_filter_.might_contain(hash_values[i], is_match);
|
||||
if (is_match) {
|
||||
if (ResFormat == VEC_FIXED) {
|
||||
res_vec->set_payload(i, &is_match_payload, sizeof(int64_t));
|
||||
} else {
|
||||
res_vec->set_int(i, is_match_payload);
|
||||
}
|
||||
} else {
|
||||
// already set not match in preset_not_match
|
||||
filter_count += 1;
|
||||
}
|
||||
}
|
||||
total_count += bound.end() - bound.start();
|
||||
} else if (OB_FAIL(ObBitVector::flip_foreach(
|
||||
skip, bound, [&](int64_t idx) __attribute__((always_inline)) {
|
||||
bloom_filter_.prefetch_bits_block(hash_values[idx]);
|
||||
return OB_SUCCESS;
|
||||
@ -798,13 +816,6 @@ int ObRFBloomFilterMsg::do_might_contain_vector(
|
||||
uint64_t seed = ObExprJoinFilter::JOIN_FILTER_SEED;
|
||||
ObBitVector &eval_flags = expr.get_evaluated_flags(ctx);
|
||||
uint64_t *hash_values = filter_ctx.right_hash_vals_;
|
||||
VectorFormat res_format = expr.get_format(ctx);
|
||||
if (VEC_FIXED == res_format) {
|
||||
IntegerFixedVec *res_vec = static_cast<IntegerFixedVec *>(expr.get_vector(ctx));
|
||||
if (OB_FAIL(preset_not_match(res_vec, bound))) {
|
||||
LOG_WARN("failed to preset_not_match", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < expr.arg_cnt_; ++i) {
|
||||
ObExpr *e = expr.args_[i];
|
||||
@ -820,14 +831,9 @@ int ObRFBloomFilterMsg::do_might_contain_vector(
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (VEC_UNIFORM == res_format) {
|
||||
IntegerUniVec *res_vec = static_cast<IntegerUniVec *>(expr.get_vector(ctx));
|
||||
ret = fill_vec_result<VEC_UNIFORM, IntegerUniVec>(res_vec, skip, bound, hash_values,
|
||||
total_count, filter_count);
|
||||
} else if (VEC_FIXED == res_format) {
|
||||
IntegerFixedVec *res_vec = static_cast<IntegerFixedVec *>(expr.get_vector(ctx));
|
||||
ret = fill_vec_result<VEC_FIXED, IntegerFixedVec>(res_vec, skip, bound, hash_values,
|
||||
total_count, filter_count);
|
||||
} else {
|
||||
ret = bloom_filter_.might_contain_vector(expr, ctx, skip, bound, hash_values, total_count,
|
||||
filter_count);
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else {
|
||||
@ -947,14 +953,9 @@ int ObRFBloomFilterMsg::insert_by_row_vector(
|
||||
arg_vec->murmur_hash_v3(*expr, batch_hash_values, *(child_brs->skip_), bound, is_batch_seed ? batch_hash_values : &seed, is_batch_seed);
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < child_brs->size_; ++i) {
|
||||
if (child_brs->skip_->at(i)) {
|
||||
continue;
|
||||
} else if (OB_FAIL(bloom_filter_.put(batch_hash_values[i]))) {
|
||||
LOG_WARN("fail to put hash value to px bloom filter", K(ret));
|
||||
} else if (is_empty_) {
|
||||
is_empty_ = false;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(bloom_filter_.put_batch(batch_hash_values, bound, *child_brs->skip_, is_empty_))) {
|
||||
LOG_WARN("failed to push hash value to px bloom filter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,60 @@ using namespace oceanbase::common;
|
||||
using namespace oceanbase::sql;
|
||||
using namespace oceanbase::share;
|
||||
|
||||
class SmallHashSetBatchInsertOP
|
||||
{
|
||||
public:
|
||||
SmallHashSetBatchInsertOP(ObSmallHashSet<false> &sm_hash_set, uint64_t *batch_hash_values)
|
||||
: sm_hash_set_(sm_hash_set), batch_hash_values_(batch_hash_values)
|
||||
{}
|
||||
OB_INLINE int operator()(int64_t batch_i)
|
||||
{
|
||||
return sm_hash_set_.insert_hash(batch_hash_values_[batch_i]);
|
||||
}
|
||||
|
||||
private:
|
||||
ObSmallHashSet<false> &sm_hash_set_;
|
||||
uint64_t *batch_hash_values_;
|
||||
};
|
||||
|
||||
template<typename ResVec>
|
||||
class InFilterProbeOP
|
||||
{
|
||||
public:
|
||||
InFilterProbeOP(ObSmallHashSet<false> &sm_hash_set, ResVec *res_vec, uint64_t *right_hash_values,
|
||||
int64_t &total_count, int64_t &filter_count)
|
||||
: sm_hash_set_(sm_hash_set), res_vec_(res_vec), right_hash_values_(right_hash_values),
|
||||
total_count_(total_count), filter_count_(filter_count)
|
||||
{}
|
||||
OB_INLINE int operator()(int64_t batch_i)
|
||||
{
|
||||
bool is_match = false;
|
||||
constexpr int64_t is_match_payload = 1;
|
||||
total_count_ += 1;
|
||||
is_match = sm_hash_set_.test_hash(right_hash_values_[batch_i]);
|
||||
if (!is_match) {
|
||||
filter_count_++;
|
||||
if (std::is_same<ResVec, IntegerUniVec>::value) {
|
||||
res_vec_->set_int(batch_i, 0);
|
||||
}
|
||||
} else {
|
||||
if (std::is_same<ResVec, IntegerUniVec>::value) {
|
||||
res_vec_->set_int(batch_i, 1);
|
||||
} else {
|
||||
res_vec_->set_payload(batch_i, &is_match_payload, sizeof(int64_t));
|
||||
}
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
private:
|
||||
ObSmallHashSet<false> &sm_hash_set_;
|
||||
ResVec *res_vec_;
|
||||
uint64_t *right_hash_values_;
|
||||
int64_t &total_count_;
|
||||
int64_t &filter_count_;
|
||||
};
|
||||
|
||||
|
||||
template <typename ResVec>
|
||||
static int proc_filter_not_active(ResVec *res_vec, const ObBitVector &skip, const EvalBound &bound);
|
||||
|
||||
@ -204,11 +258,15 @@ OB_DEF_DESERIALIZE(ObRFInFilterVecMsg)
|
||||
"RFDEInFilter",
|
||||
"RFDEInFilter"))) {
|
||||
LOG_WARN("fail to init in hash set", K(ret));
|
||||
} else if (OB_FAIL(sm_hash_set_.init(buckets_cnt, tenant_id_))) {
|
||||
LOG_WARN("faield to init small hash set", K(row_cnt));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < row_cnt; ++i) {
|
||||
ObRFInFilterNode node(&build_row_cmp_info_, &build_row_meta_, row_store_.get_row(i), nullptr);
|
||||
if (OB_FAIL(rows_set_.set_refactored(node))) {
|
||||
LOG_WARN("fail to insert in filter node", K(ret));
|
||||
} else if (OB_FAIL(sm_hash_set_.insert_hash(row_store_.get_hash_value(i, build_row_meta_)))) {
|
||||
LOG_WARN("fail to insert hash value into sm_hash_set_", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1044,6 +1102,8 @@ int ObRFInFilterVecMsg::assign(const ObP2PDatahubMsgBase &msg)
|
||||
LOG_WARN("fail to assign row_store_", K(ret));
|
||||
} else if (OB_FAIL(rows_set_.create(bucket_cnt * 2, "RFCPInFilter", "RFCPInFilter"))) {
|
||||
LOG_WARN("fail to init in hash set", K(ret));
|
||||
} else if (OB_FAIL(sm_hash_set_.init(bucket_cnt, tenant_id_))) {
|
||||
LOG_WARN("failed to init sm_hash_set_", K(other_msg.row_store_.get_row_cnt()));
|
||||
} else if (OB_FAIL(hash_funcs_for_insert_.assign(other_msg.hash_funcs_for_insert_))) {
|
||||
LOG_WARN("fail to assign hash_funcs_for_insert_", K(ret));
|
||||
} else if (OB_FAIL(query_range_info_.assign(other_msg.query_range_info_))) {
|
||||
@ -1058,6 +1118,8 @@ int ObRFInFilterVecMsg::assign(const ObP2PDatahubMsgBase &msg)
|
||||
nullptr);
|
||||
if (OB_FAIL(rows_set_.set_refactored(node))) {
|
||||
LOG_WARN("fail to insert in filter node", K(ret));
|
||||
} else if (OB_FAIL(sm_hash_set_.insert_hash(row_store_.get_hash_value(i, build_row_meta_)))) {
|
||||
LOG_WARN("fail to insert hash value into sm_hash_set_", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1107,6 +1169,13 @@ int ObRFInFilterVecMsg::insert_by_row_vector(
|
||||
}
|
||||
}
|
||||
|
||||
SmallHashSetBatchInsertOP sm_hash_set_batch_ins_op(sm_hash_set_, batch_hash_values);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(
|
||||
ObBitVector::flip_foreach(*child_brs->skip_, bound, sm_hash_set_batch_ins_op))) {
|
||||
LOG_WARN("failed insert batch_hash_values into sm_hash_set_");
|
||||
}
|
||||
|
||||
ObRowWithHash &cur_row = cur_row_with_hash_;
|
||||
ObDatum datum;
|
||||
ObEvalCtx::BatchInfoScopeGuard batch_info_guard(eval_ctx);
|
||||
@ -1348,6 +1417,9 @@ int ObRFInFilterVecMsg::merge(ObP2PDatahubMsgBase &msg)
|
||||
nullptr /*row_with_hash*/);
|
||||
if (OB_FAIL(try_merge_node(node, row_size))) {
|
||||
LOG_WARN("fail to insert node", K(ret));
|
||||
} else if (OB_FAIL(sm_hash_set_.insert_hash(
|
||||
other_msg.row_store_.get_hash_value(i, build_row_meta_)))) {
|
||||
LOG_WARN("failed to insert hash value into sm_hash_set_");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1360,6 +1432,7 @@ int ObRFInFilterVecMsg::reuse()
|
||||
is_empty_ = true;
|
||||
row_store_.reset();
|
||||
rows_set_.reuse();
|
||||
sm_hash_set_.clear();
|
||||
(void)reuse_query_range();
|
||||
return ret;
|
||||
}
|
||||
@ -1616,6 +1689,93 @@ int ObRFInFilterVecMsg::do_might_contain_vector(
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename ResVec>
|
||||
int ObRFInFilterVecMsg::do_might_contain_vector_impl(
|
||||
const ObExpr &expr,
|
||||
ObEvalCtx &ctx,
|
||||
const ObBitVector &skip,
|
||||
const EvalBound &bound,
|
||||
ObExprJoinFilter::ObExprJoinFilterContext &filter_ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t total_count = 0;
|
||||
int64_t filter_count = 0;
|
||||
uint64_t seed = ObExprJoinFilter::JOIN_FILTER_SEED;
|
||||
ObBitVector &eval_flags = expr.get_evaluated_flags(ctx);
|
||||
uint64_t *right_hash_vals = filter_ctx.right_hash_vals_;
|
||||
ResVec *res_vec = static_cast<ResVec *>(expr.get_vector(ctx));
|
||||
|
||||
if (std::is_same<ResVec, IntegerFixedVec>::value) {
|
||||
IntegerFixedVec *res_vec = static_cast<IntegerFixedVec *>(expr.get_vector(ctx));
|
||||
if (OB_FAIL(preset_not_match(res_vec, bound))) {
|
||||
LOG_WARN("failed to preset_not_match", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < expr.arg_cnt_; ++i) {
|
||||
ObExpr *e = expr.args_[i];
|
||||
if (OB_FAIL(e->eval_vector(ctx, skip, bound))) {
|
||||
LOG_WARN("evaluate vector failed", K(ret), K(*e));
|
||||
} else {
|
||||
const bool is_batch_seed = (i > 0);
|
||||
ObIVector *arg_vec = e->get_vector(ctx);
|
||||
if (OB_FAIL(arg_vec->murmur_hash_v3(*e, right_hash_vals, skip,
|
||||
bound, is_batch_seed ? right_hash_vals : &seed, is_batch_seed))) {
|
||||
LOG_WARN("failed to cal hash");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define IN_FILTER_PROBE_HELPER \
|
||||
is_match = sm_hash_set_.test_hash(right_hash_vals[batch_i]); \
|
||||
if (!is_match) { \
|
||||
filter_count++; \
|
||||
if (std::is_same<ResVec, IntegerUniVec>::value) { \
|
||||
res_vec->set_int(batch_i, 0); \
|
||||
} \
|
||||
} else { \
|
||||
if (std::is_same<ResVec, IntegerUniVec>::value) { \
|
||||
res_vec->set_int(batch_i, 1); \
|
||||
} else { \
|
||||
res_vec->set_payload(batch_i, &is_match_payload, sizeof(int64_t)); \
|
||||
} \
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else {
|
||||
ObEvalCtx::BatchInfoScopeGuard batch_info_guard(ctx);
|
||||
batch_info_guard.set_batch_size(bound.batch_size());
|
||||
bool is_match = true;
|
||||
const int64_t is_match_payload = 1; // for VEC_FIXED set set_payload, always 1
|
||||
if (bound.get_all_rows_active()) {
|
||||
total_count += bound.end() - bound.start();
|
||||
for (int64_t batch_i = bound.start(); batch_i < bound.end() && OB_SUCC(ret); ++batch_i) {
|
||||
IN_FILTER_PROBE_HELPER
|
||||
}
|
||||
} else {
|
||||
InFilterProbeOP<ResVec> in_filter_probe_op(sm_hash_set_, res_vec, right_hash_vals,
|
||||
total_count, filter_count);
|
||||
(void)ObBitVector::flip_foreach(skip, bound, in_filter_probe_op);
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
eval_flags.set_all(true);
|
||||
filter_ctx.total_count_ += total_count;
|
||||
filter_ctx.check_count_ += total_count;
|
||||
filter_ctx.filter_count_ += filter_count;
|
||||
ObExprJoinFilter::collect_sample_info_batch(filter_ctx, filter_count, total_count);
|
||||
}
|
||||
}
|
||||
#undef IN_FILTER_PROBE_HELPER
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define IN_FILTER_DISPATCH_RES_FORMAT(function, res_format) \
|
||||
if (res_format == VEC_FIXED) { \
|
||||
ret = function<IntegerFixedVec>(expr, ctx, skip, bound, filter_ctx); \
|
||||
} else { \
|
||||
ret = function<IntegerUniVec>(expr, ctx, skip, bound, filter_ctx); \
|
||||
}
|
||||
|
||||
int ObRFInFilterVecMsg::might_contain_vector(
|
||||
const ObExpr &expr,
|
||||
ObEvalCtx &ctx,
|
||||
@ -1655,8 +1815,9 @@ int ObRFInFilterVecMsg::might_contain_vector(
|
||||
filter_ctx.check_count_ += total_count;
|
||||
filter_ctx.total_count_ += total_count;
|
||||
}
|
||||
} else if (OB_FAIL(do_might_contain_vector(expr, ctx, skip, bound, filter_ctx))) {
|
||||
LOG_WARN("fail to do might contain vector");
|
||||
} else {
|
||||
VectorFormat res_format = expr.get_format(ctx);
|
||||
IN_FILTER_DISPATCH_RES_FORMAT(do_might_contain_vector_impl, res_format);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1676,7 +1837,6 @@ int ObRFInFilterVecMsg::prepare_storage_white_filter_data(ObDynamicFilterExecuto
|
||||
is_data_prepared = true;
|
||||
} else {
|
||||
for (int64_t i = 0; i < row_store_.get_row_cnt() && OB_SUCC(ret); ++i) {
|
||||
// row_store_.get_row(i)->get_datum(build_row_meta_, col_idx);
|
||||
if (OB_FAIL(params.push_back(row_store_.get_row(i)->get_datum(build_row_meta_, col_idx)))) {
|
||||
LOG_WARN("failed to push back");
|
||||
}
|
||||
@ -1697,6 +1857,7 @@ int ObRFInFilterVecMsg::destroy()
|
||||
build_row_meta_.reset();
|
||||
cur_row_with_hash_.row_.reset();
|
||||
rows_set_.destroy();
|
||||
sm_hash_set_.~ObSmallHashSet<false>();
|
||||
need_null_cmp_flags_.reset();
|
||||
row_store_.reset();
|
||||
hash_funcs_for_insert_.reset();
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "sql/engine/px/p2p_datahub/ob_p2p_dh_msg.h"
|
||||
#include "sql/engine/basic/ob_compact_row.h"
|
||||
#include "sql/engine/px/p2p_datahub/ob_runtime_filter_query_range.h"
|
||||
#include "src/sql/engine/px/p2p_datahub/ob_small_hashset.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -200,6 +201,9 @@ public:
|
||||
int assign(const ObRFInFilterRowStore &other);
|
||||
void reset();
|
||||
inline ObCompactRow *get_row(int64_t idx) { return serial_rows_.at(idx); }
|
||||
inline uint64_t get_hash_value(int64_t idx, const RowMeta &row_meta) {
|
||||
return serial_rows_.at(idx)->extra_payload<uint64_t>(row_meta);
|
||||
}
|
||||
inline int64_t get_row_size(int64_t idx) { return row_sizes_.at(idx); }
|
||||
inline int64_t get_row_cnt() const { return serial_rows_.count(); }
|
||||
inline int add_row(ObCompactRow *new_row, int64_t row_size);
|
||||
@ -240,7 +244,7 @@ public:
|
||||
build_row_meta_(&allocator_), cur_row_with_hash_(allocator_), rows_set_(),
|
||||
row_store_(allocator_), need_null_cmp_flags_(allocator_), max_in_num_(0),
|
||||
hash_funcs_for_insert_(allocator_),query_range_info_(allocator_),
|
||||
query_range_(), is_query_range_ready_(false), query_range_allocator_()
|
||||
query_range_(), is_query_range_ready_(false), query_range_allocator_(), sm_hash_set_()
|
||||
{}
|
||||
virtual int assign(const ObP2PDatahubMsgBase &);
|
||||
virtual int merge(ObP2PDatahubMsgBase &) final;
|
||||
@ -313,6 +317,11 @@ private:
|
||||
const ObBitVector &skip,
|
||||
const EvalBound &bound,
|
||||
ObExprJoinFilter::ObExprJoinFilterContext &filter_ctx);
|
||||
|
||||
template <typename ResVec>
|
||||
int do_might_contain_vector_impl(const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip,
|
||||
const EvalBound &bound,
|
||||
ObExprJoinFilter::ObExprJoinFilterContext &filter_ctx);
|
||||
int prepare_query_ranges();
|
||||
int process_query_ranges_with_deduplicate();
|
||||
int process_query_ranges_without_deduplicate();
|
||||
@ -347,6 +356,7 @@ public:
|
||||
bool is_query_range_ready_; // not need to serialize
|
||||
common::ObArenaAllocator query_range_allocator_;
|
||||
// ---end---
|
||||
ObSmallHashSet<false> sm_hash_set_;
|
||||
};
|
||||
|
||||
|
||||
|
178
src/sql/engine/px/p2p_datahub/ob_small_hashset.h
Normal file
178
src/sql/engine/px/p2p_datahub/ob_small_hashset.h
Normal file
@ -0,0 +1,178 @@
|
||||
/**
|
||||
* Copyright (c) 2024 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "lib/ob_define.h"
|
||||
#include "lib/allocator/page_arena.h"
|
||||
#include "lib/utility/ob_macro_utils.h"
|
||||
#include "lib/utility/utility.h"
|
||||
|
||||
namespace oceanbase{
|
||||
namespace sql {
|
||||
/**
|
||||
* @brief A simple hash container composed of unique uint64_t keys implemented with opened
|
||||
* addressing. The capacity of the ObSmallHashSet is 2^n.
|
||||
* @tparam _Accurate Whether need to seek whole hashset when meeting conflict.
|
||||
* If _Accurate = true, it works as a normal hashset.
|
||||
* If _Accurate = false, it only MAX_SEEK_TIMES when meeting hash confilct. That is to say,
|
||||
* when testing if an element is in the ObSmallHashSet, false positives are possible. It will either
|
||||
* say that an element is definitely not in the set or that it is possible the element is in the
|
||||
* set.
|
||||
* @
|
||||
*/
|
||||
|
||||
template <bool _Accurate>
|
||||
class ObSmallHashSet
|
||||
{
|
||||
public:
|
||||
using bucket_t = uint64_t;
|
||||
~ObSmallHashSet() {}
|
||||
|
||||
int init(uint64_t capacity, int64_t tenant_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
alloc_.set_tenant_id(tenant_id);
|
||||
alloc_.set_label("ObSmallHashSet");
|
||||
if (OB_FAIL(expand(capacity))) {
|
||||
COMMON_LOG(WARN, "failed to expand when init");
|
||||
} else {
|
||||
inited_ = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
memset(buckets_, 0, sizeof(bucket_t) * capacity_);
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
inline uint64_t size() {
|
||||
return size_;
|
||||
}
|
||||
|
||||
inline int insert_hash_batch(uint64_t* hashs, uint64_t batch_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
COMMON_LOG(ERROR, "not inited");
|
||||
}
|
||||
for (int64_t i = 0; i < batch_size && OB_SUCC(ret); ++i) {
|
||||
ret = insert_hash(hashs[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int insert_hash(uint64_t hash)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
hash |= KEY_MASK;
|
||||
uint64_t offset = hash & bucket_mask_;
|
||||
while ((buckets_[offset] != EMPTY_KEY) && (buckets_[offset] != hash)) {
|
||||
offset = (++offset) & bucket_mask_;
|
||||
}
|
||||
if (buckets_[offset] != hash) {
|
||||
buckets_[offset] = hash;
|
||||
size_++;
|
||||
if (size_ * 2 > capacity_ && OB_FAIL(expand(capacity_))) {
|
||||
COMMON_LOG(WARN, "failed to expand", K(capacity_));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool test_hash(uint64_t hash)
|
||||
{
|
||||
bool find = false;
|
||||
hash |= KEY_MASK;
|
||||
uint64_t offset = hash & bucket_mask_;
|
||||
uint64_t i = 0;
|
||||
for (i = 0; i < capacity_; ++i) {
|
||||
if (EMPTY_KEY == buckets_[offset]) {
|
||||
break;
|
||||
} else if (buckets_[offset] == hash) {
|
||||
find = true;
|
||||
break;
|
||||
} else if (!_Accurate) {
|
||||
if (i > MAX_SEEK_TIMES) {
|
||||
// no seek more, return true
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
offset = (++offset) & bucket_mask_;
|
||||
}
|
||||
#ifdef unittest
|
||||
seek_total_times_ += i;
|
||||
#endif
|
||||
return find;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t normalize_capacity(uint64_t n)
|
||||
{
|
||||
return max(MIN_BUCKET_SIZE, next_pow2(2 * n));
|
||||
}
|
||||
|
||||
int expand(uint64_t capacity) {
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t new_capacity = normalize_capacity(capacity);
|
||||
void *buf = nullptr;
|
||||
if (OB_ISNULL(buf = alloc_.alloc_aligned(sizeof(bucket_t) * new_capacity, CACHE_LINE_SIZE))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
COMMON_LOG(WARN, "failed to allocate bucket memory", K(new_capacity));
|
||||
} else {
|
||||
bucket_t *old_buckets = buckets_;
|
||||
buckets_= static_cast<bucket_t *>(buf);
|
||||
uint64_t old_capacity = capacity_;
|
||||
capacity_ = new_capacity;
|
||||
bucket_mask_ = capacity_ - 1;
|
||||
// init new bucket
|
||||
memset(buckets_, 0, sizeof(bucket_t) * new_capacity);
|
||||
// move data
|
||||
for (uint64_t i = 0; i < old_capacity; ++i) {
|
||||
uint64_t &hash = old_buckets[i];
|
||||
if (hash == EMPTY_KEY) {
|
||||
continue;
|
||||
}
|
||||
uint64_t offset = hash & bucket_mask_;
|
||||
while ((buckets_[offset] != EMPTY_KEY) && (buckets_[offset] != hash)) {
|
||||
offset = (++offset) & bucket_mask_;
|
||||
}
|
||||
buckets_[offset] = hash;
|
||||
}
|
||||
}
|
||||
COMMON_LOG(DEBUG, "expand capacity to ", K(capacity_));
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr uint64_t EMPTY_KEY = 0UL;
|
||||
static constexpr uint64_t KEY_MASK = 1UL << 63;
|
||||
static constexpr int64_t MIN_BUCKET_SIZE = 128;
|
||||
static constexpr int64_t CACHE_LINE_SIZE = 64;
|
||||
static constexpr int64_t MAX_SEEK_TIMES = 8;
|
||||
|
||||
private:
|
||||
bool inited_{false};
|
||||
bucket_t *buckets_{nullptr};
|
||||
uint64_t bucket_mask_{0};
|
||||
uint64_t capacity_{0};
|
||||
uint64_t size_{0};
|
||||
common::ObArenaAllocator alloc_;
|
||||
#ifdef unittest
|
||||
uint64_t seek_total_times_{0};
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbases
|
@ -523,6 +523,7 @@ int ObConfigInfoInPC::load_influence_plan_config()
|
||||
enable_newsort_ = GCONF._enable_newsort;
|
||||
is_strict_defensive_check_ = GCONF.enable_strict_defensive_check();
|
||||
is_enable_px_fast_reclaim_ = GCONF._enable_px_fast_reclaim;
|
||||
bloom_filter_ratio_ = GCONF._bloom_filter_ratio;
|
||||
|
||||
// For Tenant configs
|
||||
// tenant config use tenant_config to get configs
|
||||
@ -588,6 +589,9 @@ int ObConfigInfoInPC::serialize_configs(char *buf, int buf_len, int64_t &pos)
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%d", enable_var_assign_use_das_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(enable_var_assign_use_das_));
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%d", bloom_filter_ratio_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(bloom_filter_ratio_));
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
|
@ -1026,6 +1026,7 @@ public:
|
||||
is_enable_px_fast_reclaim_(false),
|
||||
enable_spf_batch_rescan_(false),
|
||||
enable_var_assign_use_das_(false),
|
||||
bloom_filter_ratio_(0),
|
||||
cluster_config_version_(-1),
|
||||
tenant_config_version_(-1),
|
||||
tenant_id_(0)
|
||||
@ -1069,6 +1070,7 @@ public:
|
||||
bool is_enable_px_fast_reclaim_;
|
||||
bool enable_spf_batch_rescan_;
|
||||
bool enable_var_assign_use_das_;
|
||||
int bloom_filter_ratio_;
|
||||
|
||||
private:
|
||||
// current cluster config version_
|
||||
|
@ -92,7 +92,7 @@ int ObCGAggCells::process(
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_idx,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count);
|
||||
int process(blocksstable::ObStorageDatum &datum, const uint64_t row_count);
|
||||
int process(const blocksstable::ObMicroIndexInfo &index_info);
|
||||
|
@ -27,7 +27,7 @@ static bool copy_row_ids(
|
||||
const int64_t offset,
|
||||
const int64_t cap,
|
||||
const int64_t step,
|
||||
int64_t *row_ids);
|
||||
int32_t *row_ids);
|
||||
|
||||
ObBlockBatchedRowStore::ObBlockBatchedRowStore(
|
||||
const int64_t batch_size,
|
||||
@ -59,14 +59,14 @@ int ObBlockBatchedRowStore::init(const ObTableAccessParam ¶m)
|
||||
ret = common::OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc cell data ptr", K(ret), K(batch_size_));
|
||||
} else if (FALSE_IT(cell_data_ptrs_ = reinterpret_cast<const char **>(buf))) {
|
||||
} else if (OB_ISNULL(buf = context_.stmt_allocator_->alloc(sizeof(int64_t) * batch_size_))) {
|
||||
} else if (OB_ISNULL(buf = context_.stmt_allocator_->alloc(sizeof(int32_t) * batch_size_))) {
|
||||
ret = common::OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc row_ids", K(ret), K(batch_size_));
|
||||
} else if (OB_ISNULL(len_array_buf = context_.stmt_allocator_->alloc(sizeof(uint32_t) * batch_size_))) {
|
||||
ret = common::OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc len_array_buf", K(ret), K_(batch_size));
|
||||
} else {
|
||||
row_ids_ = reinterpret_cast<int64_t *>(buf);
|
||||
row_ids_ = reinterpret_cast<int32_t *>(buf);
|
||||
len_array_ = reinterpret_cast<uint32_t *>(len_array_buf);
|
||||
}
|
||||
return ret;
|
||||
@ -187,8 +187,8 @@ int ObBlockBatchedRowStore::get_row_ids(
|
||||
}
|
||||
|
||||
static const int32_t DEFAULT_BATCH_ROW_COUNT = 1024;
|
||||
static int64_t default_batch_row_ids_[DEFAULT_BATCH_ROW_COUNT];
|
||||
static int64_t default_batch_reverse_row_ids_[DEFAULT_BATCH_ROW_COUNT];
|
||||
static int32_t default_batch_row_ids_[DEFAULT_BATCH_ROW_COUNT];
|
||||
static int32_t default_batch_reverse_row_ids_[DEFAULT_BATCH_ROW_COUNT];
|
||||
static void __attribute__((constructor)) init_row_ids_array()
|
||||
{
|
||||
for (int32_t i = 0; i < DEFAULT_BATCH_ROW_COUNT; i++) {
|
||||
@ -200,14 +200,14 @@ bool copy_row_ids(
|
||||
const int64_t offset,
|
||||
const int64_t cap,
|
||||
const int64_t step,
|
||||
int64_t *row_ids)
|
||||
int32_t *row_ids)
|
||||
{
|
||||
bool is_success = false;
|
||||
if (1 == step && offset + cap <= DEFAULT_BATCH_ROW_COUNT) {
|
||||
memcpy(row_ids, default_batch_row_ids_ + offset, sizeof(int64_t ) * cap);
|
||||
MEMCPY(row_ids, default_batch_row_ids_ + offset, sizeof(int32_t ) * cap);
|
||||
is_success = true;
|
||||
} else if (-1 == step && offset < DEFAULT_BATCH_ROW_COUNT) {
|
||||
memcpy(row_ids, default_batch_reverse_row_ids_ + DEFAULT_BATCH_ROW_COUNT - offset - 1, sizeof(int64_t ) * cap);
|
||||
MEMCPY(row_ids, default_batch_reverse_row_ids_ + DEFAULT_BATCH_ROW_COUNT - offset - 1, sizeof(int32_t ) * cap);
|
||||
is_success = true;
|
||||
}
|
||||
return is_success;
|
||||
|
@ -83,7 +83,7 @@ protected:
|
||||
int64_t batch_size_;
|
||||
int64_t row_capacity_;
|
||||
const char **cell_data_ptrs_;
|
||||
int64_t *row_ids_;
|
||||
int32_t *row_ids_;
|
||||
uint32_t *len_array_;
|
||||
sql::ObEvalCtx &eval_ctx_;
|
||||
};
|
||||
|
@ -330,7 +330,6 @@ int ObIndexBlockScanEstimator::prefetch_index_block_data(
|
||||
micro_handle.block_state_ = ObSSTableMicroBlockState::IN_BLOCK_IO;
|
||||
micro_handle.micro_info_.offset_ = micro_index_info.get_block_offset();
|
||||
micro_handle.micro_info_.size_ = micro_index_info.get_block_size();
|
||||
micro_handle.need_release_data_buf_ = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -390,7 +390,9 @@ int ObIndexTreePrefetcher::check_bloom_filter(
|
||||
int ObIndexTreePrefetcher::prefetch_block_data(
|
||||
blocksstable::ObMicroIndexInfo &index_block_info,
|
||||
ObMicroBlockDataHandle µ_handle,
|
||||
const bool is_data)
|
||||
const bool is_data,
|
||||
const bool use_multi_block_prefetch,
|
||||
const bool need_submit_io)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (is_rescan() && last_handle_hit(index_block_info, is_data, micro_handle)) {
|
||||
@ -400,10 +402,15 @@ int ObIndexTreePrefetcher::prefetch_block_data(
|
||||
} else if (OB_FAIL(access_ctx_->micro_block_handle_mgr_.get_micro_block_handle(
|
||||
index_block_info,
|
||||
is_data,
|
||||
true, /* need submit io */
|
||||
!is_data || need_submit_io, /* need submit io */
|
||||
use_multi_block_prefetch,
|
||||
micro_handle,
|
||||
cur_level_))) {
|
||||
LOG_WARN("Fail to get micro block handle from handle mgr", K(ret));
|
||||
if (is_data && !need_submit_io && OB_ENTRY_NOT_EXIST == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
} else {
|
||||
LOG_WARN("Fail to get micro block handle from handle mgr", K(ret));
|
||||
}
|
||||
} else if (is_rescan() && is_data && micro_handle.in_block_state()) {
|
||||
last_micro_block_handle_ = micro_handle;
|
||||
}
|
||||
@ -634,16 +641,19 @@ int ObIndexTreeMultiPrefetcher::multi_prefetch()
|
||||
cur_index_info,
|
||||
cur_index_info.is_data_block(),
|
||||
false, /* need submit io */
|
||||
false, /* use_multi_block_prefetch */
|
||||
next_handle,
|
||||
cur_level_))) {
|
||||
//not in cache yet, stop this rowkey prefetching if it's not the rowkey to be feteched
|
||||
ret = OB_SUCCESS;
|
||||
if (is_rowkey_to_fetched) {
|
||||
if (OB_FAIL(read_handle.micro_handle_->get_micro_block_data(nullptr, index_block_, false))) {
|
||||
LOG_WARN("Fail to get index block data", K(ret), KPC(read_handle.micro_handle_));
|
||||
if (OB_ENTRY_NOT_EXIST == ret) {
|
||||
//not in cache yet, stop this rowkey prefetching if it's not the rowkey to be feteched
|
||||
ret = OB_SUCCESS;
|
||||
if (is_rowkey_to_fetched) {
|
||||
if (OB_FAIL(read_handle.micro_handle_->get_micro_block_data(nullptr, index_block_, false))) {
|
||||
LOG_WARN("Fail to get index block data", K(ret), KPC(read_handle.micro_handle_));
|
||||
}
|
||||
} else {
|
||||
stop_prefetch = true;
|
||||
}
|
||||
} else {
|
||||
stop_prefetch = true;
|
||||
}
|
||||
} else if (FALSE_IT(read_handle.set_cur_micro_handle(next_handle))) {
|
||||
} else if (OB_FAIL(read_handle.micro_handle_->get_cached_index_block_data(index_block_))) {
|
||||
@ -783,6 +793,7 @@ void ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::
|
||||
reset_tree_handles();
|
||||
read_handles_.reset();
|
||||
inner_reset();
|
||||
multi_io_params_.reset();
|
||||
max_range_prefetching_cnt_ = 0;
|
||||
max_micro_handle_cnt_ = 0;
|
||||
ObIndexTreePrefetcher::reset();
|
||||
@ -796,6 +807,7 @@ void ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::
|
||||
}
|
||||
clean_blockscan_check_info();
|
||||
inner_reset();
|
||||
multi_io_params_.reuse();
|
||||
ObIndexTreePrefetcher::reuse();
|
||||
}
|
||||
|
||||
@ -813,6 +825,7 @@ void ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::
|
||||
micro_data_handles_[i].reset();
|
||||
}
|
||||
inner_reset();
|
||||
multi_io_params_.reset();
|
||||
ObIndexTreePrefetcher::reclaim();
|
||||
}
|
||||
|
||||
@ -823,6 +836,8 @@ void ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::
|
||||
is_prefetch_end_ = false;
|
||||
is_row_lock_checked_ = false;
|
||||
need_check_prefetch_depth_ = false;
|
||||
use_multi_block_prefetch_ = false;
|
||||
need_submit_io_ = true;
|
||||
cur_range_fetch_idx_ = 0;
|
||||
cur_range_prefetch_idx_ = 0;
|
||||
cur_micro_data_fetch_idx_ = -1;
|
||||
@ -874,10 +889,10 @@ int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::g
|
||||
int ret = OB_SUCCESS;
|
||||
depth = 0;
|
||||
prefetch_depth_ = MIN(2 * prefetch_depth_, DEFAULT_SCAN_MICRO_DATA_HANDLE_CNT);
|
||||
if (need_check_prefetch_depth_ && access_ctx_->limit_param_->offset_ < INT32_MAX && access_ctx_->limit_param_->limit_ < INT32_MAX) {
|
||||
if (need_check_prefetch_depth_) {
|
||||
int64_t prefetch_micro_cnt = MAX(1,
|
||||
(access_ctx_->limit_param_->offset_ + access_ctx_->limit_param_->limit_ - access_ctx_->out_cnt_ + \
|
||||
SSTABLE_MICRO_AVG_COUNT - 1) / SSTABLE_MICRO_AVG_COUNT);
|
||||
(access_ctx_->limit_param_->offset_ + access_ctx_->limit_param_->limit_ - access_ctx_->out_cnt_ + \
|
||||
SSTABLE_MICRO_AVG_COUNT - 1) / SSTABLE_MICRO_AVG_COUNT);
|
||||
prefetch_depth_ = MIN(prefetch_depth_, prefetch_micro_cnt);
|
||||
}
|
||||
depth = min(static_cast<int64_t>(prefetch_depth_),
|
||||
@ -996,7 +1011,9 @@ int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::i
|
||||
iter_param_->limit_prefetch_ &&
|
||||
nullptr != access_ctx_->limit_param_ &&
|
||||
access_ctx_->limit_param_->limit_ >= 0 &&
|
||||
access_ctx_->limit_param_->limit_ < 4096;
|
||||
access_ctx_->limit_param_->limit_ < 4096 &&
|
||||
access_ctx_->limit_param_->offset_ < INT32_MAX;
|
||||
use_multi_block_prefetch_ = (iter_param.get_io_read_batch_size() > 0);
|
||||
switch (iter_type) {
|
||||
case ObStoreRowIterator::IteratorMultiGet:
|
||||
case ObStoreRowIterator::IteratorCOMultiGet: {
|
||||
@ -1066,6 +1083,13 @@ int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::i
|
||||
LOG_WARN("Fail to init read_handles", K(ret), K(max_handle_cnt));
|
||||
} else if (OB_FAIL(init_tree_handles(max_height))) {
|
||||
LOG_WARN("Fail to init tree handles", K(ret), K(max_height));
|
||||
} else if (use_multi_block_prefetch_ &&
|
||||
OB_FAIL(multi_io_params_.init(
|
||||
iter_param,
|
||||
max_micro_handle_cnt_,
|
||||
access_ctx_->query_flag_.is_reverse_scan(),
|
||||
*access_ctx_->stmt_allocator_))) {
|
||||
LOG_WARN("Fail to init multi io params", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1087,13 +1111,10 @@ template <int32_t DATA_PREFETCH_DEPTH, int32_t INDEX_PREFETCH_DEPTH>
|
||||
int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::prefetch()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const int32_t prefetch_limit = MAX(2, max_micro_handle_cnt_ / 2);
|
||||
if (IS_NOT_INIT) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("ObIndexTreeMultiPassPrefetcher not init", K(ret));
|
||||
} else if (is_prefetch_end_) {
|
||||
} else if (micro_data_prefetch_idx_ - cur_micro_data_fetch_idx_ >= prefetch_limit) {
|
||||
// continue current prefetch
|
||||
} else if (OB_FAIL(prefetch_index_tree())) {
|
||||
if (OB_LIKELY(OB_ITER_END == ret)) {
|
||||
is_prefetch_end_ = true;
|
||||
@ -1232,7 +1253,9 @@ int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::p
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Unexpected prefetch status", K(ret), K_(cur_level), K_(index_tree_height),
|
||||
K_(micro_data_prefetch_idx), K_(cur_micro_data_fetch_idx), K_(max_micro_handle_cnt));
|
||||
} else if (micro_data_prefetch_idx_ - cur_micro_data_fetch_idx_ == max_micro_handle_cnt_) {
|
||||
} else if (micro_data_prefetch_idx_ - cur_micro_data_fetch_idx_ == max_micro_handle_cnt_ ||
|
||||
(use_multi_block_prefetch_ && prefetch_depth_ > MIN_DATA_READ_BATCH_COUNT &&
|
||||
(max_micro_handle_cnt_ - (micro_data_prefetch_idx_ - cur_micro_data_fetch_idx_)) < MIN_DATA_READ_BATCH_COUNT)) {
|
||||
// DataBlock ring buf full
|
||||
} else if (OB_FAIL(get_prefetch_depth(prefetch_depth))) {
|
||||
LOG_WARN("Fail to get prefetch depth", K(ret));
|
||||
@ -1290,7 +1313,7 @@ int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::p
|
||||
if (OB_UNLIKELY(OB_ITER_END != ret)) {
|
||||
LOG_WARN("Fail to check row lock", K(ret), K(block_info), KPC(this));
|
||||
}
|
||||
} else if (OB_FAIL(prefetch_block_data(block_info, micro_data_handles_[prefetch_micro_idx]))) {
|
||||
} else if (OB_FAIL(prefetch_data_block(micro_data_prefetch_idx_, block_info, micro_data_handles_[prefetch_micro_idx]))) {
|
||||
LOG_WARN("fail to prefetch_block_data", K(ret), K(block_info));
|
||||
}
|
||||
|
||||
@ -1300,6 +1323,10 @@ int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::p
|
||||
tree_handles_[cur_level_].current_block_read_handle().end_prefetched_row_idx_++;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && multi_io_params_.count() > 0 &&
|
||||
OB_FAIL(prefetch_multi_data_block(micro_data_prefetch_idx_))) {
|
||||
LOG_WARN("Fail to prefetch multi block", K(ret), K_(micro_data_prefetch_idx), K_(multi_io_params));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && 0 < prefetched_cnt) {
|
||||
ObSSTableReadHandle &read_handle = read_handles_[prefetching_range_idx() % max_range_prefetching_cnt_];
|
||||
@ -1691,6 +1718,56 @@ int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::c
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <int32_t DATA_PREFETCH_DEPTH, int32_t INDEX_PREFETCH_DEPTH>
|
||||
int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::prefetch_data_block(
|
||||
const int64_t prefetch_idx,
|
||||
blocksstable::ObMicroIndexInfo &index_block_info,
|
||||
ObMicroBlockDataHandle µ_handle)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(prefetch_block_data(index_block_info,
|
||||
micro_handle,
|
||||
true, /* is_data */
|
||||
use_multi_block_prefetch_,
|
||||
need_submit_io_))) {
|
||||
LOG_WARN("Fail to prefetch data block data", K(ret));
|
||||
} else if (use_multi_block_prefetch_ && micro_handle.need_multi_io()) {
|
||||
bool need_split = false;
|
||||
if (multi_io_params_.add_micro_data(index_block_info, prefetch_idx, micro_handle, need_split)) {
|
||||
if (OB_FAIL(prefetch_multi_data_block(prefetch_idx + 1))) {
|
||||
LOG_WARN("Fail to prefetch multi block", K(ret));
|
||||
} else if (need_split) {
|
||||
// reused after prefetch_multi_data_block
|
||||
if (multi_io_params_.add_micro_data(index_block_info, prefetch_idx, micro_handle, need_split)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Unexpected multi_io_params status", K(ret), K_(multi_io_params));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <int32_t DATA_PREFETCH_DEPTH, int32_t INDEX_PREFETCH_DEPTH>
|
||||
int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::prefetch_multi_data_block(
|
||||
const int64_t max_prefetch_idx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (multi_io_params_.count() > 0) {
|
||||
if (OB_FAIL(access_ctx_->micro_block_handle_mgr_.prefetch_multi_data_block(
|
||||
micro_data_infos_,
|
||||
micro_data_handles_,
|
||||
max_micro_handle_cnt_,
|
||||
max_prefetch_idx,
|
||||
multi_io_params_))) {
|
||||
LOG_WARN("Fail to prefetch multi block", K(ret));
|
||||
} else {
|
||||
multi_io_params_.reuse();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////////////////////////// ObIndexTreeLevelHandle //////////////////////////////////////////////
|
||||
template <int32_t DATA_PREFETCH_DEPTH, int32_t INDEX_PREFETCH_DEPTH>
|
||||
int ObIndexTreeMultiPassPrefetcher<DATA_PREFETCH_DEPTH, INDEX_PREFETCH_DEPTH>::ObIndexTreeLevelHandle::prefetch(
|
||||
|
@ -174,7 +174,9 @@ protected:
|
||||
int prefetch_block_data(
|
||||
ObMicroIndexInfo &index_block_info,
|
||||
ObMicroBlockDataHandle µ_handle,
|
||||
const bool is_data = true);
|
||||
const bool is_data = true,
|
||||
const bool use_multi_block_prefetch = false,
|
||||
const bool need_submit_io = true);
|
||||
int lookup_in_cache(ObSSTableReadHandle &read_handle);
|
||||
int init_basic_info(
|
||||
const int iter_type,
|
||||
@ -386,6 +388,8 @@ public:
|
||||
agg_row_store_(nullptr),
|
||||
can_blockscan_(false),
|
||||
need_check_prefetch_depth_(false),
|
||||
use_multi_block_prefetch_(false),
|
||||
need_submit_io_(true),
|
||||
tree_handle_cap_(0),
|
||||
prefetch_depth_(1),
|
||||
max_range_prefetching_cnt_(0),
|
||||
@ -394,7 +398,8 @@ public:
|
||||
query_range_(nullptr),
|
||||
border_rowkey_(),
|
||||
read_handles_(),
|
||||
tree_handles_(nullptr)
|
||||
tree_handles_(nullptr),
|
||||
multi_io_params_()
|
||||
{}
|
||||
virtual ~ObIndexTreeMultiPassPrefetcher();
|
||||
virtual void reset() override;
|
||||
@ -475,6 +480,7 @@ public:
|
||||
return DEFAULT_SCAN_MICRO_DATA_HANDLE_CNT;
|
||||
}
|
||||
|
||||
static const int16_t MIN_DATA_READ_BATCH_COUNT = 4;
|
||||
static const int16_t MAX_INDEX_TREE_HEIGHT = 16;
|
||||
static const int32_t MAX_DATA_PREFETCH_DEPTH = 32;
|
||||
static const int32_t MAX_INDEX_PREFETCH_DEPTH = 3;
|
||||
@ -484,8 +490,8 @@ public:
|
||||
K_(cur_micro_data_fetch_idx), K_(micro_data_prefetch_idx), K_(max_micro_handle_cnt),
|
||||
K_(iter_type), K_(cur_level), K_(index_tree_height), K_(max_rescan_height), KP_(long_life_allocator), K_(prefetch_depth),
|
||||
K_(total_micro_data_cnt), KP_(query_range), K_(tree_handle_cap),
|
||||
K_(can_blockscan), K_(need_check_prefetch_depth),
|
||||
K(ObArrayWrap<ObIndexTreeLevelHandle>(tree_handles_, index_tree_height_)));
|
||||
K_(can_blockscan), K_(need_check_prefetch_depth), K_(use_multi_block_prefetch), K_(need_submit_io),
|
||||
K(ObArrayWrap<ObIndexTreeLevelHandle>(tree_handles_, index_tree_height_)), K_(multi_io_params));
|
||||
protected:
|
||||
int init_basic_info(
|
||||
const int iter_type,
|
||||
@ -519,6 +525,11 @@ protected:
|
||||
void inner_reset();
|
||||
virtual int init_tree_handles(const int64_t count);
|
||||
int get_prefetch_depth(int64_t &depth);
|
||||
int prefetch_data_block(
|
||||
const int64_t prefetch_idx,
|
||||
ObMicroIndexInfo &index_block_info,
|
||||
ObMicroBlockDataHandle µ_handle);
|
||||
int prefetch_multi_data_block(const int64_t max_prefetch_idx);
|
||||
|
||||
static const int32_t DEFAULT_SCAN_RANGE_PREFETCH_CNT = 4;
|
||||
static const int32_t DEFAULT_SCAN_MICRO_DATA_HANDLE_CNT = DATA_PREFETCH_DEPTH;
|
||||
@ -693,6 +704,8 @@ public:
|
||||
protected:
|
||||
bool can_blockscan_;
|
||||
bool need_check_prefetch_depth_;
|
||||
bool use_multi_block_prefetch_;
|
||||
bool need_submit_io_;
|
||||
int16_t tree_handle_cap_;
|
||||
int16_t prefetch_depth_;
|
||||
int32_t max_range_prefetching_cnt_;
|
||||
@ -710,6 +723,7 @@ protected:
|
||||
ObIndexTreeLevelHandle *tree_handles_;
|
||||
ObMicroIndexInfo micro_data_infos_[DEFAULT_SCAN_MICRO_DATA_HANDLE_CNT];
|
||||
ObMicroBlockDataHandle micro_data_handles_[DEFAULT_SCAN_MICRO_DATA_HANDLE_CNT];
|
||||
ObMultiBlockIOParam multi_io_params_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ ObMicroBlockDataHandle::ObMicroBlockDataHandle()
|
||||
handle_mgr_(nullptr),
|
||||
allocator_(nullptr),
|
||||
loaded_block_data_(),
|
||||
need_release_data_buf_(false),
|
||||
is_loaded_block_(false)
|
||||
{
|
||||
des_meta_.encrypt_key_ = encrypt_key_;
|
||||
@ -98,7 +97,7 @@ int ObMicroBlockDataHandle::get_micro_block_data(
|
||||
int ret = OB_SUCCESS;
|
||||
if (ObSSTableMicroBlockState::NEED_SYNC_IO == block_state_ || OB_FAIL(get_loaded_block_data(block_data))) {
|
||||
if (is_loaded_block_ && loaded_block_data_.is_valid()) {
|
||||
LOG_DEBUG("Use sync loaded index block data", K_(macro_block_id),
|
||||
LOG_DEBUG("Use sync loaded index block data", K(is_data_block), K_(macro_block_id),
|
||||
K(loaded_block_data_), K_(io_handle));
|
||||
block_data = loaded_block_data_;
|
||||
} else {
|
||||
@ -211,8 +210,8 @@ int ObMicroBlockDataHandle::get_loaded_block_data(ObMicroBlockData &block_data)
|
||||
} else {
|
||||
//multi block io
|
||||
const ObMultiBlockIOResult *io_result = reinterpret_cast<const ObMultiBlockIOResult *>(io_buf);
|
||||
if (OB_FAIL(io_result->get_block_data(block_index_, block_data))) {
|
||||
LOG_WARN("get_block_data failed", K(ret), K_(block_index));
|
||||
if (OB_FAIL(io_result->get_block_data(block_index_, micro_info_, block_data))) {
|
||||
LOG_WARN("get_block_data failed", K(ret), K_(block_index), K_(micro_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -399,6 +398,7 @@ int ObMicroBlockHandleMgr::get_micro_block_handle(
|
||||
ObMicroIndexInfo &index_block_info,
|
||||
const bool is_data_block,
|
||||
const bool need_submit_io,
|
||||
const bool use_multi_block_prefetch,
|
||||
ObMicroBlockDataHandle µ_block_handle,
|
||||
int16_t cur_level)
|
||||
{
|
||||
@ -436,7 +436,12 @@ int ObMicroBlockHandleMgr::get_micro_block_handle(
|
||||
// get data / index block cache from disk
|
||||
if (!need_submit_io) {
|
||||
} else if (cache_mem_ctrl_.need_sync_io(*query_flag_, micro_block_handle, cache, block_io_allocator_)) {
|
||||
} else if (OB_FAIL(submit_async_io(cache, tenant_id, index_block_info, is_data_block, micro_block_handle))) {
|
||||
} else if (OB_FAIL(submit_async_io(cache,
|
||||
tenant_id,
|
||||
index_block_info,
|
||||
is_data_block,
|
||||
use_multi_block_prefetch,
|
||||
micro_block_handle))) {
|
||||
LOG_WARN("Fail to submit async io for prefetch", K(ret), K(index_block_info), K(micro_block_handle));
|
||||
}
|
||||
} else {
|
||||
@ -454,11 +459,71 @@ int ObMicroBlockHandleMgr::get_micro_block_handle(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObMicroBlockHandleMgr::prefetch_multi_data_block(
|
||||
const ObMicroIndexInfo *micro_data_infos,
|
||||
ObMicroBlockDataHandle *micro_data_handles,
|
||||
const int64_t max_micro_handle_cnt,
|
||||
const int64_t max_prefetch_idx,
|
||||
const ObMultiBlockIOParam &multi_io_params)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const uint64_t tenant_id = MTL_ID();
|
||||
ObMacroBlockHandle macro_handle;
|
||||
if (OB_UNLIKELY(!multi_io_params.is_valid())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Unexpected io params", K(ret), K(multi_io_params));
|
||||
} else {
|
||||
const MacroBlockId ¯o_id = micro_data_infos[multi_io_params.prefetch_idx_[0] % max_micro_handle_cnt].get_macro_id();
|
||||
if (1 == multi_io_params.count()) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < multi_io_params.count(); i++) {
|
||||
const ObMicroIndexInfo &index_info = micro_data_infos[multi_io_params.prefetch_idx_[i] % max_micro_handle_cnt];
|
||||
if (OB_FAIL(data_block_cache_->prefetch(tenant_id, macro_id, index_info, true,
|
||||
macro_handle, &block_io_allocator_))) {
|
||||
LOG_WARN("Fail to prefetch micro block", K(ret), K(index_info), K(macro_handle));
|
||||
} else {
|
||||
ObMicroBlockDataHandle µ_handle = micro_data_handles[multi_io_params.prefetch_idx_[i] % max_micro_handle_cnt];
|
||||
micro_handle.block_state_ = ObSSTableMicroBlockState::IN_BLOCK_IO;
|
||||
cache_mem_ctrl_.add_hold_size(micro_handle.get_handle_size());
|
||||
micro_handle.io_handle_ = macro_handle;
|
||||
micro_handle.allocator_ = &block_io_allocator_;
|
||||
cache_mem_ctrl_.update_data_block_io_size(index_info.get_block_size(), true, true);
|
||||
}
|
||||
}
|
||||
} else if (OB_FAIL(data_block_cache_->prefetch_multi_block(
|
||||
tenant_id,
|
||||
macro_id,
|
||||
multi_io_params,
|
||||
true, /* use_cache */
|
||||
macro_handle))) {
|
||||
LOG_WARN("Fail to prefetch multi blocks", K(ret), K(multi_io_params));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < multi_io_params.count(); i++) {
|
||||
if (multi_io_params.prefetch_idx_[i] >= max_prefetch_idx) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Unexpected prefetch idx", K(ret), K(i), K(multi_io_params.prefetch_idx_[i]), K(max_prefetch_idx));
|
||||
} else {
|
||||
ObMicroBlockDataHandle µ_handle = micro_data_handles[multi_io_params.prefetch_idx_[i] % max_micro_handle_cnt];
|
||||
micro_handle.block_state_ = ObSSTableMicroBlockState::IN_BLOCK_IO;
|
||||
micro_handle.io_handle_ = macro_handle;
|
||||
micro_handle.allocator_ = &block_io_allocator_;
|
||||
micro_handle.block_index_ = i;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
cache_mem_ctrl_.add_hold_size(multi_io_params.get_data_cache_size());
|
||||
cache_mem_ctrl_.update_data_block_io_size(multi_io_params.get_data_cache_size(), true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObMicroBlockHandleMgr::submit_async_io(
|
||||
blocksstable::ObIMicroBlockCache *cache,
|
||||
const uint64_t tenant_id,
|
||||
const ObMicroIndexInfo &index_block_info,
|
||||
const bool is_data_block,
|
||||
const bool use_multi_block_prefetch,
|
||||
ObMicroBlockDataHandle µ_block_handle)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -469,7 +534,11 @@ int ObMicroBlockHandleMgr::submit_async_io(
|
||||
bool is_use_block_cache = query_flag_->is_use_block_cache();
|
||||
bool use_cache = is_data_block ? is_use_block_cache && cache_mem_ctrl_.get_cache_use_flag()
|
||||
: is_use_block_cache;
|
||||
if (OB_FAIL(cache->prefetch(tenant_id, macro_id, index_block_info, use_cache,
|
||||
if (use_cache && is_data_block && use_multi_block_prefetch) {
|
||||
micro_block_handle.block_state_ = ObSSTableMicroBlockState::NEED_MULTI_IO;
|
||||
ret = OB_SUCCESS;
|
||||
// continue and use prefetch in batch later
|
||||
} else if (OB_FAIL(cache->prefetch(tenant_id, macro_id, index_block_info, use_cache,
|
||||
macro_handle, &block_io_allocator_))) {
|
||||
LOG_WARN("Fail to prefetch micro block", K(ret), K(index_block_info), K(macro_handle),
|
||||
K(micro_block_handle));
|
||||
@ -478,7 +547,6 @@ int ObMicroBlockHandleMgr::submit_async_io(
|
||||
cache_mem_ctrl_.add_hold_size(micro_block_handle.get_handle_size());
|
||||
micro_block_handle.io_handle_ = macro_handle;
|
||||
micro_block_handle.allocator_ = &block_io_allocator_;
|
||||
micro_block_handle.need_release_data_buf_ = true;
|
||||
cache_mem_ctrl_.update_data_block_io_size(size, is_data_block, use_cache);
|
||||
}
|
||||
return ret;
|
||||
@ -495,4 +563,4 @@ bool ObMicroBlockHandleMgr::reach_hold_limit() const
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,15 +22,16 @@
|
||||
#include "storage/ob_handle_mgr.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace blocksstable;
|
||||
namespace storage {
|
||||
|
||||
|
||||
struct ObSSTableMicroBlockState {
|
||||
enum ObSSTableMicroBlockStateEnum {
|
||||
UNKNOWN_STATE = 0,
|
||||
IN_BLOCK_CACHE,
|
||||
IN_BLOCK_IO,
|
||||
NEED_SYNC_IO
|
||||
NEED_SYNC_IO,
|
||||
NEED_MULTI_IO
|
||||
};
|
||||
};
|
||||
|
||||
@ -58,7 +59,9 @@ struct ObMicroBlockDataHandle {
|
||||
ObMicroBlockDataHandle & operator=(const ObMicroBlockDataHandle &other);
|
||||
OB_INLINE bool in_block_state() const
|
||||
{ return ObSSTableMicroBlockState::IN_BLOCK_CACHE == block_state_ || ObSSTableMicroBlockState::IN_BLOCK_IO == block_state_; }
|
||||
TO_STRING_KV(K_(tenant_id), K_(macro_block_id), K_(micro_info), K_(need_release_data_buf), K_(is_loaded_block),
|
||||
OB_INLINE bool need_multi_io() const
|
||||
{ return ObSSTableMicroBlockState::NEED_MULTI_IO == block_state_; }
|
||||
TO_STRING_KV(K_(tenant_id), K_(macro_block_id), K_(micro_info), K_(is_loaded_block),
|
||||
K_(block_state), K_(block_index), K_(cache_handle), K_(io_handle), K_(loaded_block_data), KP_(allocator));
|
||||
uint64_t tenant_id_;
|
||||
blocksstable::MacroBlockId macro_block_id_;
|
||||
@ -72,7 +75,6 @@ struct ObMicroBlockDataHandle {
|
||||
ObMicroBlockHandleMgr *handle_mgr_;
|
||||
ObIAllocator *allocator_;
|
||||
blocksstable::ObMicroBlockData loaded_block_data_;
|
||||
bool need_release_data_buf_; // TODO : @lvling to be removed
|
||||
bool is_loaded_block_;
|
||||
|
||||
private:
|
||||
@ -171,13 +173,22 @@ public:
|
||||
blocksstable::ObMicroIndexInfo &index_block_info,
|
||||
const bool is_data_block,
|
||||
const bool need_submit_io,
|
||||
const bool use_multi_block_prefetch,
|
||||
ObMicroBlockDataHandle µ_block_handle,
|
||||
int16_t cur_level);
|
||||
int prefetch_multi_data_block(
|
||||
const ObMicroIndexInfo *micro_data_infos,
|
||||
ObMicroBlockDataHandle *micro_data_handles,
|
||||
const int64_t max_micro_handle_cnt,
|
||||
const int64_t max_prefetch_idx,
|
||||
const ObMultiBlockIOParam &multi_io_params);
|
||||
|
||||
int submit_async_io(
|
||||
blocksstable::ObIMicroBlockCache *cache,
|
||||
const uint64_t tenant_id,
|
||||
const blocksstable::ObMicroIndexInfo &index_block_info,
|
||||
const bool is_data_block,
|
||||
const bool use_multi_block_prefetch,
|
||||
ObMicroBlockDataHandle µ_block_handle);
|
||||
void dec_hold_size(ObMicroBlockDataHandle &handle);
|
||||
bool reach_hold_limit() const;
|
||||
|
@ -496,7 +496,7 @@ int ObAggCell::eval_micro_block(
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -933,7 +933,7 @@ int ObCountAggCell::eval_micro_block(
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -1854,7 +1854,7 @@ int ObSumOpSizeAggCell::eval_micro_block(
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -3140,7 +3140,7 @@ int ObFirstRowAggCell::eval_micro_block(
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -256,7 +256,7 @@ public:
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count);
|
||||
virtual int eval_index_info(const blocksstable::ObMicroIndexInfo &index_info, const bool is_cg = false);
|
||||
// For group by pushdown
|
||||
@ -349,7 +349,7 @@ public:
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count) override;
|
||||
virtual int eval_index_info(const blocksstable::ObMicroIndexInfo &index_info, const bool is_cg = false) override;
|
||||
virtual int eval_batch_in_group_by(
|
||||
@ -486,7 +486,7 @@ public:
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count) override;
|
||||
virtual int eval_index_info(const blocksstable::ObMicroIndexInfo &index_info, const bool is_cg = false);
|
||||
virtual int eval_batch_in_group_by(
|
||||
@ -659,7 +659,7 @@ public:
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
blocksstable::ObIMicroBlockReader *reader,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_count) override;
|
||||
virtual int eval_index_info(const blocksstable::ObMicroIndexInfo &index_info, const bool is_cg = false) override;
|
||||
virtual int eval_batch_in_group_by(
|
||||
|
@ -646,7 +646,7 @@ int ObSSTableRowScanner<PrefetchType>::forward_blockscan(
|
||||
// 1. There are more undetected rows in current range for columnar scan.
|
||||
// 2. The number of detected rows is less than defualt batch size.
|
||||
if ((IN_END_OF_RANGE != state && PENDING_BLOCK_SCAN != state)
|
||||
|| (end - begin + 1) >= OB_CS_SCAN_GROUP_SIZE) {
|
||||
|| (end - begin + 1) >= iter_param_->get_storage_rowsets_size()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,8 @@ ObTableIterParam::ObTableIterParam()
|
||||
limit_prefetch_(false),
|
||||
is_non_unique_local_index_(false),
|
||||
ss_rowkey_prefix_cnt_(0),
|
||||
pd_storage_flag_()
|
||||
pd_storage_flag_(),
|
||||
table_scan_opt_()
|
||||
{
|
||||
}
|
||||
|
||||
@ -100,6 +101,7 @@ void ObTableIterParam::reset()
|
||||
is_for_foreign_check_ = false;
|
||||
limit_prefetch_ = false;
|
||||
is_non_unique_local_index_ = false;
|
||||
table_scan_opt_.reset();
|
||||
ObSSTableIndexFilterFactory::destroy_sstable_index_filter(sstable_index_filter_);
|
||||
}
|
||||
|
||||
@ -184,7 +186,8 @@ DEF_TO_STRING(ObTableIterParam)
|
||||
K_(is_for_foreign_check),
|
||||
K_(limit_prefetch),
|
||||
K_(is_non_unique_local_index),
|
||||
K_(ss_rowkey_prefix_cnt));
|
||||
K_(ss_rowkey_prefix_cnt),
|
||||
K_(table_scan_opt));
|
||||
J_OBJ_END();
|
||||
return pos;
|
||||
}
|
||||
@ -260,6 +263,18 @@ int ObTableAccessParam::init(
|
||||
iter_param_.read_info_->get_schema_column_count() == iter_param_.rowkey_read_info_->get_schema_column_count();
|
||||
|
||||
iter_param_.pd_storage_flag_ = scan_param.pd_storage_flag_;
|
||||
if (scan_param.table_scan_opt_.is_io_valid()) {
|
||||
iter_param_.table_scan_opt_.io_read_batch_size_ = scan_param.table_scan_opt_.io_read_batch_size_;
|
||||
iter_param_.table_scan_opt_.io_read_gap_size_ = scan_param.table_scan_opt_.io_read_gap_size_;
|
||||
} else {
|
||||
iter_param_.table_scan_opt_.io_read_batch_size_ = 0;
|
||||
iter_param_.table_scan_opt_.io_read_gap_size_ = 0;
|
||||
}
|
||||
if (scan_param.table_scan_opt_.is_rowsets_valid()) {
|
||||
iter_param_.table_scan_opt_.storage_rowsets_size_ = scan_param.table_scan_opt_.storage_rowsets_size_;
|
||||
} else {
|
||||
iter_param_.table_scan_opt_.storage_rowsets_size_ = 1;
|
||||
}
|
||||
iter_param_.pushdown_filter_ = scan_param.pd_storage_filters_;
|
||||
// disable blockscan if scan order is KeepOrder(for iterator iterator and table api)
|
||||
// disable blockscan if use index skip scan as no large range to scan
|
||||
|
@ -175,6 +175,12 @@ public:
|
||||
!pd_storage_flag_.is_group_by_pushdown() &&
|
||||
!pd_storage_flag_.is_aggregate_pushdown();
|
||||
}
|
||||
OB_INLINE int64_t get_io_read_batch_size() const
|
||||
{ return table_scan_opt_.io_read_batch_size_; }
|
||||
OB_INLINE int64_t get_io_read_gap_size() const
|
||||
{ return table_scan_opt_.io_read_gap_size_; }
|
||||
OB_INLINE int64_t get_storage_rowsets_size() const
|
||||
{ return table_scan_opt_.storage_rowsets_size_; }
|
||||
DECLARE_TO_STRING;
|
||||
public:
|
||||
uint64_t table_id_;
|
||||
@ -212,6 +218,7 @@ public:
|
||||
bool is_non_unique_local_index_;
|
||||
int64_t ss_rowkey_prefix_cnt_;
|
||||
sql::ObStoragePushdownFlag pd_storage_flag_;
|
||||
ObTableScanOption table_scan_opt_;
|
||||
};
|
||||
|
||||
struct ObTableAccessParam
|
||||
|
@ -315,7 +315,7 @@ int ObVectorStore::fill_output_rows(
|
||||
}
|
||||
LOG_TRACE("[Vectorized] vector store copy rows", K(ret),
|
||||
K(begin_index), K(end_index), K(row_capacity), K(res),
|
||||
"row_ids", common::ObArrayWrap<const int64_t>(row_ids_, row_capacity),
|
||||
"row_ids", common::ObArrayWrap<const int32_t>(row_ids_, row_capacity),
|
||||
KPC(this));
|
||||
return ret;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace blocksstable
|
||||
{
|
||||
|
||||
int ObCSVectorDecodingUtil::decode_all_null_vector(
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
sql::VectorHeader &vec_header,
|
||||
const int64_t vec_offset)
|
||||
|
@ -26,7 +26,7 @@ class ObCSVectorDecodingUtil final
|
||||
{
|
||||
public:
|
||||
static int decode_all_null_vector(
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
sql::VectorHeader &vec_header,
|
||||
const int64_t vec_offset);
|
||||
@ -35,4 +35,4 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -160,7 +160,7 @@ void ObDictValueIterator::build_decode_by_ref_func_()
|
||||
|
||||
int ObDictColumnDecoder::get_null_count(
|
||||
const ObColumnCSDecoderCtx &col_ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
int64_t &null_count) const
|
||||
{
|
||||
@ -204,7 +204,7 @@ int ObDictColumnDecoder::get_null_count(
|
||||
int ObDictColumnDecoder::extract_ref_and_null_count_(
|
||||
const ObConstEncodingRefDesc &ref_desc,
|
||||
const int64_t dict_count,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums,
|
||||
int64_t &null_count,
|
||||
@ -2225,7 +2225,7 @@ int ObDictColumnDecoder::read_distinct(
|
||||
|
||||
int ObDictColumnDecoder::read_reference(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObGroupByCell &group_by_cell) const
|
||||
{
|
||||
@ -2258,7 +2258,7 @@ int ObDictColumnDecoder::read_reference(
|
||||
|
||||
int ObDictColumnDecoder::get_aggregate_result(
|
||||
const ObColumnCSDecoderCtx &col_ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObAggCell &agg_cell) const
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
virtual ~ObDictColumnDecoder() {}
|
||||
ObDictColumnDecoder(const ObDictColumnDecoder &) = delete;
|
||||
ObDictColumnDecoder &operator=(const ObDictColumnDecoder &) = delete;
|
||||
virtual int get_null_count(const ObColumnCSDecoderCtx &ctx, const int64_t *row_ids,
|
||||
virtual int get_null_count(const ObColumnCSDecoderCtx &ctx, const int32_t *row_ids,
|
||||
const int64_t row_cap, int64_t &null_count) const override;
|
||||
|
||||
virtual int pushdown_operator(
|
||||
@ -50,7 +50,7 @@ public:
|
||||
|
||||
virtual int get_aggregate_result(
|
||||
const ObColumnCSDecoderCtx &col_ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObAggCell &agg_cell) const override;
|
||||
|
||||
@ -64,7 +64,7 @@ public:
|
||||
|
||||
virtual int read_reference(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObGroupByCell &group_by_cell) const override;
|
||||
|
||||
@ -119,7 +119,7 @@ protected:
|
||||
static int extract_ref_and_null_count_(
|
||||
const ObConstEncodingRefDesc &ref_desc,
|
||||
const int64_t dict_count,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums,
|
||||
int64_t &null_count,
|
||||
|
@ -24,7 +24,7 @@ using namespace common;
|
||||
|
||||
int ObIColumnCSDecoder::get_null_count(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
int64_t &null_count) const
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
OB_INLINE void reuse() {}
|
||||
|
||||
VIRTUAL_TO_STRING_KV(K(this));
|
||||
virtual int decode(const ObColumnCSDecoderCtx &ctx, const int64_t row_id, common::ObDatum &datum) const = 0;
|
||||
virtual int decode(const ObColumnCSDecoderCtx &ctx, const int32_t row_id, common::ObDatum &datum) const = 0;
|
||||
|
||||
virtual ObCSColumnHeader::Type get_type() const = 0;
|
||||
|
||||
@ -53,7 +53,7 @@ public:
|
||||
// Performance critical, only check pointer once in caller
|
||||
virtual int batch_decode(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums) const
|
||||
{
|
||||
@ -93,7 +93,7 @@ public:
|
||||
|
||||
virtual int get_aggregate_result(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObAggCell &agg_cell) const
|
||||
{
|
||||
@ -103,7 +103,7 @@ public:
|
||||
|
||||
virtual int get_null_count(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
int64_t &null_count) const;
|
||||
|
||||
@ -123,7 +123,7 @@ public:
|
||||
|
||||
virtual int read_reference(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObGroupByCell &group_by_cell) const
|
||||
{
|
||||
@ -137,7 +137,7 @@ class ObNoneExistColumnCSDecoder : public ObIColumnCSDecoder
|
||||
public:
|
||||
static const ObCSColumnHeader::Type type_ = ObCSColumnHeader::MAX_TYPE;
|
||||
|
||||
virtual int decode(const ObColumnCSDecoderCtx &ctx, const int64_t row_id, common::ObDatum &datum) const override
|
||||
virtual int decode(const ObColumnCSDecoderCtx &ctx, const int32_t row_id, common::ObDatum &datum) const override
|
||||
{
|
||||
datum.set_ext();
|
||||
datum.no_cv(datum.extend_obj_)->set_ext(common::ObActionFlag::OP_NOP);
|
||||
|
@ -23,7 +23,7 @@ namespace oceanbase
|
||||
namespace blocksstable
|
||||
{
|
||||
int ObIntDictColumnDecoder::decode(
|
||||
const ObColumnCSDecoderCtx &ctx, const int64_t row_id, common::ObDatum &datum) const
|
||||
const ObColumnCSDecoderCtx &ctx, const int32_t row_id, common::ObDatum &datum) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObDictColumnDecoderCtx &dict_ctx = ctx.dict_ctx_;
|
||||
@ -93,7 +93,7 @@ int ObIntDictColumnDecoder::decode_and_aggregate(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObIntDictColumnDecoder::batch_decode(const ObColumnCSDecoderCtx &ctx, const int64_t *row_ids,
|
||||
int ObIntDictColumnDecoder::batch_decode(const ObColumnCSDecoderCtx &ctx, const int32_t *row_ids,
|
||||
const int64_t row_cap, common::ObDatum *datums) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -30,8 +30,8 @@ public:
|
||||
ObIntDictColumnDecoder &operator=(const ObDictColumnDecoder &) = delete;
|
||||
|
||||
virtual int decode(
|
||||
const ObColumnCSDecoderCtx &ctx, const int64_t row_id, common::ObDatum &datum) const override;
|
||||
virtual int batch_decode(const ObColumnCSDecoderCtx &ctx, const int64_t *row_ids,
|
||||
const ObColumnCSDecoderCtx &ctx, const int32_t row_id, common::ObDatum &datum) const override;
|
||||
virtual int batch_decode(const ObColumnCSDecoderCtx &ctx, const int32_t *row_ids,
|
||||
const int64_t row_cap, common::ObDatum *datums) const override;
|
||||
virtual int decode_vector(const ObColumnCSDecoderCtx &ctx, ObVectorDecodeCtx &vector_ctx) const override;
|
||||
virtual int decode_and_aggregate(
|
||||
|
@ -26,7 +26,7 @@ using namespace oceanbase::common;
|
||||
using namespace oceanbase::share;
|
||||
|
||||
int ObIntegerColumnDecoder::decode(const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t row_id,
|
||||
const int32_t row_id,
|
||||
common::ObDatum &datum) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -42,7 +42,7 @@ int ObIntegerColumnDecoder::decode(const ObColumnCSDecoderCtx &ctx,
|
||||
}
|
||||
|
||||
int ObIntegerColumnDecoder::batch_decode(const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids, const int64_t row_cap, common::ObDatum *datums) const
|
||||
const int32_t *row_ids, const int64_t row_cap, common::ObDatum *datums) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObIntegerColumnDecoderCtx &integer_ctx = ctx.integer_ctx_;
|
||||
@ -70,7 +70,7 @@ int ObIntegerColumnDecoder::decode_vector(
|
||||
|
||||
int ObIntegerColumnDecoder::get_null_count(
|
||||
const ObColumnCSDecoderCtx &col_ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
int64_t &null_count) const
|
||||
{
|
||||
@ -706,7 +706,7 @@ int ObIntegerColumnDecoder::tranverse_datum_all_op(
|
||||
|
||||
int ObIntegerColumnDecoder::get_aggregate_result(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObAggCell &agg_cell) const
|
||||
{
|
||||
|
@ -30,13 +30,13 @@ public:
|
||||
ObIntegerColumnDecoder &operator=(const ObIntegerColumnDecoder&) = delete;
|
||||
|
||||
virtual int decode(const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t row_id, common::ObDatum &datum) const override;
|
||||
virtual int batch_decode(const ObColumnCSDecoderCtx &ctx, const int64_t *row_ids,
|
||||
const int32_t row_id, common::ObDatum &datum) const override;
|
||||
virtual int batch_decode(const ObColumnCSDecoderCtx &ctx, const int32_t *row_ids,
|
||||
const int64_t row_cap, common::ObDatum *datums) const override;
|
||||
virtual int decode_vector(const ObColumnCSDecoderCtx &ctx, ObVectorDecodeCtx &vector_ctx) const override;
|
||||
|
||||
virtual int get_null_count(const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids, const int64_t row_cap, int64_t &null_count) const override;
|
||||
const int32_t *row_ids, const int64_t row_cap, int64_t &null_count) const override;
|
||||
|
||||
virtual ObCSColumnHeader::Type get_type() const override { return type_; }
|
||||
|
||||
@ -49,7 +49,7 @@ public:
|
||||
|
||||
virtual int get_aggregate_result(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObAggCell &agg_cell) const override;
|
||||
|
||||
|
@ -40,7 +40,7 @@ struct ConvertUintToDatum_T
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums)
|
||||
{
|
||||
@ -63,7 +63,7 @@ struct ConvertUintToDatum_T<store_len_V,
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums)
|
||||
{
|
||||
@ -109,7 +109,7 @@ struct ConvertUintToDatum_T<store_len_V,
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums)
|
||||
{
|
||||
@ -147,7 +147,7 @@ struct ConvertUintToDatum_T<store_len_V,
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums)
|
||||
{
|
||||
@ -190,7 +190,7 @@ struct ConvertUintToDatum_T<store_len_V,
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums)
|
||||
{
|
||||
@ -227,7 +227,7 @@ struct ConvertUintToDatum_T<store_len_V,
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums)
|
||||
{
|
||||
@ -269,7 +269,7 @@ struct ConvertUintToDatum_T<store_len_V,
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums)
|
||||
{
|
||||
@ -310,7 +310,7 @@ struct ConvertUintToDatum_T<store_len_V,
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums)
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ typedef void (*ConvertUnitToDatumFunc)(
|
||||
const char *data,
|
||||
const ObIntegerStreamDecoderCtx &ctx,
|
||||
const char *ref_data,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *datums);
|
||||
|
||||
|
@ -158,7 +158,7 @@ int ObColumnCSDecoder::decode(const int64_t row_id, common::ObDatum &datum)
|
||||
}
|
||||
|
||||
int ObColumnCSDecoder::batch_decode(
|
||||
const int64_t *row_ids, const int64_t row_cap, common::ObDatum *datums)
|
||||
const int32_t *row_ids, const int64_t row_cap, common::ObDatum *datums)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(nullptr == row_ids || nullptr == datums || 0 >= row_cap)) {
|
||||
@ -172,7 +172,7 @@ int ObColumnCSDecoder::batch_decode(
|
||||
}
|
||||
|
||||
LOG_DEBUG("[Batch decode] Batch decoded datums: ", K(ret), K(row_cap), K(*ctx_),
|
||||
K(ObArrayWrap<int64_t>(row_ids, row_cap)), K(ObArrayWrap<ObDatum>(datums, row_cap)));
|
||||
K(ObArrayWrap<int32_t>(row_ids, row_cap)), K(ObArrayWrap<ObDatum>(datums, row_cap)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ int ObColumnCSDecoder::decode_vector(ObVectorDecodeCtx &vector_ctx)
|
||||
}
|
||||
|
||||
int ObColumnCSDecoder::get_row_count(
|
||||
const int64_t *row_ids, const int64_t row_cap, const bool contains_null, int64_t &count)
|
||||
const int32_t *row_ids, const int64_t row_cap, const bool contains_null, int64_t &count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t null_count = 0;
|
||||
@ -1559,7 +1559,7 @@ int ObMicroBlockCSDecoder::filter_black_filter_batch(
|
||||
int ObMicroBlockCSDecoder::get_rows(
|
||||
const common::ObIArray<int32_t> &cols,
|
||||
const common::ObIArray<const share::schema::ObColumnParam *> &col_params,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const char **cell_datas,
|
||||
const int64_t row_cap,
|
||||
common::ObIArray<ObSqlDatumInfo> &datum_infos,
|
||||
@ -1598,7 +1598,7 @@ int ObMicroBlockCSDecoder::get_rows(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObMicroBlockCSDecoder::get_row_count(int32_t col_id, const int64_t *row_ids,
|
||||
int ObMicroBlockCSDecoder::get_row_count(int32_t col_id, const int32_t *row_ids,
|
||||
const int64_t row_cap, const bool contains_null, const share::schema::ObColumnParam *col_param, int64_t &count)
|
||||
{
|
||||
UNUSED(col_param);
|
||||
@ -1609,7 +1609,7 @@ int ObMicroBlockCSDecoder::get_row_count(int32_t col_id, const int64_t *row_ids,
|
||||
LOG_WARN("not init", K(ret));
|
||||
} else if (OB_FAIL(decoders_[col_id].get_row_count(row_ids, row_cap, contains_null, count))) {
|
||||
LOG_WARN("fail to get datums from decoder", K(ret), K(col_id), K(row_cap), "row_ids",
|
||||
common::ObArrayWrap<const int64_t>(row_ids, row_cap));
|
||||
common::ObArrayWrap<const int32_t>(row_ids, row_cap));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1645,7 +1645,7 @@ int ObMicroBlockCSDecoder::get_column_datum(
|
||||
|
||||
bool ObMicroBlockCSDecoder::can_pushdown_decoder(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
const ObAggCell &agg_cell) const
|
||||
{
|
||||
@ -1680,7 +1680,7 @@ int ObMicroBlockCSDecoder::get_aggregate_result(
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
const share::schema::ObColumnParam &col_param,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObAggDatumBuf &agg_datum_buf,
|
||||
ObAggCell &agg_cell)
|
||||
@ -1732,7 +1732,7 @@ int ObMicroBlockCSDecoder::get_aggregate_result(
|
||||
|
||||
int ObMicroBlockCSDecoder::get_col_datums(
|
||||
int32_t col_id,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
common::ObDatum *col_datums)
|
||||
{
|
||||
@ -1751,7 +1751,7 @@ int ObMicroBlockCSDecoder::get_col_datums(
|
||||
}
|
||||
} else if (OB_FAIL(decoders_[col_id].batch_decode(row_ids, row_cap, col_datums))) {
|
||||
LOG_WARN("fail to get datums from decoder", K(ret), K(col_id), K(row_cap),
|
||||
"row_ids", common::ObArrayWrap<const int64_t>(row_ids, row_cap));
|
||||
"row_ids", common::ObArrayWrap<const int32_t>(row_ids, row_cap));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1789,7 +1789,7 @@ int ObMicroBlockCSDecoder::read_distinct(
|
||||
|
||||
int ObMicroBlockCSDecoder::read_reference(
|
||||
const int32_t group_by_col,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObGroupByCell &group_by_cell) const
|
||||
{
|
||||
@ -1807,7 +1807,7 @@ int ObMicroBlockCSDecoder::read_reference(
|
||||
}
|
||||
|
||||
int ObMicroBlockCSDecoder::get_group_by_aggregate_result(
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const char **cell_datas,
|
||||
const int64_t row_cap,
|
||||
storage::ObGroupByCell &group_by_cell)
|
||||
@ -1847,7 +1847,7 @@ int ObMicroBlockCSDecoder::get_group_by_aggregate_result(
|
||||
int ObMicroBlockCSDecoder::get_rows(
|
||||
const common::ObIArray<int32_t> &cols,
|
||||
const common::ObIArray<const share::schema::ObColumnParam *> &col_params,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
const char **cell_datas,
|
||||
const int64_t vec_offset,
|
||||
|
@ -46,17 +46,17 @@ public:
|
||||
int quick_compare(const ObStorageDatum &left, const ObStorageDatumCmpFunc &cmp_func,
|
||||
const int64_t row_id, int32_t &cmp_ret);
|
||||
|
||||
int batch_decode(const int64_t *row_ids, const int64_t row_cap, common::ObDatum *datums);
|
||||
int batch_decode(const int32_t *row_ids, const int64_t row_cap, common::ObDatum *datums);
|
||||
int decode_vector(ObVectorDecodeCtx &vector_ctx);
|
||||
int get_row_count(
|
||||
const int64_t *row_ids, const int64_t row_cap, const bool contains_null, int64_t &count);
|
||||
const int32_t *row_ids, const int64_t row_cap, const bool contains_null, int64_t &count);
|
||||
OB_INLINE int get_distinct_count(int64_t &distinct_cnt) const
|
||||
{ return decoder_->get_distinct_count(*ctx_, distinct_cnt); }
|
||||
OB_INLINE int read_distinct(
|
||||
storage::ObGroupByCell &group_by_cell) const
|
||||
{ return decoder_->read_distinct(*ctx_, group_by_cell); }
|
||||
OB_INLINE int read_reference(
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObGroupByCell &group_by_cell) const
|
||||
{ return decoder_->read_reference(*ctx_, row_ids, row_cap, group_by_cell); }
|
||||
@ -212,12 +212,12 @@ public:
|
||||
virtual int get_rows(
|
||||
const common::ObIArray<int32_t> &cols,
|
||||
const common::ObIArray<const share::schema::ObColumnParam *> &col_params,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const char **cell_datas,
|
||||
const int64_t row_cap,
|
||||
common::ObIArray<ObSqlDatumInfo> &datum_infos,
|
||||
const int64_t datum_offset = 0) override;
|
||||
virtual int get_row_count(int32_t col_id, const int64_t *row_ids, const int64_t row_cap,
|
||||
virtual int get_row_count(int32_t col_id, const int32_t *row_ids, const int64_t row_cap,
|
||||
const bool contains_null, const share::schema::ObColumnParam *col_param, int64_t &count) override final;
|
||||
virtual int64_t get_column_count() const override
|
||||
{
|
||||
@ -246,21 +246,21 @@ public:
|
||||
const ObTableAccessContext &context,
|
||||
const int32_t col_offset,
|
||||
const share::schema::ObColumnParam &col_param,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
storage::ObAggDatumBuf &agg_datum_buf,
|
||||
ObAggCell &agg_cell) override;
|
||||
virtual int get_distinct_count(const int32_t group_by_col, int64_t &distinct_cnt) const override;
|
||||
virtual int read_distinct(const int32_t group_by_col, const char **cell_datas,
|
||||
storage::ObGroupByCell &group_by_cell) const override;
|
||||
virtual int read_reference(const int32_t group_by_col, const int64_t *row_ids,
|
||||
virtual int read_reference(const int32_t group_by_col, const int32_t *row_ids,
|
||||
const int64_t row_cap, storage::ObGroupByCell &group_by_cell) const override;
|
||||
virtual int get_group_by_aggregate_result(const int64_t *row_ids, const char **cell_datas,
|
||||
virtual int get_group_by_aggregate_result(const int32_t *row_ids, const char **cell_datas,
|
||||
const int64_t row_cap, storage::ObGroupByCell &group_by_cell) override;
|
||||
virtual int get_rows(
|
||||
const common::ObIArray<int32_t> &cols,
|
||||
const common::ObIArray<const share::schema::ObColumnParam *> &col_params,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
const char **cell_datas,
|
||||
const int64_t vec_offset,
|
||||
@ -284,7 +284,7 @@ private:
|
||||
int get_row_impl(int64_t index, ObDatumRow &row);
|
||||
bool can_pushdown_decoder(
|
||||
const ObColumnCSDecoderCtx &ctx,
|
||||
const int64_t *row_ids,
|
||||
const int32_t *row_ids,
|
||||
const int64_t row_cap,
|
||||
const ObAggCell &agg_cell) const;
|
||||
OB_INLINE static const ObRowHeader &get_major_store_row_header()
|
||||
@ -304,7 +304,7 @@ private:
|
||||
sql::ObWhiteFilterExecutor &filter, const sql::PushdownFilterInfo &pd_filter_info,
|
||||
const int32_t col_offset, const share::schema::ObColumnParam *col_param,
|
||||
ObStorageDatum &decoded_datum, common::ObBitmap &result_bitmap);
|
||||
int get_col_datums(int32_t col_id, const int64_t *row_ids, const int64_t row_cap, common::ObDatum *col_datums);
|
||||
int get_col_datums(int32_t col_id, const int32_t *row_ids, const int64_t row_cap, common::ObDatum *col_datums);
|
||||
int get_col_data(int32_t col_id, ObVectorDecodeCtx &ctx);
|
||||
|
||||
private:
|
||||
|
@ -23,7 +23,7 @@ namespace oceanbase
|
||||
namespace blocksstable
|
||||
{
|
||||
int ObStrDictColumnDecoder::decode(
|
||||
const ObColumnCSDecoderCtx &ctx, const int64_t row_id, common::ObDatum &datum) const
|
||||
const ObColumnCSDecoderCtx &ctx, const int32_t row_id, common::ObDatum &datum) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObDictColumnDecoderCtx &dict_ctx = ctx.dict_ctx_;
|
||||
@ -96,7 +96,7 @@ int ObStrDictColumnDecoder::decode_and_aggregate(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObStrDictColumnDecoder::batch_decode(const ObColumnCSDecoderCtx &ctx, const int64_t *row_ids,
|
||||
int ObStrDictColumnDecoder::batch_decode(const ObColumnCSDecoderCtx &ctx, const int32_t *row_ids,
|
||||
const int64_t row_cap, common::ObDatum *datums) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -30,8 +30,8 @@ public:
|
||||
ObStrDictColumnDecoder &operator=(const ObStrDictColumnDecoder &) = delete;
|
||||
|
||||
virtual int decode(
|
||||
const ObColumnCSDecoderCtx &ctx, const int64_t row_id, common::ObDatum &datum) const override;
|
||||
virtual int batch_decode(const ObColumnCSDecoderCtx &ctx, const int64_t *row_ids,
|
||||
const ObColumnCSDecoderCtx &ctx, const int32_t row_id, common::ObDatum &datum) const override;
|
||||
virtual int batch_decode(const ObColumnCSDecoderCtx &ctx, const int32_t *row_ids,
|
||||
const int64_t row_cap, common::ObDatum *datums) const override;
|
||||
virtual int decode_vector(const ObColumnCSDecoderCtx &ctx, ObVectorDecodeCtx &vector_ctx) const override;
|
||||
virtual int decode_and_aggregate(
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user