@@ -8,12 +8,30 @@ use proptest::prelude::*;
88use rand:: distributions:: Distribution ;
99use rand:: SeedableRng ;
1010
11+ fn rotate_edges ( bookmark : & tskit:: types:: Bookmark , tables : & mut tskit:: TableCollection ) {
12+ let num_edges = tables. edges ( ) . num_rows ( ) . as_usize ( ) ;
13+ let left =
14+ unsafe { std:: slice:: from_raw_parts_mut ( ( * tables. as_mut_ptr ( ) ) . edges . left , num_edges) } ;
15+ let right =
16+ unsafe { std:: slice:: from_raw_parts_mut ( ( * tables. as_mut_ptr ( ) ) . edges . right , num_edges) } ;
17+ let parent =
18+ unsafe { std:: slice:: from_raw_parts_mut ( ( * tables. as_mut_ptr ( ) ) . edges . parent , num_edges) } ;
19+ let child =
20+ unsafe { std:: slice:: from_raw_parts_mut ( ( * tables. as_mut_ptr ( ) ) . edges . child , num_edges) } ;
21+ let mid = bookmark. edges ( ) . as_usize ( ) ;
22+ left. rotate_left ( mid) ;
23+ right. rotate_left ( mid) ;
24+ parent. rotate_left ( mid) ;
25+ child. rotate_left ( mid) ;
26+ }
27+
1128// ANCHOR: haploid_wright_fisher
1229fn simulate (
1330 seed : u64 ,
1431 popsize : usize ,
1532 num_generations : i32 ,
1633 simplify_interval : i32 ,
34+ update_bookmark : bool ,
1735) -> Result < tskit:: TreeSequence > {
1836 if popsize == 0 {
1937 return Err ( anyhow:: Error :: msg ( "popsize must be > 0" ) ) ;
@@ -46,6 +64,7 @@ fn simulate(
4664 let parent_picker = rand:: distributions:: Uniform :: new ( 0 , popsize) ;
4765 let breakpoint_generator = rand:: distributions:: Uniform :: new ( 0.0 , 1.0 ) ;
4866 let mut rng = rand:: rngs:: StdRng :: seed_from_u64 ( seed) ;
67+ let mut bookmark = tskit:: types:: Bookmark :: new ( ) ;
4968
5069 for birth_time in ( 0 ..num_generations) . rev ( ) {
5170 for c in children. iter_mut ( ) {
@@ -64,7 +83,10 @@ fn simulate(
6483 }
6584
6685 if birth_time % simplify_interval == 0 {
67- tables. full_sort ( tskit:: TableSortOptions :: default ( ) ) ?;
86+ tables. sort ( & bookmark, tskit:: TableSortOptions :: default ( ) ) ?;
87+ if update_bookmark {
88+ rotate_edges ( & bookmark, & mut tables) ;
89+ }
6890 if let Some ( idmap) =
6991 tables. simplify ( children, tskit:: SimplificationOptions :: default ( ) , true ) ?
7092 {
@@ -73,6 +95,9 @@ fn simulate(
7395 * o = idmap[ usize:: try_from ( * o) ?] ;
7496 }
7597 }
98+ if update_bookmark {
99+ bookmark. set_edges ( tables. edges ( ) . num_rows ( ) ) ;
100+ }
76101 }
77102 std:: mem:: swap ( & mut parents, & mut children) ;
78103 }
@@ -91,6 +116,8 @@ struct SimParams {
91116 num_generations : i32 ,
92117 simplify_interval : i32 ,
93118 treefile : Option < String > ,
119+ #[ clap( short, long, help = "Use bookmark to avoid sorting entire edge table." ) ]
120+ bookmark : bool ,
94121}
95122
96123fn main ( ) -> Result < ( ) > {
@@ -100,6 +127,7 @@ fn main() -> Result<()> {
100127 params. popsize ,
101128 params. num_generations ,
102129 params. simplify_interval ,
130+ params. bookmark ,
103131 ) ?;
104132
105133 if let Some ( treefile) = & params. treefile {
@@ -114,8 +142,9 @@ proptest! {
114142#[ test]
115143 fn test_simulate_proptest( seed in any:: <u64 >( ) ,
116144 num_generations in 50 ..100i32 ,
117- simplify_interval in 1 ..100i32 ) {
118- let ts = simulate( seed, 100 , num_generations, simplify_interval) . unwrap( ) ;
145+ simplify_interval in 1 ..100i32 ,
146+ bookmark in proptest:: bool :: ANY ) {
147+ let ts = simulate( seed, 100 , num_generations, simplify_interval, bookmark) . unwrap( ) ;
119148
120149 // stress test the branch length fn b/c it is not a trivial
121150 // wrapper around the C API.
0 commit comments