Files
oceanbase/src/sql/executor/ob_interm_result_item_pool.cpp
oceanbase-admin cea7de1475 init push
2021-05-31 22:56:52 +08:00

162 lines
5.0 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.
*/
#define USING_LOG_PREFIX SQL_EXE
#include "sql/executor/ob_interm_result_item_pool.h"
#include "sql/executor/ob_task_event.h"
#include "lib/alloc/alloc_func.h"
using namespace oceanbase::common;
namespace oceanbase {
namespace sql {
ObIntermResultItemPool* ObIntermResultItemPool::instance_ = NULL;
ObIntermResultItemPool::ObIntermResultItemPool() : inited_(false), mem_item_allocator_(), disk_item_allocator_()
{}
ObIntermResultItemPool::~ObIntermResultItemPool()
{
reset();
}
void ObIntermResultItemPool::reset()
{
int ret = OB_SUCCESS;
inited_ = false;
if (OB_FAIL(mem_item_allocator_.destroy())) {
LOG_ERROR("fail to destroy allocator", K(ret));
} else if (OB_FAIL(disk_item_allocator_.destroy())) {
LOG_ERROR("fail to destroy allocator", K(ret));
}
}
int ObIntermResultItemPool::build_instance()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(NULL != instance_)) {
ret = OB_INIT_TWICE;
LOG_ERROR("instance is not NULL, build twice", K(ret));
} else if (OB_ISNULL(instance_ = OB_NEW(ObIntermResultItemPool, ObModIds::OB_SQL_EXECUTOR))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("instance is NULL, unexpected", K(ret));
} else if (OB_FAIL(instance_->init())) {
instance_->reset();
OB_DELETE(ObIntermResultItemPool, ObModIds::OB_SQL_EXECUTOR, instance_);
instance_ = NULL;
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to init scanner pool", K(ret));
} else {
}
return ret;
}
ObIntermResultItemPool* ObIntermResultItemPool::get_instance()
{
ObIntermResultItemPool* instance = NULL;
if (OB_ISNULL(instance_) || OB_UNLIKELY(!instance_->inited_)) {
LOG_ERROR("instance is NULL or not inited", K(instance_));
} else {
instance = instance_;
}
return instance;
}
int ObIntermResultItemPool::init()
{
const static int64_t block_size = OB_MALLOC_NORMAL_BLOCK_SIZE;
int ret = OB_SUCCESS;
if (OB_UNLIKELY(inited_)) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else if (OB_FAIL(mem_item_allocator_.init(sizeof(ObIntermResultItem),
ObModIds::OB_SQL_EXECUTOR,
OB_SERVER_TENANT_ID,
block_size,
1,
get_capacity()))) {
LOG_WARN("fail to init allocator", K(ret), "capacity", get_capacity());
} else if (OB_FAIL(disk_item_allocator_.init(sizeof(ObDiskIntermResultItem),
ObModIds::OB_SQL_EXECUTOR,
OB_SERVER_TENANT_ID,
block_size,
1,
get_capacity()))) {
LOG_WARN("fail to init allocator", K(ret), "capacity", get_capacity());
} else {
inited_ = true;
LOG_INFO("initialize scanner pool", "size", get_capacity());
}
return ret;
}
int ObIntermResultItemPool::alloc_mem_item(ObIntermResultItem*& ir_item, const uint64_t tenant_id)
{
int ret = OB_SUCCESS;
void* ir_item_ptr = NULL;
if (OB_ISNULL(ir_item_ptr = mem_item_allocator_.alloc())) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to alloc scanner from obj pool", K(ret));
} else if (OB_ISNULL(ir_item = new (ir_item_ptr)
ObIntermResultItem(ObModIds::OB_SQL_EXECUTOR_INTERM_RESULT_ITEM, tenant_id))) {
LOG_WARN("fail to new ObIntermResultItem", K(ret), K(tenant_id));
}
return ret;
}
int ObIntermResultItemPool::alloc_disk_item(ObDiskIntermResultItem*& item, const uint64_t tenant_id, const int64_t fd,
const int64_t dir_id, const int64_t offset)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
void* mem = disk_item_allocator_.alloc();
if (OB_ISNULL(mem)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("failed to alloc disk interim result item", K(ret));
} else {
ObDiskIntermResultItem* it = new (mem) ObDiskIntermResultItem();
if (OB_FAIL(it->init(tenant_id, fd, dir_id, offset))) {
LOG_WARN("init disk interim result item failed", K(ret), K(tenant_id), K(fd), K(offset));
it->~ObDiskIntermResultItem();
it = NULL;
disk_item_allocator_.free(mem);
mem = NULL;
} else {
item = it;
}
}
}
return ret;
}
int ObIntermResultItemPool::free(ObIIntermResultItem* item)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(item)) {
ret = OB_INVALID_ARGUMENT;
LOG_ERROR("interm result item is NULL", K(ret));
} else {
ObSmallAllocator& allocator = get_allocator(item->in_memory());
item->~ObIIntermResultItem();
allocator.free(item);
item = NULL;
}
return ret;
}
} // namespace sql
} // namespace oceanbase