Add custom errors with thiserror, log thread id
This commit is contained in:
@@ -2,6 +2,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use crate::{
|
||||
config::UserConfig,
|
||||
errors::SearchError,
|
||||
resident::ResidentId,
|
||||
schedule::MonthlySchedule,
|
||||
slot::Slot,
|
||||
@@ -9,10 +10,12 @@ use crate::{
|
||||
workload::{WorkloadBounds, WorkloadTracker},
|
||||
};
|
||||
|
||||
use anyhow::bail;
|
||||
use log::warn;
|
||||
use log::info;
|
||||
use rand::Rng;
|
||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||
use rayon::{
|
||||
current_thread_index,
|
||||
iter::{IntoParallelRefIterator, ParallelIterator},
|
||||
};
|
||||
|
||||
pub struct Scheduler {
|
||||
pub config: UserConfig,
|
||||
@@ -43,7 +46,7 @@ impl Scheduler {
|
||||
&self,
|
||||
schedule: &mut MonthlySchedule,
|
||||
tracker: &mut WorkloadTracker,
|
||||
) -> anyhow::Result<bool> {
|
||||
) -> Result<bool, SearchError> {
|
||||
schedule.prefill(&self.config);
|
||||
for (slot, res_id) in schedule.0.iter() {
|
||||
tracker.insert(*res_id, &self.config, *slot);
|
||||
@@ -55,7 +58,7 @@ impl Scheduler {
|
||||
let slot = (0..=self.config.total_slots)
|
||||
.find(|&slot_idx| !schedule.0.contains_key(&Slot::from(slot_idx)))
|
||||
.map(Slot::from)
|
||||
.ok_or_else(|| anyhow::anyhow!("Schedule is already full"))?;
|
||||
.ok_or(SearchError::ScheduleFull)?;
|
||||
|
||||
let resident_ids = self.valid_residents(slot, schedule);
|
||||
let solved_in_thread = AtomicBool::new(false);
|
||||
@@ -78,7 +81,7 @@ impl Scheduler {
|
||||
Ok(true) => Some((local_schedule, local_tracker)),
|
||||
Ok(false) => None,
|
||||
Err(e) => {
|
||||
warn!("Search error: {}", e);
|
||||
info!("Thread Id: [{}] {}", current_thread_index().unwrap(), e);
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -102,13 +105,13 @@ impl Scheduler {
|
||||
tracker: &mut WorkloadTracker,
|
||||
slot: Slot,
|
||||
solved_in_thread: &AtomicBool,
|
||||
) -> anyhow::Result<bool> {
|
||||
) -> Result<bool, SearchError> {
|
||||
if solved_in_thread.load(Ordering::Relaxed) {
|
||||
bail!("Another thread found the solution")
|
||||
return Err(SearchError::SolutionFound);
|
||||
}
|
||||
|
||||
if self.timer.limit_exceeded() {
|
||||
bail!("Time exceeded. Restrictions too tight");
|
||||
return Err(SearchError::Timeout);
|
||||
}
|
||||
|
||||
if !slot.is_first()
|
||||
@@ -132,10 +135,10 @@ impl Scheduler {
|
||||
// sort candidates by current workload, add rng for tie breakers
|
||||
let mut valid_resident_ids = self.valid_residents(slot, schedule);
|
||||
valid_resident_ids.sort_unstable_by_key(|res_id| {
|
||||
let type_count = tracker.get_type_count(res_id, slot.shift_type());
|
||||
let workload = tracker.current_workload(res_id);
|
||||
let tie_breaker: f64 = rand::rng().random();
|
||||
(type_count, workload, (tie_breaker * 1000.0) as usize)
|
||||
let type_count = tracker.get_type_count(res_id, slot.shift_type());
|
||||
let workload = tracker.current_workload(res_id);
|
||||
let tie_breaker: f64 = rand::rng().random();
|
||||
(type_count, workload, (tie_breaker * 1000.0) as usize)
|
||||
});
|
||||
|
||||
for id in valid_resident_ids {
|
||||
|
||||
Reference in New Issue
Block a user