@@ -7,8 +7,10 @@ pub enum Step {
7
7
size : usize ,
8
8
} ,
9
9
Realistic {
10
- /// Like `Partitioned::size, and used to have big steps until the last partition which is then single-steped entirely.
11
- partitions : usize ,
10
+ /// Like `Partitioned::size, and used to have big steps until `ordered_partitions` are executed.
11
+ unordered_partitions : usize ,
12
+ /// The amount of partitions to use for obtaining ordered changes
13
+ ordered_partitions : usize ,
12
14
} ,
13
15
}
14
16
@@ -41,37 +43,64 @@ pub fn baseline(mode: Step) -> Result<(), Box<dyn std::error::Error + Send + Syn
41
43
. map ( |id| id. map ( |id| id. detach ( ) ) )
42
44
. collect :: < Result < Vec < _ > , _ > > ( ) ?;
43
45
44
- // This could be more complex, like jumping to landmarks like 'Delete crate(s)' and so forth.
45
- let ( partitions, last_partition_is_single_step) = match mode {
46
- Step :: Partitioned { size } => ( size, false ) ,
47
- Step :: Realistic { partitions } => ( partitions, true ) ,
46
+ enum Kind {
47
+ Unordered ,
48
+ Ordered ,
49
+ }
50
+ let ( mut unordered_partitions, mut ordered_partitions) = match mode {
51
+ Step :: Partitioned { size } => ( size, 0 ) ,
52
+ Step :: Realistic {
53
+ unordered_partitions,
54
+ ordered_partitions,
55
+ } => ( unordered_partitions, ordered_partitions) ,
48
56
} ;
49
- let chunk_size = ( commits. len ( ) / partitions) . max ( 1 ) ;
50
- let mut steps = if last_partition_is_single_step && chunk_size > 1 {
51
- let mut steps: Vec < _ > = ( 0 ..chunk_size) . collect ( ) ;
52
- steps. extend ( ( chunk_size..commits. len ( ) ) . step_by ( chunk_size) ) ;
53
- steps
54
- } else {
55
- ( 0 ..commits. len ( ) ) . step_by ( chunk_size) . collect :: < Vec < _ > > ( )
57
+ let chunk_size =
58
+ ( commits. len ( ) / ( unordered_partitions + ordered_partitions) ) . max ( 1 ) ;
59
+ let mut new_kind = || {
60
+ if unordered_partitions > 0 {
61
+ unordered_partitions -= 1 ;
62
+ Kind :: Unordered
63
+ } else if ordered_partitions > 0 {
64
+ ordered_partitions -= 1 ;
65
+ Kind :: Ordered
66
+ } else {
67
+ Kind :: Unordered
68
+ }
56
69
} ;
57
- if * steps. last ( ) . expect ( "at least 1" ) != commits. len ( ) - 1 {
58
- steps. push ( commits. len ( ) - 1 ) ;
70
+ let mut steps = ( 0 ..commits. len ( ) )
71
+ . step_by ( chunk_size)
72
+ . map ( |s| ( s, new_kind ( ) ) )
73
+ . collect :: < Vec < _ > > ( ) ;
74
+ if steps. last ( ) . expect ( "at least 1" ) . 0 != commits. len ( ) - 1 {
75
+ steps. push ( ( commits. len ( ) - 1 , new_kind ( ) ) ) ;
59
76
}
60
77
let mut versions = HashMap :: default ( ) ;
61
78
let mut previous = None ;
62
79
let num_steps = steps. len ( ) ;
63
- for ( step, current) in steps
80
+ for ( step, ( current, kind ) ) in steps
64
81
. into_iter ( )
65
82
. rev ( )
66
- . map ( |idx| commits[ idx] . to_owned ( ) )
83
+ . map ( |( idx, kind ) | ( commits[ idx] . to_owned ( ) , kind ) )
67
84
. enumerate ( )
68
85
{
69
86
let old = previous
70
87
. unwrap_or_else ( || git:: hash:: ObjectId :: empty_tree ( git:: hash:: Kind :: Sha1 ) ) ;
71
88
previous = Some ( current) ;
72
89
73
90
let start = std:: time:: Instant :: now ( ) ;
74
- let changes = index. changes_between_commits ( old, current) ?;
91
+ let changes = match kind {
92
+ Kind :: Unordered => index. changes_between_commits ( old, current) ?,
93
+ Kind :: Ordered => {
94
+ let ( changes, actual_order) =
95
+ index. changes_between_ancestor_commits ( old, current) ?;
96
+ assert_eq ! (
97
+ actual_order,
98
+ crates_index_diff:: index:: diff:: Order :: AsInCratesIndex ,
99
+ "input is always correctly ordered and is commits"
100
+ ) ;
101
+ changes
102
+ }
103
+ } ;
75
104
let num_changes = changes. len ( ) ;
76
105
for change in changes {
77
106
match change {
0 commit comments