Files
oceanbase/src/storage/blocksstable/encoding/ob_encoding_allocator.ipp

166 lines
4.9 KiB
C++

/**
* 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.
*/
template <typename EncodingItem>
ObEncodingPool<EncodingItem>::ObEncodingPool(const int64_t item_size, const ObMemAttr &attr)
: free_items_(), free_cnt_(0),
pool_(item_size, common::OB_MALLOC_NORMAL_BLOCK_SIZE,
common::ObMalloc(attr))
{
}
template <typename EncodingItem>
ObEncodingPool<EncodingItem>::~ObEncodingPool()
{
while (free_cnt_ > 0) {
free_items_[free_cnt_ - 1]->~EncodingItem();
--free_cnt_;
}
}
template <typename EncodingItem>
template <typename T>
inline int ObEncodingPool<EncodingItem>::alloc(T *&item)
{
int ret = common::OB_SUCCESS;
item = NULL;
if (OB_UNLIKELY(free_cnt_ <= 0)) {
void *p = pool_.alloc();
if (NULL == p) {
ret = common::OB_ALLOCATE_MEMORY_FAILED;
STORAGE_LOG(WARN, "allocate memory failed", K(ret));
} else {
item = new (p) T();
}
} else {
item = static_cast<T *>(free_items_[free_cnt_ - 1]);
item->reuse();
--free_cnt_;
}
return ret;
}
template <typename EncodingItem>
inline void ObEncodingPool<EncodingItem>::free(EncodingItem *item)
{
if (NULL != item) {
if (free_cnt_ < MAX_FREE_ITEM_CNT) {
free_items_[free_cnt_] = item;
++free_cnt_;
} else {
item->~EncodingItem();
pool_.free(item);
item = NULL;
}
}
}
template <typename EncodingItem>
ObEncodingAllocator<EncodingItem>::ObEncodingAllocator(const int64_t *size_array, const ObMemAttr &attr)
: inited_(false),
size_index_(0),
raw_pool_(size_array[size_index_++], attr),
dict_pool_(size_array[size_index_++], attr),
rle_pool_(size_array[size_index_++], attr),
const_pool_(size_array[size_index_++], attr),
int_diff_pool_(size_array[size_index_++], attr),
str_diff_pool_(size_array[size_index_++], attr),
hex_str_pool_(size_array[size_index_++], attr),
str_prefix_pool_(size_array[size_index_++], attr),
column_equal_pool_(size_array[size_index_++], attr),
column_substr_pool_(size_array[size_index_++], attr),
pool_cnt_(0)
{
for (int64_t i = 0; i < ObColumnHeader::MAX_TYPE; i++) {
pools_[i] = NULL;
}
}
template <typename EncodingItem>
int ObEncodingAllocator<EncodingItem>::init()
{
int ret = common::OB_SUCCESS;
// can init twice
if (!inited_) {
MEMSET(pools_, 0, sizeof(pools_));
if (OB_FAIL(add_pool(&raw_pool_))
|| OB_FAIL(add_pool(&dict_pool_))
|| OB_FAIL(add_pool(&rle_pool_))
|| OB_FAIL(add_pool(&const_pool_))
|| OB_FAIL(add_pool(&int_diff_pool_))
|| OB_FAIL(add_pool(&str_diff_pool_))
|| OB_FAIL(add_pool(&hex_str_pool_))
|| OB_FAIL(add_pool(&str_prefix_pool_))
|| OB_FAIL(add_pool(&column_equal_pool_))
|| OB_FAIL(add_pool(&column_substr_pool_))) {
STORAGE_LOG(WARN, "add_pool failed", K(ret));
} else if (pool_cnt_ != size_index_) {
ret = common::OB_INNER_STAT_ERROR;
STORAGE_LOG(WARN, "pool_cnt and size_index not same", K(ret), K_(pool_cnt), K_(size_index));
} else if (pool_cnt_ != ObColumnHeader::MAX_TYPE) {
ret = common::OB_INNER_STAT_ERROR;
STORAGE_LOG(WARN, "not all encoder has pool", K(ret), K_(pool_cnt),
"encoder cnt", ObColumnHeader::MAX_TYPE);
} else {
inited_ = true;
}
}
return ret;
}
template <typename EncodingItem>
template<typename T>
inline int ObEncodingAllocator<EncodingItem>::alloc(T *&item)
{
int ret = common::OB_SUCCESS;
item = NULL;
if (OB_UNLIKELY(!inited_)) {
ret = common::OB_NOT_INIT;
STORAGE_LOG(WARN, "not init", K(ret));
} else {
// performance critical, don't check params
if (OB_FAIL(pools_[T::type_]->alloc(item))) {
STORAGE_LOG(WARN, "allocate failed", K(ret));
}
}
return ret;
}
template <typename EncodingItem>
inline void ObEncodingAllocator<EncodingItem>::free(EncodingItem *item)
{
if (NULL != item) {
// performance critical, don't check params
pools_[item->get_type()]->free(item);
item = NULL;
}
}
template <typename EncodingItem>
int ObEncodingAllocator<EncodingItem>::add_pool(Pool *pool)
{
int ret = common::OB_SUCCESS;
if (NULL == pool) {
ret = common::OB_INVALID_ARGUMENT;
STORAGE_LOG(WARN, "pool is null", K(ret));
} else if (pool_cnt_ >= ObColumnHeader::MAX_TYPE) {
ret = common::OB_SIZE_OVERFLOW;
STORAGE_LOG(WARN, "pool array size overflow", K(ret), K_(pool_cnt),
"pool array size", ObColumnHeader::MAX_TYPE);
} else {
pools_[pool_cnt_] = pool;
++pool_cnt_;
}
return ret;
}