diff --git a/src/main.rs b/src/main.rs index cd77424..22b848a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -123,6 +123,7 @@ struct RoyaltyTree { } struct Royalty { + count: usize, // Here and below weight: FiNum, // Here and below lazy: FiNum, // To be distributed to here and to below based on weights acc: FiNum, // Accumulated here @@ -131,7 +132,7 @@ struct Royalty { impl Royalty { fn new() -> Self { - Royalty { weight:FiNum::zero(), lazy:FiNum::zero(), acc:FiNum::zero(), order_id:0, } + Royalty { weight:FiNum::zero(), lazy:FiNum::zero(), acc:FiNum::zero(), order_id:0, count:0 } } } @@ -147,6 +148,9 @@ impl RoyaltyTree { fn weight_here_below(&self, index:usize) -> FiNum { self.tree[index].weight } + fn count_here_below(&self, index:usize) -> usize { + self.tree[index].count + } fn weight_below(&self, index: usize) -> FiNum { if index&1==0 { FiNum::zero() @@ -156,6 +160,15 @@ impl RoyaltyTree { w0+w1 } } + fn count_below(&self, index: usize) -> usize { + if index&1==0 { + 0 + } else { + let c0=self.count_here_below(wt_left (index).unwrap()); + let c1=self.count_here_below(wt_right(index).unwrap()); + c0+c1 + } + } fn weight_here(&self, index:usize) -> FiNum { if index&1==0 { self.weight_here_below(index) @@ -165,6 +178,16 @@ impl RoyaltyTree { w0-w1 } } + fn count_here(&self, index:usize) -> usize { + if index&1==0 { + self.count_here_below(index) + } else { + let c0=self.count_here_below(index); + let c1=self.count_below(index); + if c1>c0 { println!("Count_here({}) ... c0={} c1={}",index,c0,c1) }; + c0-c1 + } + } fn expand_to(&mut self, index: usize) -> &mut Self { for _ in self.tree.len()..=index { self.tree.push(Royalty::new()) } self @@ -223,6 +246,24 @@ impl RoyaltyTree { let weight=self.weight_here(pos); self.sub_weight(pos,weight); } + fn random_order_id(&self, rng: &mut rand::rngs::StdRng) -> Option { + if self.tree.len()==0 { return None } + let mut f=self.forefather(); + while self.count_here_below(f)>0 { + let c0=self.count_here(f); + let c1=if f&1==0 { 0 } else { self.count_here_below(wt_left(f).unwrap()) }; + let c2=if f&1==0 { 0 } else { self.count_here_below(wt_right(f).unwrap()) }; + let c=c0+c1+c2; + let r=rng.gen_range(0..c); + if r FiNum { + FiNum::zero() + } fn sub_weight(&mut self, index: usize, weight: FiNum) { self.get_royalty(index); let redist=self.tree[index].acc; @@ -240,10 +281,12 @@ impl RoyaltyTree { let mut ff0=self.forefather(); let ff1=wt_forefather(index); let w=self.tree[ff0].weight; + let c=self.tree[ff0].count; self.expand_to(ff1*2); while ff0FiNum::zero() { self.tree[index].count+=1; } self.tree[index].weight+=weight; index=wt_parent(index); } + if self.tree[index].weight==FiNum::zero() && weight>FiNum::zero() { self.tree[index].count+=1; } self.tree[index].weight+=weight; } fn forefather(&self) -> usize { @@ -262,7 +307,7 @@ impl RoyaltyTree { fn dump(&mut self) { for index in 0..self.tree.len() { let roy=self.get_royalty(index); - println!("Index {} Weight {} Lazy {} Acc {} Royalty {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc,roy); + println!("Index {} Count {} Weight {} Lazy {} Acc {} Royalty {}",index,self.tree[index].count,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc,roy); } } fn raw_dump(&mut self) { @@ -749,11 +794,16 @@ fn wt_forefather(max_index:usize) -> usize { fn royalty_stuff() { let mut rng: StdRng=StdRng::seed_from_u64(13u64); let mut rt=RoyaltyTree::new(); - for i in 1..1000 { + rt.add_weight(4,FiNum::new_i32(1)); + rt.add_weight(5,FiNum::new_i32(1)); + rt.dump(); + return; + for i in 1..1000000 { + rt.dump(); match rng.gen_range(0..10) { - 0 => rt.add_weight(rng.gen_range(0..32),FiNum::new(rng.gen_range(0..101))), - 1 => rt.add_royalty(FiNum::new(rng.gen_range(0..10))), - 2 => rt.sub_royalty(FiNum::new(rng.gen_range(0..10))), + 0 => rt.add_weight(rng.gen_range(0..8),FiNum::new_i32(rng.gen_range(0..101))), + 1 => rt.add_royalty(FiNum::new_i32(rng.gen_range(0..10))), + 2 => println!("Random Order ID: {:?}",rt.random_order_id(&mut rng)), _ => (), } }