Basic timer implementation; TODO: implement timer wheel
This commit is contained in:
parent
4bf5636d24
commit
b794187027
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@ memgraph
|
||||
*.pyc
|
||||
*.breakpoint
|
||||
*.session.yaml
|
||||
tags
|
||||
|
@ -3,9 +3,9 @@
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "utils/string/file.hpp"
|
||||
|
||||
std::string extract_query(const vector_str& arguments)
|
||||
std::string extract_query(const std::vector<std::string>& arguments)
|
||||
{
|
||||
if (contain_argument(arguments, "-q"))
|
||||
if (contains_argument(arguments, "-q"))
|
||||
return get_argument(arguments, "-q", "CREATE (n) RETURN n");
|
||||
auto default_file = "query.cypher";
|
||||
auto file = get_argument(arguments, "-f", default_file);
|
||||
|
29
test/unit/timer/main.cpp
Normal file
29
test/unit/timer/main.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
// #define NOT_LOG_INFO
|
||||
// compile this with: c++ -std=c++1y -o a.out -I../../../ -pthread main.cpp
|
||||
|
||||
#include "utils/log/logger.hpp"
|
||||
#include "utils/timer/timer.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
Timer::sptr create_test_timer(int64_t counter)
|
||||
{
|
||||
return std::make_shared<Timer>(
|
||||
counter, [](){ LOG_INFO("Timer timeout"); }
|
||||
);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
TimerScheduler<TimerSet, std::chrono::seconds> timer_scheduler;
|
||||
timer_scheduler.run();
|
||||
for (int64_t i = 1; i <= 3; ++i) {
|
||||
timer_scheduler.add(create_test_timer(i));
|
||||
}
|
||||
std::this_thread::sleep_for(10s);
|
||||
timer_scheduler.add(create_test_timer(1));
|
||||
return 0;
|
||||
}
|
131
utils/timer/timer.hpp
Normal file
131
utils/timer/timer.hpp
Normal file
@ -0,0 +1,131 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "utils/log/logger.hpp"
|
||||
|
||||
/** @class Timer
|
||||
* @brief The timer contains counter and handler.
|
||||
*
|
||||
* With every clock interval the counter should be decresed for
|
||||
* delta count. Delta count is one for now but it should be a variable in the
|
||||
* near future. The handler is function that will be called when counter
|
||||
* becomes zero or smaller than zero.
|
||||
*/
|
||||
struct Timer
|
||||
{
|
||||
using sptr = std::shared_ptr<Timer>;
|
||||
using handler_t = std::function<void(void)>;
|
||||
|
||||
Timer(int64_t counter, handler_t handler):
|
||||
counter(counter), handler(handler)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator--()
|
||||
{
|
||||
if (--counter <= 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t counter;
|
||||
handler_t handler;
|
||||
};
|
||||
|
||||
/**
|
||||
* Timer container knows how to add a new timer and remove the
|
||||
* existing container from itself. Also, time container object
|
||||
* has the process method whose responsibility is to iterate
|
||||
* over existing timers and call the appropriate handler function.
|
||||
* The handler method could be called on the same thread, on a
|
||||
* separate thread or on a thread pool, that is implementation detail of
|
||||
* the process method.
|
||||
*/
|
||||
|
||||
/** @class TimerSet
|
||||
* @brief Trivial timer container implementation.
|
||||
*
|
||||
* Internal data stucture for storage of timers is std::set. So, the
|
||||
* related timer complexities are:
|
||||
* insertion: O(log(n))
|
||||
* deletion: O(log(n))
|
||||
* process: O(n)
|
||||
*/
|
||||
class TimerSet
|
||||
{
|
||||
public:
|
||||
void add(Timer::sptr timer)
|
||||
{
|
||||
timers.insert(timer);
|
||||
}
|
||||
|
||||
void remove(Timer::sptr timer)
|
||||
{
|
||||
timers.erase(timer);
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
for (auto it = timers.begin(); it != timers.end(); ) {
|
||||
auto timer = *it;
|
||||
if (--*timer) {
|
||||
timer->handler();
|
||||
it = timers.erase(it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::shared_ptr<Timer>> timers;
|
||||
};
|
||||
|
||||
/** @class TimerScheduler
|
||||
* @brief TimerScheduler is a manager class and its responsibility is to
|
||||
* take care of the time and call the timer_container process method in the
|
||||
* appropriate time.
|
||||
*/
|
||||
template <
|
||||
typename timer_container_type,
|
||||
typename delta_time_type,
|
||||
uint64_t delta_time = 1
|
||||
> class TimerScheduler
|
||||
{
|
||||
public:
|
||||
void add(Timer::sptr timer)
|
||||
{
|
||||
timer_container.add(timer);
|
||||
}
|
||||
|
||||
void remove(Timer::sptr timer)
|
||||
{
|
||||
timer_container.remove(timer);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
run_thread = std::thread([this]() {
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(delta_time_type(delta_time));
|
||||
timer_container.process();
|
||||
LOG_INFO("timer_container.process()");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
~TimerScheduler()
|
||||
{
|
||||
run_thread.join();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
timer_container_type timer_container;
|
||||
std::thread run_thread;
|
||||
};
|
Loading…
Reference in New Issue
Block a user