init push

This commit is contained in:
oceanbase-admin
2021-05-31 22:56:52 +08:00
commit cea7de1475
7020 changed files with 5689869 additions and 0 deletions

View File

@ -0,0 +1,215 @@
/**
* 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.
*/
#ifndef OCEANBASE_LIB_QUEUE_M_FIXED_QUEUE_H_
#define OCEANBASE_LIB_QUEUE_M_FIXED_QUEUE_H_
#include "lib/queue/ob_fixed_queue.h" // ObFixedQueue
#include "common/ob_queue_thread.h" // ObCond
namespace oceanbase {
namespace common {
const int64_t DefaultMaxQueueNum = 32;
const int64_t DefaultQueueNum = 0;
template <int MAX_QUEUE_NUM = DefaultMaxQueueNum>
class ObMultiFixedQueue {
public:
ObMultiFixedQueue() : inited_(false), queue_num_(DefaultQueueNum)
{}
virtual ~ObMultiFixedQueue()
{
int ret = OB_SUCCESS;
if (OB_SUCCESS != (ret = destroy())) {
LIB_LOG(ERROR, "err destroy multi fixed queue", K(ret));
}
}
public:
int init(const int64_t queue_size, const int64_t queue_num);
int destroy();
int push(void* data, const uint64_t hash_val, const int64_t timeout);
int pop(void*& data, const int64_t queue_index, const int64_t timeout);
int get_task_count(const int64_t queue_index, int64_t& task_count);
private:
int init_queue_(const int64_t queue_num, const int64_t queue_size);
void destroy_queue_(const int64_t queue_num);
private:
bool inited_;
ObFixedQueue<void> queue_[MAX_QUEUE_NUM];
ObCond queue_conds_[MAX_QUEUE_NUM];
int64_t queue_num_;
private:
DISALLOW_COPY_AND_ASSIGN(ObMultiFixedQueue);
};
template <int MAX_QUEUE_NUM>
int ObMultiFixedQueue<MAX_QUEUE_NUM>::init(const int64_t queue_size, const int64_t queue_num)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
} else if (0 >= queue_size || 0 >= queue_num || queue_num > MAX_QUEUE_NUM) {
ret = OB_INVALID_ARGUMENT;
} else if (OB_SUCCESS != (ret = init_queue_(queue_num, queue_size))) {
LIB_LOG(ERROR, "err init queue", K(ret));
} else {
inited_ = true;
}
return ret;
}
template <int MAX_QUEUE_NUM>
int ObMultiFixedQueue<MAX_QUEUE_NUM>::destroy()
{
inited_ = false;
if (0 < queue_num_) {
destroy_queue_(queue_num_);
}
queue_num_ = 0;
return OB_SUCCESS;
}
template <int MAX_QUEUE_NUM>
int ObMultiFixedQueue<MAX_QUEUE_NUM>::init_queue_(const int64_t queue_num, const int64_t queue_size)
{
int ret = OB_SUCCESS;
if (!(0 < queue_num && MAX_QUEUE_NUM >= queue_num && 0 < queue_size)) {
ret = OB_INVALID_ARGUMENT;
LIB_LOG(ERROR, "invalid arguments", K(ret), K(queue_num), K(queue_size));
} else {
queue_num_ = queue_num;
}
for (int64_t index = 0; OB_SUCC(ret) && index < queue_num; index++) {
if (OB_SUCCESS != (ret = queue_[index].init(queue_size))) {
LIB_LOG(ERROR, "err init queue", K(ret));
}
}
return ret;
}
template <int MAX_QUEUE_NUM>
void ObMultiFixedQueue<MAX_QUEUE_NUM>::destroy_queue_(const int64_t queue_num)
{
if (0 < queue_num) {
for (int64_t index = 0; index < queue_num; index++) {
queue_[index].destroy();
}
}
}
template <int MAX_QUEUE_NUM>
int ObMultiFixedQueue<MAX_QUEUE_NUM>::push(void* data, const uint64_t hash_val, const int64_t timeout)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
} else if (NULL == data) {
ret = OB_INVALID_ARGUMENT;
} else {
int64_t index = hash_val % queue_num_;
ObCond& cond = queue_conds_[index];
int64_t end_time = timeout + ::oceanbase::common::ObTimeUtility::current_time();
while (true) {
ret = queue_[index].push(data);
if (OB_SIZE_OVERFLOW != ret) {
break;
}
int64_t left_time = end_time - ::oceanbase::common::ObTimeUtility::current_time();
if (left_time <= 0) {
ret = OB_TIMEOUT;
break;
}
cond.timedwait(left_time);
}
if (OB_SUCC(ret)) {
cond.signal();
}
}
return ret;
}
template <int MAX_QUEUE_NUM>
int ObMultiFixedQueue<MAX_QUEUE_NUM>::pop(void*& data, const int64_t queue_index, const int64_t timeout)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
} else if (0 > queue_index || queue_index >= MAX_QUEUE_NUM) {
ret = OB_INVALID_ARGUMENT;
} else {
ObCond& cond = queue_conds_[queue_index];
int64_t end_time = timeout + ::oceanbase::common::ObTimeUtility::current_time();
data = NULL;
while (true) {
ret = queue_[queue_index].pop(data);
if (OB_ENTRY_NOT_EXIST != ret) {
break;
}
int64_t left_time = end_time - ::oceanbase::common::ObTimeUtility::current_time();
if (left_time <= 0) {
ret = OB_TIMEOUT;
break;
}
cond.timedwait(left_time);
}
if (OB_SUCC(ret)) {
cond.signal();
}
}
return ret;
}
template <int MAX_QUEUE_NUM>
int ObMultiFixedQueue<MAX_QUEUE_NUM>::get_task_count(const int64_t queue_index, int64_t& task_count)
{
int ret = OB_SUCCESS;
task_count = 0;
if (OB_UNLIKELY(queue_index < 0) || OB_UNLIKELY(queue_index >= queue_num_)) {
LIB_LOG(ERROR, "invalid argument", K(queue_index), K(queue_num_));
ret = OB_INVALID_ARGUMENT;
} else {
task_count = queue_[queue_index].get_total();
}
return ret;
}
} // namespace common
} // namespace oceanbase
#endif /* OCEANBASE_LIB_QUEUE_M_FIXED_QUEUE_H_ */