This commit is contained in:
2024-06-09 21:13:07 -04:00
parent 99d45b53c4
commit 24170816e1

View File

@@ -59,66 +59,75 @@ struct RoyaltyTree {
tree: Vec<Royalty>, tree: Vec<Royalty>,
} }
struct Royalty {
weight: FiNum, // Here and below
lazy: FiNum, // To be distributed to here and to below based on weights
acc: FiNum, // Accumulated here
}
impl Royalty {
fn new() -> Self {
Royalty { weight:FiNum::zero(), lazy:FiNum::zero(), acc:FiNum::zero() }
}
}
impl RoyaltyTree { impl RoyaltyTree {
fn new() -> Self { fn new() -> Self {
RoyaltyTree { tree:Vec::new() } RoyaltyTree { tree:Vec::new() }
} }
fn get_weight(&self, index:usize) -> FiNum { fn weight_here_below(&self, index:usize) -> FiNum {
println!("Get_weight {} self.tree.len() {} ",index,self.tree.len()); if index<self.tree.len() { self.tree[index].weight } else { FiNum::zero() }
if index<self.tree.len() { self.tree[index].weight } }
else { fn weight_below(&self, index:usize) -> FiNum {
let ff=wt_forefather(index); if index&1==0 {
let mut index=index; FiNum::zero()
while index!=ff { } else {
if index<self.tree.len() { return self.tree[index].weight } self.weight_here_below(wt_left (index).unwrap())+self.weight_here_below(wt_right(index).unwrap())
else { index=wt_parent(index) }
}
while index>=self.tree.len() { index=wt_left(index).unwrap() }
self.tree[index].weight
} }
} }
} fn weight_here(&self, index:usize) -> FiNum {
if index&1==0 {
struct Royalty { self.weight_here_below(index)
weight: FiNum, // Here and below } else {
acc: FiNum, // Here and Below self.weight_here_below(index)-self.weight_below(index)
} }
}
impl Royalty { fn expand_to(&mut self, index: usize) -> &mut Self {
fn new(weight: FiNum) -> Self { for _ in self.tree.len()..=index+1 { self.tree.push(Royalty::new()) }
Royalty { weight:weight, acc:FiNum::new(0u64) } self
} }
} fn capture0(&mut self, index: usize) -> &mut Self {
if index<self.tree.len() {
impl RoyaltyTree { if index&1==0 {
fn insert(&mut self, weight: FiNum, royalty:FiNum) -> usize { self.tree[index].acc+=self.tree[index].lazy;
let last=self.tree.len(); self.tree[index].lazy=FiNum::zero();
let mut nweight=weight; } else {
if let Some(left )=wt_left (last) { if left <self.tree.len() { nweight+=self.tree[left ].weight } } let lazy=self.tree[index].lazy;
if let Some(right)=wt_right(last) { if right<self.tree.len() { nweight+=self.tree[right].weight } } let d1=lazy*self.weight_here(index)/self.weight_here_below(index);
self.tree.push(Royalty::new(nweight)); let d02=lazy-d1;
let forefather=wt_forefather(last); let index_left =wt_left (index).unwrap();
let mut pivot=last; let index_right=wt_right(index).unwrap();
while pivot!=forefather { let d0=d02*self.weight_here_below(index_left)/self.weight_below(index);
pivot=wt_parent(pivot); let d2=d02-d0;
if pivot<self.tree.len() { self.tree[pivot].weight+=weight } assert!(lazy==d0+d1+d2,"Distributing amounts that don't add up.");
} self.expand_to(index_right);
self.tree[forefather].acc+=royalty; self.tree[index_left ].lazy+=d0;
last self.tree[index_right].lazy+=d2;
self.tree[index].acc+=d1;
self.tree[index].lazy=FiNum::zero();
}
}
self
} }
fn capture(&mut self, index:usize, weight: FiNum) -> FiNum { fn capture(&mut self, index: usize) -> &mut Self { // Clear out lazy by drilling from root to index
let ff=wt_forefather(index); let ff=wt_forefather(index);
let mut index=index; let mut index=index;
let mut rval=FiNum::zero(); while index!=ff {
loop { self.capture0(index);
let cap=self.tree[index].acc*weight/self.tree[index].weight; index=wt_parent(index);
self.tree[index].weight-=weight;
self.tree[index].acc-=cap;
rval+=cap;
if index!=ff { index=wt_parent(index); } else { break; }
} }
rval self
} }
fn dump(&self) { fn dump(&self) {
for index in 0..self.tree.len() { for index in 0..self.tree.len() {
println!("Index {} Weight {}",index,self.tree[index].weight); println!("Index {} Weight {}",index,self.tree[index].weight);