Skip to content

Commit a30038c

Browse files
committed
Use smallvec to avoid some allocations in push and with
1 parent b92dbe1 commit a30038c

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

misc/multiaddr/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ serde = "1.0.70"
1919
static_assertions = "1.1"
2020
unsigned-varint = "0.3"
2121
url = { version = "2.1.0", default-features = false }
22+
smallvec = "1.0"
2223

2324
[dev-dependencies]
2425
bincode = "1"

misc/multiaddr/src/lib.rs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ impl Multiaddr {
7070
/// ```
7171
///
7272
pub fn push(&mut self, p: Protocol<'_>) {
73-
let mut w = io::Cursor::new(self.to_vec());
74-
w.set_position(w.get_ref().len() as u64);
75-
p.write_bytes(&mut w).expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.");
76-
self.storage = Storage::from_slice(&w.into_inner());
73+
let mut w = Buffer::from_ref(self.as_ref());
74+
p.write_bytes(&mut w).expect("Writing to a `Buffer` never fails.");
75+
self.storage = w.to_storage();
7776
}
7877

7978
/// Pops the last `Protocol` of this multiaddr, or `None` if the multiaddr is empty.
@@ -105,10 +104,9 @@ impl Multiaddr {
105104

106105
/// Like [`Multiaddr::push`] but consumes `self`.
107106
pub fn with(mut self, p: Protocol<'_>) -> Self {
108-
let mut w = io::Cursor::new(self.to_vec());
109-
w.set_position(w.get_ref().len() as u64);
110-
p.write_bytes(&mut w).expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.");
111-
self.storage = Storage::from_slice(&w.into_inner());
107+
let mut w = Buffer::from_ref(self.as_ref());
108+
p.write_bytes(&mut w).expect("Writing to a `Buffer` never fails.");
109+
self.storage = w.to_storage();
112110
self
113111
}
114112

@@ -425,3 +423,26 @@ macro_rules! multiaddr {
425423
}
426424
}
427425
}
426+
427+
struct Buffer(smallvec::SmallVec<[u8; 32]>);
428+
429+
impl Buffer {
430+
fn from_ref(data: &[u8]) -> Self {
431+
Self(data.into())
432+
}
433+
434+
fn to_storage(self) -> Storage {
435+
Storage::from_slice(&self.0)
436+
}
437+
}
438+
439+
impl io::Write for Buffer {
440+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
441+
self.0.extend_from_slice(buf);
442+
Ok(buf.len())
443+
}
444+
445+
fn flush(&mut self) -> io::Result<()> {
446+
Ok(())
447+
}
448+
}

0 commit comments

Comments
 (0)