@@ -8,12 +8,30 @@ use proptest::prelude::*;
8
8
use rand:: distributions:: Distribution ;
9
9
use rand:: SeedableRng ;
10
10
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
+
11
28
// ANCHOR: haploid_wright_fisher
12
29
fn simulate (
13
30
seed : u64 ,
14
31
popsize : usize ,
15
32
num_generations : i32 ,
16
33
simplify_interval : i32 ,
34
+ update_bookmark : bool ,
17
35
) -> Result < tskit:: TreeSequence > {
18
36
if popsize == 0 {
19
37
return Err ( anyhow:: Error :: msg ( "popsize must be > 0" ) ) ;
@@ -46,6 +64,7 @@ fn simulate(
46
64
let parent_picker = rand:: distributions:: Uniform :: new ( 0 , popsize) ;
47
65
let breakpoint_generator = rand:: distributions:: Uniform :: new ( 0.0 , 1.0 ) ;
48
66
let mut rng = rand:: rngs:: StdRng :: seed_from_u64 ( seed) ;
67
+ let mut bookmark = tskit:: types:: Bookmark :: new ( ) ;
49
68
50
69
for birth_time in ( 0 ..num_generations) . rev ( ) {
51
70
for c in children. iter_mut ( ) {
@@ -64,7 +83,10 @@ fn simulate(
64
83
}
65
84
66
85
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
+ }
68
90
if let Some ( idmap) =
69
91
tables. simplify ( children, tskit:: SimplificationOptions :: default ( ) , true ) ?
70
92
{
@@ -73,6 +95,9 @@ fn simulate(
73
95
* o = idmap[ usize:: try_from ( * o) ?] ;
74
96
}
75
97
}
98
+ if update_bookmark {
99
+ bookmark. set_edges ( tables. edges ( ) . num_rows ( ) ) ;
100
+ }
76
101
}
77
102
std:: mem:: swap ( & mut parents, & mut children) ;
78
103
}
@@ -91,6 +116,8 @@ struct SimParams {
91
116
num_generations : i32 ,
92
117
simplify_interval : i32 ,
93
118
treefile : Option < String > ,
119
+ #[ clap( short, long, help = "Use bookmark to avoid sorting entire edge table." ) ]
120
+ bookmark : bool ,
94
121
}
95
122
96
123
fn main ( ) -> Result < ( ) > {
@@ -100,6 +127,7 @@ fn main() -> Result<()> {
100
127
params. popsize ,
101
128
params. num_generations ,
102
129
params. simplify_interval ,
130
+ params. bookmark ,
103
131
) ?;
104
132
105
133
if let Some ( treefile) = & params. treefile {
@@ -114,8 +142,9 @@ proptest! {
114
142
#[ test]
115
143
fn test_simulate_proptest( seed in any:: <u64 >( ) ,
116
144
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( ) ;
119
148
120
149
// stress test the branch length fn b/c it is not a trivial
121
150
// wrapper around the C API.
0 commit comments