Skip to content

Commit fe847fa

Browse files
authored
Merge pull request #118 from nazar-pc/use-bytes
Use `Bytes` to avoid double indirection with `Arc<Vec<u8>>`
2 parents def1fff + 1eeade6 commit fe847fa

File tree

2 files changed

+36
-29
lines changed

2 files changed

+36
-29
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ default = ["url"]
1616
[dependencies]
1717
arrayref = "0.3"
1818
byteorder = "1.5.0"
19+
bytes = "1.7.2"
1920
data-encoding = "2.6.0"
2021
multibase = "0.9.1"
2122
multihash = "0.19"

src/lib.rs

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ mod from_url;
1313
pub use self::errors::{Error, Result};
1414
pub use self::onion_addr::Onion3Addr;
1515
pub use self::protocol::Protocol;
16+
use bytes::{BufMut, Bytes, BytesMut};
1617
use serde::{
1718
de::{self, Error as DeserializerError},
1819
Deserialize, Deserializer, Serialize, Serializer,
1920
};
2021
use std::{
2122
convert::TryFrom,
22-
fmt, io,
23+
fmt,
2324
iter::FromIterator,
2425
net::{IpAddr, Ipv4Addr, Ipv6Addr},
2526
result::Result as StdResult,
2627
str::FromStr,
27-
sync::Arc,
2828
};
2929

