Files
oceanbase/deps/oblib/src/lib/queue/ob_lighty_queue.h
2024-03-06 07:15:08 +00:00

115 lines
3.5 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.
*/
#ifndef OB_COMMON_OB_LIGHTY_QUEUE_
#define OB_COMMON_OB_LIGHTY_QUEUE_
#include <stdint.h>
#include <stddef.h>
#include "lib/alloc/alloc_struct.h"
#include "lib/allocator/ob_mod_define.h"
#include "lib/lock/ob_futex.h"
#include "lib/queue/ob_fixed_queue.h"
namespace oceanbase
{
namespace common
{
struct ObLightyCond
{
public:
ObLightyCond(): n_waiters_(0) {}
~ObLightyCond() {}
void signal();
uint32_t get_seq() { return ATOMIC_LOAD(&futex_.uval()); }
void wait(const uint32_t cmp, const int64_t timeout);
private:
lib::ObFutex futex_;
uint32_t n_waiters_;
private:
DISALLOW_COPY_AND_ASSIGN(ObLightyCond);
};
class ObLightyQueue
{
public:
typedef ObLightyCond Cond;
ObLightyQueue(): capacity_(0), n_cond_(0), data_(NULL), cond_(NULL), push_(0), pop_(0) {}
~ObLightyQueue() { destroy(); }
int init(const uint64_t capacity,
const lib::ObLabel &label = ObModIds::OB_LIGHTY_QUEUE,
const uint64_t tenant_id = common::OB_SERVER_TENANT_ID);
void destroy();
void reset() { clear(); }
void clear();
int64_t size() const { return (int64_t)(ATOMIC_LOAD(&push_) - ATOMIC_LOAD(&pop_)); }
int64_t capacity() const { return capacity_; }
bool is_inited() const { return NULL != data_; }
int push(void* p);
int pop(void*& p, int64_t timeout = 0);
private:
static uint64_t calc_n_cond(uint64_t capacity)
{
OB_ASSERT(0ULL != capacity);
return std::min(1024ULL, 1ULL<<(63 - __builtin_clzll(capacity)));
}
uint64_t push_bounded(void* p, uint64_t limit);
uint64_t wait_push(uint64_t seq, int64_t timeout);
static int64_t get_us();
uint64_t idx(uint64_t x) { return x % capacity_; }
Cond& get_cond(uint64_t seq) { return cond_[seq % n_cond_]; }
static uint64_t inc_if_lt(uint64_t *addr, uint64_t *limit_addr, uint64_t delta, uint64_t &limit);
static uint64_t inc_if_lt(uint64_t* addr, uint64_t b);
void* fetch(uint64_t seq);
void store(uint64_t seq, void* p);
private:
uint64_t capacity_;
uint64_t n_cond_;
void** data_;
Cond* cond_;
uint64_t push_ CACHE_ALIGNED;
uint64_t pop_ CACHE_ALIGNED;
};
class LightyQueue
{
public:
typedef ObLightyCond Cond;
LightyQueue() {}
~LightyQueue() { destroy(); }
public:
int init(const uint64_t capacity,
const lib::ObLabel &label = ObModIds::OB_LIGHTY_QUEUE,
const uint64_t tenant_id = common::OB_SERVER_TENANT_ID);
void destroy() { queue_.destroy(); }
void reset();
int64_t size() const { return queue_.get_total(); }
int64_t curr_size() const { return queue_.get_total(); }
int64_t max_size() const { return queue_.capacity(); }
bool is_inited() const { return queue_.is_inited(); }
int push(void *data, const int64_t timeout = 0);
int pop(void *&data, const int64_t timeout = 0);
int multi_pop(void **data, const int64_t data_count, int64_t &avail_count, const int64_t timeout = 0);
private:
typedef ObOrderedFixedQueue<void> Queue;
Queue queue_;
Cond cond_;
private:
DISALLOW_COPY_AND_ASSIGN(LightyQueue);
};
}; // end namespace common
}; // end namespace oceanbase
#endif /* __OB_COMMON_OB_LIGHTY_QUEUE_H__ */