use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
pub type BranchId = u64;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum BranchStatus {
Active = 0,
Failed = 1,
Solved = 2,
}
impl BranchStatus {
pub fn from_u8(v: u8) -> Option<Self> {
match v {
0 => Some(Self::Active),
1 => Some(Self::Failed),
2 => Some(Self::Solved),
_ => None,
}
}
}
pub struct Branch {
id: BranchId,
parent_id: Option<BranchId>,
refcount: AtomicU32,
status: AtomicU32,
depth: u32,
jobs_completed: AtomicU64,
confidence: AtomicU64, }
impl Branch {
pub fn new_root() -> Self {
Self {
id: 0,
parent_id: None,
refcount: AtomicU32::new(0),
status: AtomicU32::new(BranchStatus::Active as u32),
depth: 0,
jobs_completed: AtomicU64::new(0),
confidence: AtomicU64::new(1.0f64.to_bits()),
}
}
pub fn new_child(id: BranchId, parent_id: BranchId, parent_depth: u32) -> Self {
Self {
id,
parent_id: Some(parent_id),
refcount: AtomicU32::new(0),
status: AtomicU32::new(BranchStatus::Active as u32),
depth: parent_depth + 1,
jobs_completed: AtomicU64::new(0),
confidence: AtomicU64::new(1.0f64.to_bits()),
}
}
pub fn id(&self) -> BranchId {
self.id
}
pub fn parent_id(&self) -> Option<BranchId> {
self.parent_id
}
pub fn depth(&self) -> u32 {
self.depth
}
pub fn status(&self) -> BranchStatus {
BranchStatus::from_u8(self.status.load(Ordering::Acquire) as u8)
.unwrap_or(BranchStatus::Active)
}
pub fn set_status(&self, status: BranchStatus) {
self.status.store(status as u32, Ordering::Release);
}
pub fn is_failed(&self) -> bool {
self.status() == BranchStatus::Failed
}
pub fn is_active(&self) -> bool {
self.status() == BranchStatus::Active
}
pub fn inc_refcount(&self) -> u32 {
self.refcount.fetch_add(1, Ordering::SeqCst) + 1
}
pub fn dec_refcount(&self) -> u32 {
self.refcount.fetch_sub(1, Ordering::SeqCst) - 1
}
pub fn refcount(&self) -> u32 {
self.refcount.load(Ordering::Acquire)
}
pub fn inc_jobs_completed(&self) -> u64 {
self.jobs_completed.fetch_add(1, Ordering::Relaxed) + 1
}
pub fn jobs_completed(&self) -> u64 {
self.jobs_completed.load(Ordering::Relaxed)
}
pub fn confidence(&self) -> f64 {
f64::from_bits(self.confidence.load(Ordering::Relaxed))
}
pub fn set_confidence(&self, confidence: f64) {
self.confidence
.store(confidence.to_bits(), Ordering::Relaxed);
}
}
impl Clone for Branch {
fn clone(&self) -> Self {
Self {
id: self.id,
parent_id: self.parent_id,
refcount: AtomicU32::new(self.refcount.load(Ordering::Relaxed)),
status: AtomicU32::new(self.status.load(Ordering::Relaxed)),
depth: self.depth,
jobs_completed: AtomicU64::new(self.jobs_completed.load(Ordering::Relaxed)),
confidence: AtomicU64::new(self.confidence.load(Ordering::Relaxed)),
}
}
}