Skip to content

Commit be6ba3a

Browse files
committed
now using erease_if in scheduler where usable
more branch predictor hints
1 parent 744665b commit be6ba3a

5 files changed

Lines changed: 37 additions & 36 deletions

File tree

include/oryx/chron/scheduler.hpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Scheduler {
2525

2626
auto AddSchedule(std::string name, std::string_view cron_expr, TaskFn work) -> bool {
2727
auto task = MakeTask(std::move(name), cron_expr, std::move(work));
28-
if (!task) {
28+
if (!task) [[unlikely]] {
2929
return false;
3030
}
3131

@@ -36,18 +36,20 @@ class Scheduler {
3636
}
3737

3838
template <typename F>
39-
auto AddScheduleBatch(F&& fn, std::optional<size_t> num_tasks = std::nullopt) -> bool {
39+
auto AddScheduleBatch(F&& fn, std::optional<std::size_t> num_tasks = {}) -> bool {
4040
std::vector<Task> tasks;
4141
if (num_tasks) tasks.reserve(num_tasks.value());
4242
auto add_schedule = [this, &tasks](std::string name, std::string_view cron_expr, TaskFn work) -> bool {
4343
auto task = MakeTask(std::move(name), cron_expr, work);
44-
if (!task) return false;
44+
if (!task) [[unlikely]] {
45+
return false;
46+
}
4547
tasks.emplace_back(std::move(task.value()));
4648
return true;
4749
};
4850

4951
std::invoke(fn, std::move(add_schedule));
50-
if (tasks.empty()) {
52+
if (tasks.empty()) [[unlikely]] {
5153
return false;
5254
}
5355

@@ -63,23 +65,19 @@ class Scheduler {
6365
tasks_.clear();
6466
}
6567

66-
void RemoveSchedule(const std::string& name) {
68+
void RemoveSchedule(std::string_view name) {
6769
std::lock_guard lock{tasks_mtx_};
68-
auto it = std::ranges::find_if(tasks_, [&name](const Task& to_compare) { return name == to_compare; });
69-
if (it != tasks_.end()) {
70-
tasks_.erase(it);
71-
}
70+
std::erase_if(tasks_, [name](const Task& t) { return t == name; });
7271
}
7372

7473
void RecalculateSchedules() {
7574
std::lock_guard lock{tasks_mtx_};
7675
for (auto& task : tasks_) task.CalculateNext(clock_.Now() + std::chrono::seconds(1));
7776
}
7877

79-
auto Tick(TimePoint now) -> size_t {
78+
auto Tick(TimePoint now) -> std::size_t {
8079
std::lock_guard lock{tasks_mtx_};
8180

82-
size_t executed_count{};
8381
if (!first_tick_) [[likely]] {
8482
auto diff = now - last_tick_;
8583

@@ -96,21 +94,19 @@ class Scheduler {
9694

9795
last_tick_ = now;
9896
if (tasks_.empty()) {
99-
return executed_count;
97+
return 0;
10098
}
10199

102-
for (auto& task : tasks_) {
103-
if (task.IsExpired(now)) {
104-
task.Execute(now);
105-
if (!task.CalculateNext(now + std::chrono::seconds(1))) {
106-
auto it = std::ranges::find_if(tasks_, [&task](const Task& t) { return task.GetName() == t; });
107-
if (it != tasks_.end()) {
108-
tasks_.erase(it);
109-
}
110-
}
111-
++executed_count;
100+
std::size_t executed_count{};
101+
std::erase_if(tasks_, [&executed_count, now](Task& task) {
102+
if (!task.IsExpired(now)) {
103+
return false;
112104
}
113-
}
105+
106+
task.Execute(now);
107+
executed_count++;
108+
return !task.CalculateNext(now + std::chrono::seconds(1));
109+
});
114110

115111
if (executed_count > 0) {
116112
UnsafeSortTasks();
@@ -119,19 +115,23 @@ class Scheduler {
119115
return executed_count;
120116
}
121117

122-
auto Tick() -> size_t { return Tick(clock_.Now()); }
118+
auto Tick() -> std::size_t { return Tick(clock_.Now()); }
123119

124120
auto TimeUntilNext() const -> Duration {
125121
std::lock_guard lock{tasks_mtx_};
126122
if (tasks_.empty()) {
127-
return std::chrono::minutes::max();
123+
return Duration::max();
128124
}
129125
return tasks_[0].TimeUntilExpiry(clock_.Now());
130126
}
131127

132128
auto GetClock() -> ClockType& { return clock_; }
133129
auto GetParser() -> ParserType& { return parser_; }
134-
auto GetNumTasks() const -> size_t { return tasks_.size(); }
130+
131+
auto GetNumTasks() const -> std::size_t {
132+
std::lock_guard lock{tasks_mtx_};
133+
return tasks_.size();
134+
}
135135

136136
auto GetTasksStatus() const -> std::vector<std::string> {
137137
std::vector<std::string> status{};
@@ -148,12 +148,12 @@ class Scheduler {
148148
private:
149149
auto MakeTask(std::string name, std::string_view cron_expr, TaskFn work) const -> std::optional<Task> {
150150
auto data = parser_(cron_expr);
151-
if (!data) {
151+
if (!data) [[unlikely]] {
152152
return std::nullopt;
153153
}
154154

155155
Task task(std::move(name), Schedule(std::move(data.value())), std::move(work));
156-
if (!task.CalculateNext(clock_.Now())) {
156+
if (!task.CalculateNext(clock_.Now())) [[unlikely]] {
157157
return std::nullopt;
158158
}
159159
return task;

include/oryx/chron/task.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ class Task {
1919
public:
2020
Task(std::string name, Schedule schedule, TaskFn task);
2121

22-
auto operator=(const Task &) -> Task & = default;
2322
auto operator>(const Task &other) const -> bool { return next_schedule_ > other.next_schedule_; }
2423
auto operator<(const Task &other) const -> bool { return next_schedule_ < other.next_schedule_; }
2524

src/parser.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ auto ExpressionParser::operator()(std::string_view cron_expression) const -> std
2222

2323
if (!cron_expression.empty() && cron_expression[0] == '@') {
2424
auto it = std::ranges::find(kShortcuts, cron_expression, &DollarExprPair::expr);
25-
if (it != kShortcuts.end()) {
25+
if (it != kShortcuts.end()) [[likely]] {
2626
cron_expression = it->cron;
2727
}
2828
}
2929

3030
bool valid{};
3131
ChronData data{};
32-
if (auto match = ctre::match<R"#(^\s*(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s*$)#">(cron_expression)) {
32+
if (auto match = ctre::match<R"#(^\s*(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s*$)#">(cron_expression))
33+
[[likely]] {
3334
valid = details::Parser::ValidateNumeric<Seconds>(match.get<1>().to_view(), data.seconds);
3435
valid &= details::Parser::ValidateNumeric<Minutes>(match.get<2>().to_view(), data.minutes);
3536
valid &= details::Parser::ValidateNumeric<Hours>(match.get<3>().to_view(), data.hours);
@@ -41,7 +42,7 @@ auto ExpressionParser::operator()(std::string_view cron_expression) const -> std
4142
valid &= details::Parser::ValidateDateVsMonths(data);
4243
}
4344

44-
if (!valid) {
45+
if (!valid) [[unlikely]] {
4546
return std::nullopt;
4647
}
4748
return data;

src/randomization.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,9 @@ auto Randomization::Parse(std::string_view cron_schedule) -> std::optional<std::
129129
std::set<Months> month_range{};
130130
if (selected_value == kSelectedValueNone) {
131131
// Month is not specific, get the range.
132-
bool success = details::Parser::ConvertFromStringRangeToNumberRange(match.get<5>().to_view(), month_range);
133-
if (!success) return std::nullopt;
132+
if (!details::Parser::ConvertFromStringRangeToNumberRange(match.get<5>().to_view(), month_range)) [[unlikely]] {
133+
return std::nullopt;
134+
}
134135
} else {
135136
month_range.emplace(static_cast<Months>(selected_value));
136137
}

src/task.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ auto Task::IsExpired(TimePoint now) const -> bool { return valid_ && now >= last
5252
auto Task::GetStatus(TimePoint now) const -> std::string {
5353
auto dt = Schedule::ToCalendarTime(next_schedule_);
5454
auto expires_in = duration_cast<milliseconds>(TimeUntilExpiry(now));
55-
return std::format("'{}' expires in => {}-{}-{} {}:{}:{}", GetName(), expires_in, dt.year, dt.month, dt.day,
56-
dt.hour, dt.min, dt.sec);
55+
return std::format("'{}' expires in => {}-{}-{} {}:{}:{}", name_, expires_in, dt.year, dt.month, dt.day, dt.hour,
56+
dt.min, dt.sec);
5757
}
5858
} // namespace oryx::chron

0 commit comments

Comments
 (0)