Skip to content

Commit ea14b0e

Browse files
authored
Amortize AppendVec scan_accounts allocation (solana-labs#6331)
1 parent 37289c8 commit ea14b0e

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

accounts-db/src/append_vec.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,16 +1047,21 @@ impl AppendVec {
10471047
} else if STORE_META_OVERHEAD + data_len <= BUFFER_SIZE {
10481048
reader.set_required_data_len(STORE_META_OVERHEAD + data_len);
10491049
} else {
1050-
const MAX_CAPACITY: usize =
1051-
STORE_META_OVERHEAD + MAX_PERMITTED_DATA_LENGTH as usize;
1052-
if data_overflow_buffer.is_empty() {
1053-
// Reserve to worst case to avoid multiple reallocations.
1054-
data_overflow_buffer.reserve_exact(MAX_CAPACITY);
1055-
// SAFETY: we only write to the uninitialized portion of the buffer via `copy_from_slice` and `read_into_buffer`.
1050+
const MAX_CAPACITY: usize = MAX_PERMITTED_DATA_LENGTH as usize;
1051+
// 128KiB covers a reasonably large distribution of typical account sizes.
1052+
// In a recent sample, 99.98% of accounts' data lengths were less than or equal to 128KiB.
1053+
const MIN_CAPACITY: usize = 1024 * 128;
1054+
let capacity = data_overflow_buffer.capacity();
1055+
if data_len > capacity {
1056+
let next_cap = data_len
1057+
.next_power_of_two()
1058+
.clamp(MIN_CAPACITY, MAX_CAPACITY);
1059+
data_overflow_buffer.reserve_exact(next_cap - capacity);
1060+
// SAFETY: We only write to the uninitialized portion of the buffer via `copy_from_slice` and `read_into_buffer`.
10561061
// Later, we ensure we only read from the initialized portion of the buffer.
10571062
unsafe {
1058-
data_overflow_buffer.set_len(MAX_CAPACITY);
1059-
};
1063+
data_overflow_buffer.set_len(next_cap);
1064+
}
10601065
}
10611066

10621067
// Copy already read data to overflow buffer.

0 commit comments

Comments
 (0)