/*
|
* =====================================================================================
|
*
|
* Filename: timed_queue.h
|
*
|
* Description:
|
*
|
* Version: 1.0
|
* Created: 2021年04月12日 09时36分04秒
|
* Revision: none
|
* Compiler: gcc
|
*
|
* Author: Li Chao (), lichao@aiotlink.com
|
* Organization:
|
*
|
* =====================================================================================
|
*/
|
#ifndef TIMED_QUEUE_Y2YLRBS3
|
#define TIMED_QUEUE_Y2YLRBS3
|
|
#include "bh_util.h"
|
#include <chrono>
|
#include <list>
|
#include <string>
|
|
template <class Data, class ClockType = std::chrono::steady_clock>
|
class TimedData
|
{
|
public:
|
typedef ClockType Clock;
|
typedef typename Clock::time_point TimePoint;
|
typedef typename Clock::duration Duration;
|
|
TimedData(const TimePoint &expire, const Data &data) :
|
expire_(expire), data_(data) {}
|
TimedData(const TimePoint &expire, Data &&data) :
|
expire_(expire), data_(std::move(data)) {}
|
bool Expired() const { return Clock::now() > expire_; }
|
const TimePoint &expire() const { return expire_; }
|
Data &data() { return data_; }
|
Data const &data() const { return data_; }
|
|
private:
|
TimePoint expire_;
|
Data data_;
|
};
|
|
template <class Data, class ClockType = std::chrono::steady_clock>
|
class TimedQueue
|
{
|
typedef TimedData<Data, ClockType> Record;
|
|
public:
|
typedef typename Record::Clock Clock;
|
typedef typename Record::TimePoint TimePoint;
|
typedef typename Record::Duration Duration;
|
|
private:
|
typedef std::list<Record> Queue;
|
Synced<Queue> queue_;
|
|
public:
|
void Push(Data &&data, const TimePoint &expire) { queue_->emplace_back(expire, std::move(data)); }
|
void Push(Data const &data, const TimePoint &expire) { queue_->emplace_back(expire, data); }
|
|
void Push(Data &&data, Duration const &timeout) { Push(std::move(data), Clock::now() + timeout); }
|
void Push(Data const &data, Duration const &timeout) { Push(data, Clock::now() + timeout); }
|
|
template <class Func>
|
void CheckAll(Func const &func)
|
{
|
queue_.Apply([&](Queue &q) {
|
if (q.empty()) {
|
return;
|
}
|
auto it = q.begin();
|
do {
|
if (it->Expired()) {
|
it = q.erase(it);
|
} else if (func(it->data())) {
|
it = q.erase(it);
|
} else {
|
++it;
|
}
|
} while (it != q.end());
|
});
|
}
|
};
|
|
#endif // end of include guard: TIMED_QUEUE_Y2YLRBS3
|