@@ -83,31 +83,28 @@ pub fn add_publisher(
83
83
}
84
84
}
85
85
86
- let mut current_index: usize = try_convert ( price_data. num_ ) ?;
86
+ let current_index: usize = try_convert ( price_data. num_ ) ?;
87
87
sol_memset (
88
88
bytes_of_mut ( & mut price_data. comp_ [ current_index] ) ,
89
89
0 ,
90
90
size_of :: < PriceComponent > ( ) ,
91
91
) ;
92
92
price_data. comp_ [ current_index] . pub_ = cmd_args. publisher ;
93
+ price_data. num_ += 1 ;
93
94
94
- // Shift the element back to keep the publishers components sorted.
95
- while current_index > 0
96
- && price_data. comp_ [ current_index] . pub_ < price_data. comp_ [ current_index - 1 ] . pub_
95
+ // Sort the publishers in the list
97
96
{
98
- price_data . comp_ . swap ( current_index , current_index - 1 ) ;
99
- current_index -= 1 ;
97
+ let num_comps = try_convert :: < u32 , usize > ( price_data . num_ ) ? ;
98
+ sort_price_comps ( & mut price_data . comp_ , num_comps ) ? ;
100
99
}
101
100
102
- price_data. num_ += 1 ;
103
101
price_data. header . size = try_convert :: < _ , u32 > ( PriceAccount :: INITIAL_SIZE ) ?;
104
102
Ok ( ( ) )
105
103
}
106
104
107
105
/// A copy of rust slice/sort.rs heapsort implementation which is small and fast. We couldn't use
108
106
/// the sort directly because it was only accessible behind a unstable feature flag at the time of
109
107
/// writing this code.
110
- #[ inline( always) ]
111
108
fn heapsort ( v : & mut [ ( Pubkey , usize ) ] ) {
112
109
// This binary heap respects the invariant `parent >= child`.
113
110
let sift_down = |v : & mut [ ( Pubkey , usize ) ] , mut node : usize | {
@@ -155,16 +152,19 @@ fn heapsort(v: &mut [(Pubkey, usize)]) {
155
152
///
156
153
/// num_publishers is the number of publishers in the list that should be sorted. It is explicitly
157
154
/// passed to avoid callers mistake of passing the full slice which may contain uninitialized values.
158
- #[ inline( always) ]
159
155
fn sort_price_comps ( comps : & mut [ PriceComponent ] , num_comps : usize ) -> Result < ( ) , ProgramError > {
160
156
let comps = comps
161
157
. get_mut ( ..num_comps)
162
158
. ok_or ( ProgramError :: InvalidArgument ) ?;
163
159
160
+ // Publishers are likely sorted in ascending order but
161
+ // heapsorts creates a max-heap so we reverse the order
162
+ // of the keys to make the heapify step faster.
164
163
let mut keys = comps
165
164
. iter ( )
166
165
. enumerate ( )
167
166
. map ( |( i, x) | ( x. pub_ , i) )
167
+ . rev ( )
168
168
. collect :: < Vec < _ > > ( ) ;
169
169
170
170
heapsort ( & mut keys) ;
0 commit comments