@@ -83,31 +83,28 @@ pub fn add_publisher(
8383 }
8484 }
8585
86- let mut current_index: usize = try_convert ( price_data. num_ ) ?;
86+ let current_index: usize = try_convert ( price_data. num_ ) ?;
8787 sol_memset (
8888 bytes_of_mut ( & mut price_data. comp_ [ current_index] ) ,
8989 0 ,
9090 size_of :: < PriceComponent > ( ) ,
9191 ) ;
9292 price_data. comp_ [ current_index] . pub_ = cmd_args. publisher ;
93+ price_data. num_ += 1 ;
9394
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
9796 {
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 ) ? ;
10099 }
101100
102- price_data. num_ += 1 ;
103101 price_data. header . size = try_convert :: < _ , u32 > ( PriceAccount :: INITIAL_SIZE ) ?;
104102 Ok ( ( ) )
105103}
106104
107105/// A copy of rust slice/sort.rs heapsort implementation which is small and fast. We couldn't use
108106/// the sort directly because it was only accessible behind a unstable feature flag at the time of
109107/// writing this code.
110- #[ inline( always) ]
111108fn heapsort ( v : & mut [ ( Pubkey , usize ) ] ) {
112109 // This binary heap respects the invariant `parent >= child`.
113110 let sift_down = |v : & mut [ ( Pubkey , usize ) ] , mut node : usize | {
@@ -155,16 +152,19 @@ fn heapsort(v: &mut [(Pubkey, usize)]) {
155152///
156153/// num_publishers is the number of publishers in the list that should be sorted. It is explicitly
157154/// passed to avoid callers mistake of passing the full slice which may contain uninitialized values.
158- #[ inline( always) ]
159155fn sort_price_comps ( comps : & mut [ PriceComponent ] , num_comps : usize ) -> Result < ( ) , ProgramError > {
160156 let comps = comps
161157 . get_mut ( ..num_comps)
162158 . ok_or ( ProgramError :: InvalidArgument ) ?;
163159
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.
164163 let mut keys = comps
165164 . iter ( )
166165 . enumerate ( )
167166 . map ( |( i, x) | ( x. pub_ , i) )
167+ . rev ( )
168168 . collect :: < Vec < _ > > ( ) ;
169169
170170 heapsort ( & mut keys) ;
0 commit comments