Skip to content

Commit 45002cf

Browse files
committed
refactor: use heapsort for each publisher addition too
1 parent c27465d commit 45002cf

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

program/rust/src/processor/add_publisher.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -83,31 +83,29 @@ 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;
9393

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
9797
{
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)?;
100100
}
101101

102-
price_data.num_ += 1;
103102
price_data.header.size = try_convert::<_, u32>(PriceAccount::INITIAL_SIZE)?;
104103
Ok(())
105104
}
106105

107106
/// A copy of rust slice/sort.rs heapsort implementation which is small and fast. We couldn't use
108107
/// the sort directly because it was only accessible behind a unstable feature flag at the time of
109108
/// writing this code.
110-
#[inline(always)]
111109
fn heapsort(v: &mut [(Pubkey, usize)]) {
112110
// This binary heap respects the invariant `parent >= child`.
113111
let sift_down = |v: &mut [(Pubkey, usize)], mut node: usize| {
@@ -155,16 +153,19 @@ fn heapsort(v: &mut [(Pubkey, usize)]) {
155153
///
156154
/// num_publishers is the number of publishers in the list that should be sorted. It is explicitly
157155
/// passed to avoid callers mistake of passing the full slice which may contain uninitialized values.
158-
#[inline(always)]
159156
fn sort_price_comps(comps: &mut [PriceComponent], num_comps: usize) -> Result<(), ProgramError> {
160157
let comps = comps
161158
.get_mut(..num_comps)
162159
.ok_or(ProgramError::InvalidArgument)?;
163160

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.
164164
let mut keys = comps
165165
.iter()
166166
.enumerate()
167167
.map(|(i, x)| (x.pub_, i))
168+
.rev()
168169
.collect::<Vec<_>>();
169170

170171
heapsort(&mut keys);

0 commit comments

Comments
 (0)