3030
pub use libp2p_identity::PeerId;
@@ -42,21 +42,21 @@ static_assertions::const_assert! {
4242
#[allow(clippy::rc_buffer)]
4343
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
4444
pub struct Multiaddr {
45-
bytes: Arc<Vec<u8>>,
45+
bytes: Bytes,
4646
}
4747

4848
impl Multiaddr {
4949
/// Create a new, empty multiaddress.
5050
pub fn empty() -> Self {
5151
Self {
52-
bytes: Arc::new(Vec::new()),
52+
bytes: Bytes::new(),
5353
}
5454
}
5555

5656
/// Create a new, empty multiaddress with the given capacity.
5757
pub fn with_capacity(n: usize) -> Self {
5858
Self {
59-
bytes: Arc::new(Vec::with_capacity(n)),
59+
bytes: BytesMut::with_capacity(n).freeze(),
6060
}
6161
}
6262

@@ -88,10 +88,10 @@ impl Multiaddr {
8888
/// ```
8989
///
9090
pub fn push(&mut self, p: Protocol<'_>) {
91-
let mut w = io::Cursor::<&mut Vec<u8>>::new(Arc::make_mut(&mut self.bytes));
92-
w.set_position(w.get_ref().len() as u64);
93-
p.write_bytes(&mut w)
94-
.expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.")
91+
let mut bytes = BytesMut::from(std::mem::take(&mut self.bytes));
92+
p.write_bytes(&mut (&mut bytes).writer())
93+
.expect("Writing to a `BytesMut` never fails.");
94+
self.bytes = bytes.freeze();
9595
}
9696

9797
/// Pops the last `Protocol` of this multiaddr, or `None` if the multiaddr is empty.
@@ -116,17 +116,19 @@ impl Multiaddr {
116116
}
117117
slice = s
118118
};
119-
let remaining_len = self.bytes.len() - slice.len();
120-
Arc::make_mut(&mut self.bytes).truncate(remaining_len);
119+
let remaining_len = self.len() - slice.len();
120+
let mut bytes = BytesMut::from(std::mem::take(&mut self.bytes));
121+
bytes.truncate(remaining_len);
122+
self.bytes = bytes.freeze();
121123
Some(protocol)
122124
}
123125

124126
/// Like [`Multiaddr::push`] but consumes `self`.
125127
pub fn with(mut self, p: Protocol<'_>) -> Self {
126-
let mut w = io::Cursor::<&mut Vec<u8>>::new(Arc::make_mut(&mut self.bytes));
127-
w.set_position(w.get_ref().len() as u64);
128-
p.write_bytes(&mut w)
129-
.expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.");
128+
let mut bytes = BytesMut::from(std::mem::take(&mut self.bytes));
129+
p.write_bytes(&mut (&mut bytes).writer())
130+
.expect("Writing to a `BytesMut` never fails.");
131+
self.bytes = bytes.freeze();
130132
self
131133
}
132134

@@ -210,7 +212,7 @@ impl Multiaddr {
210212

211213
/// Returns &str identifiers for the protocol names themselves.
212214
/// This omits specific info like addresses, ports, peer IDs, and the like.
213-
/// Example: `"/ip4/127.0.0.1/tcp/5001"` would return `["ip4", "tcp"]`
215+
/// Example: `"/ip4/127.0.0.1/tcp/5001"` would return `["ip4", "tcp"]`
214216
pub fn protocol_stack(&self) -> ProtoStackIter {
215217
ProtoStackIter { parts: self.iter() }
216218
}
@@ -262,13 +264,13 @@ impl<'a> FromIterator<Protocol<'a>> for Multiaddr {
262264
where
263265
T: IntoIterator<Item = Protocol<'a>>,
264266
{
265-
let mut writer = Vec::new();
267+
let mut bytes = BytesMut::new();
266268
for cmp in iter {
267-
cmp.write_bytes(&mut writer)
268-
.expect("Writing to a `Vec` never fails.");
269+
cmp.write_bytes(&mut (&mut bytes).writer())
270+
.expect("Writing to a `BytesMut` never fails.");
269271
}
270272
Multiaddr {
271-
bytes: Arc::new(writer),
273+
bytes: bytes.freeze(),
272274
}
273275
}
274276
}
@@ -277,7 +279,7 @@ impl FromStr for Multiaddr {
277279
type Err = Error;
278280

279281
fn from_str(input: &str) -> Result<Self> {
280-
let mut writer = Vec::new();
282+
let mut bytes = BytesMut::new();
281283
let mut parts = input.split('/').peekable();
282284

283285
if Some("") != parts.next() {
@@ -287,12 +289,12 @@ impl FromStr for Multiaddr {
287289

288290
while parts.peek().is_some() {
289291
let p = Protocol::from_str_parts(&mut parts)?;
290-
p.write_bytes(&mut writer)
291-
.expect("Writing to a `Vec` never fails.");
292+
p.write_bytes(&mut (&mut bytes).writer())
293+
.expect("Writing to a `BytesMut` never fails.");
292294
}
293295

294296
Ok(Multiaddr {
295-
bytes: Arc::new(writer),
297+
bytes: bytes.freeze(),
296298
})
297299
}
298300
}
@@ -330,10 +332,12 @@ impl<'a> Iterator for ProtoStackIter<'a> {
330332

331333
impl<'a> From<Protocol<'a>> for Multiaddr {
332334
fn from(p: Protocol<'a>) -> Multiaddr {
333-
let mut w = Vec::new();
334-
p.write_bytes(&mut w)
335-
.expect("Writing to a `Vec` never fails.");
336-
Multiaddr { bytes: Arc::new(w) }
335+
let mut bytes = BytesMut::new();
336+
p.write_bytes(&mut (&mut bytes).writer())
337+
.expect("Writing to a `BytesMut` never fails.");
338+
Multiaddr {
339+
bytes: bytes.freeze(),
340+
}
337341
}
338342
}
339343

@@ -368,7 +372,9 @@ impl TryFrom<Vec<u8>> for Multiaddr {
368372
let (_, s) = Protocol::from_bytes(slice)?;
369373
slice = s
370374
}
371-
Ok(Multiaddr { bytes: Arc::new(v) })
375+
Ok(Multiaddr {
376+
bytes: Bytes::from(v),
377+
})
372378
}
373379
}
374380

0 commit comments

Comments
 (0)