Skip to content

Commit 37e99b8

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

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

program/rust/src/processor/add_publisher.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -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)]
111108
fn 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)]
159155
fn 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

Comments
 (0)