pub struct Branch {
counts: u16,
}
impl Default for Branch {
fn default() -> Branch {
Branch::new()
}
}
const fn problookup() -> [u8; 65536] {
let mut retval = [0; 65536];
let mut i = 1i32;
while i < 65536 {
let a = i >> 8;
let b = i & 0xff;
retval[i as usize] = ((a << 8) / (a + b)) as u8;
i += 1;
}
return retval;
}
static PROB_LOOKUP: [u8; 65536] = problookup();
impl Branch {
pub fn new() -> Self {
Branch { counts: 0x0101 }
}
#[allow(dead_code)]
pub fn get_u64(&self) -> u64 {
let mut c = self.counts;
if c == 0 {
c = 0x01ff;
}
return ((PROB_LOOKUP[self.counts as usize] as u64) << 16) + c as u64;
}
#[inline(always)]
pub fn get_probability(&self) -> u8 {
PROB_LOOKUP[self.counts as usize]
}
#[inline(always)]
pub fn record_and_update_true_obs(&mut self) {
if self.counts == 0 {
return; }
if (self.counts & 0xff) != 0xff {
self.counts += 1;
} else {
if self.counts == 0x01ff {
self.counts = 0;
} else {
self.counts = (((self.counts as u32 + 0x100) >> 1) & 0xff00) as u16 | 129;
}
}
}
#[inline(always)]
pub fn record_and_update_false_obs(&mut self) {
if self.counts == 0 {
self.counts = 0x02ff;
return;
}
if (self.counts & 0xff00) != 0xff00 {
self.counts += 0x100;
} else {
if self.counts == 0xff01 {
} else {
self.counts = ((1 + (self.counts & 0xff) as u32) >> 1) as u16 | 0x8100;
}
}
}
}