Skip to content

Commit 03f81ff

Browse files
committed
Use VecDeque, rather than LinkedList in peer message buffering
When buffering outbound messages for peers, `LinkedList` adds rather substantial allocation overhead, which we avoid here by swapping for a `VecDeque`.
1 parent 5dc93af commit 03f81ff

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

lightning/src/ln/peer_handler.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::util::string::PrintableString;
4040

4141
use crate::prelude::*;
4242
use crate::io;
43-
use alloc::collections::LinkedList;
43+
use alloc::collections::VecDeque;
4444
use crate::sync::{Arc, Mutex, MutexGuard, FairRwLock};
4545
use core::sync::atomic::{AtomicBool, AtomicU32, AtomicI32, Ordering};
4646
use core::{cmp, hash, fmt, mem};
@@ -489,13 +489,13 @@ struct Peer {
489489
their_features: Option<InitFeatures>,
490490
their_socket_address: Option<SocketAddress>,
491491

492-
pending_outbound_buffer: LinkedList<Vec<u8>>,
492+
pending_outbound_buffer: VecDeque<Vec<u8>>,
493493
pending_outbound_buffer_first_msg_offset: usize,
494494
/// Queue gossip broadcasts separately from `pending_outbound_buffer` so we can easily
495495
/// prioritize channel messages over them.
496496
///
497497
/// Note that these messages are *not* encrypted/MAC'd, and are only serialized.
498-
gossip_broadcast_buffer: LinkedList<Vec<u8>>,
498+
gossip_broadcast_buffer: VecDeque<Vec<u8>>,
499499
awaiting_write_event: bool,
500500

501501
pending_read_buffer: Vec<u8>,
@@ -997,9 +997,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
997997
their_features: None,
998998
their_socket_address: remote_network_address,
999999

1000-
pending_outbound_buffer: LinkedList::new(),
1000+
pending_outbound_buffer: VecDeque::new(),
10011001
pending_outbound_buffer_first_msg_offset: 0,
1002-
gossip_broadcast_buffer: LinkedList::new(),
1002+
gossip_broadcast_buffer: VecDeque::new(),
10031003
awaiting_write_event: false,
10041004

10051005
pending_read_buffer,
@@ -1053,9 +1053,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
10531053
their_features: None,
10541054
their_socket_address: remote_network_address,
10551055

1056-
pending_outbound_buffer: LinkedList::new(),
1056+
pending_outbound_buffer: VecDeque::new(),
10571057
pending_outbound_buffer_first_msg_offset: 0,
1058-
gossip_broadcast_buffer: LinkedList::new(),
1058+
gossip_broadcast_buffer: VecDeque::new(),
10591059
awaiting_write_event: false,
10601060

10611061
pending_read_buffer,
@@ -1168,6 +1168,14 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
11681168
if peer.pending_outbound_buffer_first_msg_offset == next_buff.len() {
11691169
peer.pending_outbound_buffer_first_msg_offset = 0;
11701170
peer.pending_outbound_buffer.pop_front();
1171+
// Try to keep the buffer to no more than 170 elements
1172+
const VEC_SIZE: usize = ::core::mem::size_of::<Vec<u8>>();
1173+
let large_capacity = peer.pending_outbound_buffer.capacity() > 4096 / VEC_SIZE;
1174+
let lots_of_slack = peer.pending_outbound_buffer.len()
1175+
< peer.pending_outbound_buffer.capacity() / 2;
1176+
if large_capacity && lots_of_slack {
1177+
peer.pending_outbound_buffer.shrink_to_fit();
1178+
}
11711179
} else {
11721180
peer.awaiting_write_event = true;
11731181
}
@@ -1246,6 +1254,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
12461254
/// Append a message to a peer's pending outbound/write gossip broadcast buffer
12471255
fn enqueue_encoded_gossip_broadcast(&self, peer: &mut Peer, encoded_message: Vec<u8>) {
12481256
peer.msgs_sent_since_pong += 1;
1257+
debug_assert!(peer.gossip_broadcast_buffer.len() <= OUTBOUND_BUFFER_LIMIT_DROP_GOSSIP);
12491258
peer.gossip_broadcast_buffer.push_back(encoded_message);
12501259
}
12511260

0 commit comments

Comments
 (0)