mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-30 18:21:33 +00:00
multiaddr: Replace Bytes
with Arc<Vec<u8>>
. (#1370)
* multiaddr: Replace `Bytes` with `Arc<Vec<u8>>`. * Annotate type of `io::Cursor`. Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com> * Annotate type of `io::Cursor`. Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com> Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
This commit is contained in:
committed by
Pierre Krieger
parent
d83619109b
commit
ab2eb7a51d
@ -12,11 +12,11 @@ version = "0.6.0"
|
|||||||
arrayref = "0.3"
|
arrayref = "0.3"
|
||||||
bs58 = "0.3.0"
|
bs58 = "0.3.0"
|
||||||
byteorder = "1.3.1"
|
byteorder = "1.3.1"
|
||||||
bytes = "0.4.12"
|
|
||||||
data-encoding = "2.1"
|
data-encoding = "2.1"
|
||||||
multihash = { package = "parity-multihash", version = "0.2.0", path = "../multihash" }
|
multihash = { package = "parity-multihash", version = "0.2.0", path = "../multihash" }
|
||||||
percent-encoding = "2.1.0"
|
percent-encoding = "2.1.0"
|
||||||
serde = "1.0.70"
|
serde = "1.0.70"
|
||||||
|
static_assertions = "1.1"
|
||||||
unsigned-varint = "0.3"
|
unsigned-varint = "0.3"
|
||||||
url = { version = "2.1.0", default-features = false }
|
url = { version = "2.1.0", default-features = false }
|
||||||
|
|
||||||
|
@ -5,9 +5,7 @@ pub use multihash;
|
|||||||
mod protocol;
|
mod protocol;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod from_url;
|
mod from_url;
|
||||||
mod util;
|
|
||||||
|
|
||||||
use bytes::Bytes;
|
|
||||||
use serde::{
|
use serde::{
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Deserializer,
|
Deserializer,
|
||||||
@ -18,28 +16,36 @@ use serde::{
|
|||||||
use std::{
|
use std::{
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
fmt,
|
fmt,
|
||||||
|
io,
|
||||||
iter::FromIterator,
|
iter::FromIterator,
|
||||||
net::{IpAddr, Ipv4Addr, Ipv6Addr},
|
net::{IpAddr, Ipv4Addr, Ipv6Addr},
|
||||||
result::Result as StdResult,
|
result::Result as StdResult,
|
||||||
str::FromStr
|
str::FromStr,
|
||||||
|
sync::Arc
|
||||||
};
|
};
|
||||||
pub use self::errors::{Result, Error};
|
pub use self::errors::{Result, Error};
|
||||||
pub use self::from_url::{FromUrlErr, from_url, from_url_lossy};
|
pub use self::from_url::{FromUrlErr, from_url, from_url_lossy};
|
||||||
pub use self::protocol::Protocol;
|
pub use self::protocol::Protocol;
|
||||||
|
|
||||||
|
static_assertions::const_assert! {
|
||||||
|
// This check is most certainly overkill right now, but done here
|
||||||
|
// anyway to ensure the `as u64` casts in this crate are safe.
|
||||||
|
std::mem::size_of::<usize>() <= std::mem::size_of::<u64>()
|
||||||
|
}
|
||||||
|
|
||||||
/// Representation of a Multiaddr.
|
/// Representation of a Multiaddr.
|
||||||
#[derive(PartialEq, Eq, Clone, Hash)]
|
#[derive(PartialEq, Eq, Clone, Hash)]
|
||||||
pub struct Multiaddr { bytes: Bytes }
|
pub struct Multiaddr { bytes: Arc<Vec<u8>> }
|
||||||
|
|
||||||
impl Multiaddr {
|
impl Multiaddr {
|
||||||
/// Create a new, empty multiaddress.
|
/// Create a new, empty multiaddress.
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self { bytes: Bytes::new() }
|
Self { bytes: Arc::new(Vec::new()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new, empty multiaddress with the given capacity.
|
/// Create a new, empty multiaddress with the given capacity.
|
||||||
pub fn with_capacity(n: usize) -> Self {
|
pub fn with_capacity(n: usize) -> Self {
|
||||||
Self { bytes: Bytes::with_capacity(n) }
|
Self { bytes: Arc::new(Vec::with_capacity(n)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the length in bytes of this multiaddress.
|
/// Return the length in bytes of this multiaddress.
|
||||||
@ -65,9 +71,9 @@ impl Multiaddr {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
pub fn push(&mut self, p: Protocol<'_>) {
|
pub fn push(&mut self, p: Protocol<'_>) {
|
||||||
let mut w = Vec::new();
|
let mut w = io::Cursor::<&mut Vec<u8>>::new(Arc::make_mut(&mut self.bytes));
|
||||||
p.write_bytes(&mut w).expect("Writing to a `Vec` never fails.");
|
w.set_position(w.get_ref().len() as u64);
|
||||||
self.bytes.extend_from_slice(&w);
|
p.write_bytes(&mut w).expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pops the last `Protocol` of this multiaddr, or `None` if the multiaddr is empty.
|
/// Pops the last `Protocol` of this multiaddr, or `None` if the multiaddr is empty.
|
||||||
@ -93,25 +99,16 @@ impl Multiaddr {
|
|||||||
slice = s
|
slice = s
|
||||||
};
|
};
|
||||||
let remaining_len = self.bytes.len() - slice.len();
|
let remaining_len = self.bytes.len() - slice.len();
|
||||||
self.bytes.truncate(remaining_len);
|
Arc::make_mut(&mut self.bytes).truncate(remaining_len);
|
||||||
Some(protocol)
|
Some(protocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like [`push`] but more efficient if this `Multiaddr` has no living clones.
|
/// Like [`push`] but consumes `self`.
|
||||||
pub fn with(self, p: Protocol<'_>) -> Self {
|
pub fn with(mut self, p: Protocol<'_>) -> Self {
|
||||||
match self.bytes.try_mut() {
|
let mut w = io::Cursor::<&mut Vec<u8>>::new(Arc::make_mut(&mut self.bytes));
|
||||||
Ok(bytes) => {
|
w.set_position(w.get_ref().len() as u64);
|
||||||
let mut w = util::BytesWriter(bytes);
|
p.write_bytes(&mut w).expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.");
|
||||||
p.write_bytes(&mut w).expect("Writing to a `BytesWriter` never fails.");
|
self
|
||||||
Multiaddr { bytes: w.0.freeze() }
|
|
||||||
}
|
|
||||||
Err(mut bytes) => {
|
|
||||||
let mut w = Vec::new();
|
|
||||||
p.write_bytes(&mut w).expect("Writing to a `Vec` never fails.");
|
|
||||||
bytes.extend_from_slice(&w);
|
|
||||||
Multiaddr { bytes }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the components of this multiaddress.
|
/// Returns the components of this multiaddress.
|
||||||
@ -217,7 +214,7 @@ impl<'a> FromIterator<Protocol<'a>> for Multiaddr {
|
|||||||
for cmp in iter {
|
for cmp in iter {
|
||||||
cmp.write_bytes(&mut writer).expect("Writing to a `Vec` never fails.");
|
cmp.write_bytes(&mut writer).expect("Writing to a `Vec` never fails.");
|
||||||
}
|
}
|
||||||
Multiaddr { bytes: writer.into() }
|
Multiaddr { bytes: Arc::new(writer) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +235,7 @@ impl FromStr for Multiaddr {
|
|||||||
p.write_bytes(&mut writer).expect("Writing to a `Vec` never fails.");
|
p.write_bytes(&mut writer).expect("Writing to a `Vec` never fails.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Multiaddr { bytes: writer.into() })
|
Ok(Multiaddr { bytes: Arc::new(writer) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +262,7 @@ impl<'a> From<Protocol<'a>> for Multiaddr {
|
|||||||
fn from(p: Protocol<'a>) -> Multiaddr {
|
fn from(p: Protocol<'a>) -> Multiaddr {
|
||||||
let mut w = Vec::new();
|
let mut w = Vec::new();
|
||||||
p.write_bytes(&mut w).expect("Writing to a `Vec` never fails.");
|
p.write_bytes(&mut w).expect("Writing to a `Vec` never fails.");
|
||||||
Multiaddr { bytes: w.into() }
|
Multiaddr { bytes: Arc::new(w) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +297,7 @@ impl TryFrom<Vec<u8>> for Multiaddr {
|
|||||||
let (_, s) = Protocol::from_bytes(slice)?;
|
let (_, s) = Protocol::from_bytes(slice)?;
|
||||||
slice = s
|
slice = s
|
||||||
}
|
}
|
||||||
Ok(Multiaddr { bytes: v.into() })
|
Ok(Multiaddr { bytes: Arc::new(v) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,4 +410,3 @@ macro_rules! multiaddr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
use bytes::BytesMut;
|
|
||||||
|
|
||||||
/// An [`io::Write`] impl for [`BytesMut`].
|
|
||||||
///
|
|
||||||
/// In contrast to [`bytes::buf::Writer`] this [`io::Write] implementation
|
|
||||||
/// transparently reserves enough space for [`io::Write::write_all`] to
|
|
||||||
/// succeed, i.e. it does not require upfront reservation of space.
|
|
||||||
pub(crate) struct BytesWriter(pub(crate) BytesMut);
|
|
||||||
|
|
||||||
impl std::io::Write for BytesWriter {
|
|
||||||
fn write(&mut self, src: &[u8]) -> std::io::Result<usize> {
|
|
||||||
self.0.extend_from_slice(src);
|
|
||||||
Ok(src.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> std::io::Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user