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