From fa05fe8376b106d19bc6a8b04759fb136738d2b8 Mon Sep 17 00:00:00 2001 From: Igor Katson Date: Fri, 29 Mar 2024 11:00:58 +0000 Subject: [PATCH] Box<[u8]> instead of Vec for ByteBufOwned --- Makefile | 2 +- crates/bencode/src/bencode_value.rs | 4 +- crates/bencode/src/lib.rs | 2 +- crates/bencode/src/serde_bencode_ser.rs | 14 +++---- crates/buffers/src/lib.rs | 38 +++++++++---------- crates/dht/src/bprotocol.rs | 4 +- crates/dht/src/dht.rs | 30 +++++++-------- crates/dht/src/peer_store.rs | 4 +- crates/librqbit/src/api.rs | 4 +- crates/librqbit/src/chunk_tracker.rs | 2 +- crates/librqbit/src/create_torrent_file.rs | 15 +++++--- crates/librqbit/src/dht_utils.rs | 4 +- crates/librqbit/src/file_ops.rs | 14 ++++--- crates/librqbit/src/peer_connection.rs | 6 +-- crates/librqbit/src/peer_info_reader/mod.rs | 13 ++++--- crates/librqbit/src/session.rs | 27 +++++++------ crates/librqbit/src/torrent_state/live/mod.rs | 8 ++-- .../src/torrent_state/live/peer/mod.rs | 2 +- .../src/torrent_state/live/peers/mod.rs | 4 +- crates/librqbit/src/torrent_state/mod.rs | 8 ++-- crates/librqbit/src/type_aliases.rs | 2 +- crates/librqbit_core/Cargo.toml | 12 +++--- crates/librqbit_core/src/torrent_metainfo.rs | 4 +- crates/peer_binary_protocol/src/lib.rs | 4 +- 24 files changed, 118 insertions(+), 109 deletions(-) diff --git a/Makefile b/Makefile index 751fb44..c06ddaa 100644 --- a/Makefile +++ b/Makefile @@ -113,4 +113,4 @@ release-all: release-windows release-linux release-macos-universal cp ./target/x86_64-pc-windows-gnu/release-github/rqbit.exe /tmp/rqbit-release cp ./target/x86_64-apple-darwin/release-github/rqbit-osx-universal /tmp/rqbit-release cp ./target/x86_64-unknown-linux-gnu/release-github/rqbit /tmp/rqbit-release/rqbit-linux-x86_64 - echo "The release was built in /tmp/rqbit-release" \ No newline at end of file + echo "The release was built in /tmp/rqbit-release" diff --git a/crates/bencode/src/bencode_value.rs b/crates/bencode/src/bencode_value.rs index b765d16..f507447 100644 --- a/crates/bencode/src/bencode_value.rs +++ b/crates/bencode/src/bencode_value.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, marker::PhantomData}; -use buffers::{ByteBuf, ByteString}; +use buffers::{ByteBuf, ByteBufOwned}; use clone_to_owned::CloneToOwned; use serde::Deserializer; @@ -133,7 +133,7 @@ where } pub type BencodeValueBorrowed<'a> = BencodeValue>; -pub type BencodeValueOwned = BencodeValue; +pub type BencodeValueOwned = BencodeValue; #[cfg(test)] mod tests { diff --git a/crates/bencode/src/lib.rs b/crates/bencode/src/lib.rs index dc5a7ed..2753a6a 100644 --- a/crates/bencode/src/lib.rs +++ b/crates/bencode/src/lib.rs @@ -6,4 +6,4 @@ pub use bencode_value::*; pub use serde_bencode_de::*; pub use serde_bencode_ser::*; -pub use buffers::{ByteBuf, ByteString}; +pub use buffers::{ByteBuf, ByteBufOwned}; diff --git a/crates/bencode/src/serde_bencode_ser.rs b/crates/bencode/src/serde_bencode_ser.rs index 2344e2e..71357c7 100644 --- a/crates/bencode/src/serde_bencode_ser.rs +++ b/crates/bencode/src/serde_bencode_ser.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use serde::{ser::Impossible, Serialize, Serializer}; -use buffers::ByteString; +use buffers::ByteBufOwned; #[derive(Debug)] pub enum SerErrorKind { @@ -136,8 +136,8 @@ impl<'ser, W: std::io::Write> serde::ser::SerializeTuple for SerializeTuple<'ser struct SerializeMap<'ser, W: std::io::Write> { ser: &'ser mut BencodeSerializer, - tmp: BTreeMap, - last_key: Option, + tmp: BTreeMap, + last_key: Option, } impl<'ser, W: std::io::Write> serde::ser::SerializeMap for SerializeMap<'ser, W> { type Ok = (); @@ -152,7 +152,7 @@ impl<'ser, W: std::io::Write> serde::ser::SerializeMap for SerializeMap<'ser, W> let mut ser = BencodeSerializer::new(&mut buf); ser.hack_no_bytestring_prefix = true; key.serialize(&mut ser)?; - self.last_key.replace(ByteString::from(buf)); + self.last_key.replace(ByteBufOwned::from(buf)); Ok(()) // key.serialize(&mut *self.ser); } @@ -165,7 +165,7 @@ impl<'ser, W: std::io::Write> serde::ser::SerializeMap for SerializeMap<'ser, W> let mut ser = BencodeSerializer::new(&mut buf); value.serialize(&mut ser)?; self.tmp - .insert(self.last_key.take().unwrap(), ByteString::from(buf)); + .insert(self.last_key.take().unwrap(), ByteBufOwned::from(buf)); Ok(()) } @@ -180,7 +180,7 @@ impl<'ser, W: std::io::Write> serde::ser::SerializeMap for SerializeMap<'ser, W> struct SerializeStruct<'ser, W: std::io::Write> { ser: &'ser mut BencodeSerializer, - tmp: BTreeMap<&'static str, ByteString>, + tmp: BTreeMap<&'static str, ByteBufOwned>, } impl<'ser, W: std::io::Write> serde::ser::SerializeStruct for SerializeStruct<'ser, W> { type Ok = (); @@ -198,7 +198,7 @@ impl<'ser, W: std::io::Write> serde::ser::SerializeStruct for SerializeStruct<'s let mut buf = Vec::new(); let mut ser = BencodeSerializer::new(&mut buf); value.serialize(&mut ser)?; - self.tmp.insert(key, ByteString::from(buf)); + self.tmp.insert(key, ByteBufOwned::from(buf)); Ok(()) } diff --git a/crates/buffers/src/lib.rs b/crates/buffers/src/lib.rs index b45c891..934db37 100644 --- a/crates/buffers/src/lib.rs +++ b/crates/buffers/src/lib.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Deserializer}; use clone_to_owned::CloneToOwned; #[derive(Default, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)] -pub struct ByteString(pub Vec); +pub struct ByteBufOwned(pub Box<[u8]>); #[derive(Default, Deserialize, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)] #[serde(transparent)] @@ -18,7 +18,7 @@ pub trait ByteBufT { fn as_slice(&self) -> &[u8]; } -impl ByteBufT for ByteString { +impl ByteBufT for ByteBufOwned { fn as_slice(&self) -> &[u8] { self.as_ref() } @@ -78,31 +78,31 @@ impl<'a> std::fmt::Display for ByteBuf<'a> { } } -impl std::fmt::Debug for ByteString { +impl std::fmt::Debug for ByteBufOwned { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { debug_bytes(&self.0, f, true) } } -impl std::fmt::Display for ByteString { +impl std::fmt::Display for ByteBufOwned { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { debug_bytes(&self.0, f, false) } } impl<'a> CloneToOwned for ByteBuf<'a> { - type Target = ByteString; + type Target = ByteBufOwned; fn clone_to_owned(&self) -> Self::Target { - ByteString(self.as_slice().to_owned()) + ByteBufOwned(self.as_slice().to_owned().into_boxed_slice()) } } -impl CloneToOwned for ByteString { - type Target = ByteString; +impl CloneToOwned for ByteBufOwned { + type Target = ByteBufOwned; fn clone_to_owned(&self) -> Self::Target { - ByteString(self.as_slice().to_owned()) + ByteBufOwned(self.0.clone()) } } @@ -112,7 +112,7 @@ impl<'a> std::convert::AsRef<[u8]> for ByteBuf<'a> { } } -impl std::convert::AsRef<[u8]> for ByteString { +impl std::convert::AsRef<[u8]> for ByteBufOwned { fn as_ref(&self) -> &[u8] { &self.0 } @@ -126,7 +126,7 @@ impl<'a> std::ops::Deref for ByteBuf<'a> { } } -impl std::ops::Deref for ByteString { +impl std::ops::Deref for ByteBufOwned { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -140,15 +140,15 @@ impl<'a> From<&'a [u8]> for ByteBuf<'a> { } } -impl<'a> From<&'a [u8]> for ByteString { +impl<'a> From<&'a [u8]> for ByteBufOwned { fn from(b: &'a [u8]) -> Self { Self(b.into()) } } -impl From> for ByteString { +impl From> for ByteBufOwned { fn from(b: Vec) -> Self { - Self(b) + Self(b.into_boxed_slice()) } } @@ -161,7 +161,7 @@ impl<'a> serde::ser::Serialize for ByteBuf<'a> { } } -impl serde::ser::Serialize for ByteString { +impl serde::ser::Serialize for ByteBufOwned { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, @@ -170,7 +170,7 @@ impl serde::ser::Serialize for ByteString { } } -impl<'de> serde::de::Deserialize<'de> for ByteString { +impl<'de> serde::de::Deserialize<'de> for ByteBufOwned { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, @@ -178,7 +178,7 @@ impl<'de> serde::de::Deserialize<'de> for ByteString { struct Visitor; impl<'de> serde::de::Visitor<'de> for Visitor { - type Value = Vec; + type Value = ByteBufOwned; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("byte string") @@ -187,9 +187,9 @@ impl<'de> serde::de::Deserialize<'de> for ByteString { where E: serde::de::Error, { - Ok(v.to_owned()) + Ok(v.to_owned().into()) } } - Ok(ByteString(deserializer.deserialize_byte_buf(Visitor {})?)) + Ok(deserializer.deserialize_byte_buf(Visitor {})?) } } diff --git a/crates/dht/src/bprotocol.rs b/crates/dht/src/bprotocol.rs index 2cbe170..2c5335b 100644 --- a/crates/dht/src/bprotocol.rs +++ b/crates/dht/src/bprotocol.rs @@ -4,7 +4,7 @@ use std::{ net::{Ipv4Addr, SocketAddrV4}, }; -use bencode::{ByteBuf, ByteString}; +use bencode::{ByteBuf, ByteBufOwned}; use clone_to_owned::CloneToOwned; use librqbit_core::hash_id::Id20; use serde::{ @@ -356,7 +356,7 @@ pub struct Message { pub ip: Option, } -impl Message { +impl Message { // This implies that the transaction id was generated by us. pub fn get_our_transaction_id(&self) -> Option { if self.transaction_id.len() != 2 { diff --git a/crates/dht/src/dht.rs b/crates/dht/src/dht.rs index 0198038..2c1a6ab 100644 --- a/crates/dht/src/dht.rs +++ b/crates/dht/src/dht.rs @@ -21,7 +21,7 @@ use crate::{ }; use anyhow::{bail, Context}; use backoff::{backoff::Backoff, ExponentialBackoffBuilder}; -use bencode::ByteString; +use bencode::ByteBufOwned; use dashmap::DashMap; use futures::{ future::BoxFuture, stream::FuturesUnordered, FutureExt, Stream, StreamExt, TryFutureExt, @@ -59,7 +59,7 @@ struct OutstandingRequest { pub struct WorkerSendRequest { // If this is set, we are tracking the response in inflight_by_transaction_id our_tid: Option, - message: Message, + message: Message, addr: SocketAddr, } @@ -607,13 +607,13 @@ impl DhtState { } } - fn create_request(&self, request: Request) -> (u16, Message) { + fn create_request(&self, request: Request) -> (u16, Message) { let transaction_id = self.next_transaction_id.fetch_add(1, Ordering::Relaxed); let transaction_id_buf = [(transaction_id >> 8) as u8, (transaction_id & 0xff) as u8]; let message = match request { Request::GetPeers(info_hash) => Message { - transaction_id: ByteString::from(transaction_id_buf.as_ref()), + transaction_id: ByteBufOwned::from(transaction_id_buf.as_ref()), version: None, ip: None, kind: MessageKind::GetPeersRequest(GetPeersRequest { @@ -622,7 +622,7 @@ impl DhtState { }), }, Request::FindNode(target) => Message { - transaction_id: ByteString::from(transaction_id_buf.as_ref()), + transaction_id: ByteBufOwned::from(transaction_id_buf.as_ref()), version: None, ip: None, kind: MessageKind::FindNodeRequest(FindNodeRequest { @@ -631,7 +631,7 @@ impl DhtState { }), }, Request::Ping => Message { - transaction_id: ByteString::from(transaction_id_buf.as_ref()), + transaction_id: ByteBufOwned::from(transaction_id_buf.as_ref()), version: None, ip: None, kind: MessageKind::PingRequest(PingRequest { id: self.id }), @@ -648,7 +648,7 @@ impl DhtState { port, token, }), - transaction_id: ByteString::from(transaction_id_buf.as_ref()), + transaction_id: ByteBufOwned::from(transaction_id_buf.as_ref()), version: None, ip: None, }, @@ -658,7 +658,7 @@ impl DhtState { fn on_received_message( self: &Arc, - msg: Message, + msg: Message, addr: SocketAddr, ) -> anyhow::Result<()> { let generate_compact_nodes = |target| { @@ -770,8 +770,8 @@ impl DhtState { id: self.id, nodes: Some(compact_node_info), values: Some(compact_peer_info), - token: Some(ByteString( - self.peer_store.gen_token_for(req.id, addr).to_vec(), + token: Some(ByteBufOwned::from( + &self.peer_store.gen_token_for(req.id, addr)[..], )), }), }; @@ -821,15 +821,15 @@ enum Request { FindNode(Id20), Announce { info_hash: Id20, - token: ByteString, + token: ByteBufOwned, port: u16, }, Ping, } enum ResponseOrError { - Response(Response), - Error(ErrorDescription), + Response(Response), + Error(ErrorDescription), } impl core::fmt::Debug for ResponseOrError { @@ -1010,7 +1010,7 @@ impl DhtWorker { &self, socket: &UdpSocket, mut input_rx: UnboundedReceiver, - output_tx: Sender<(Message, SocketAddr)>, + output_tx: Sender<(Message, SocketAddr)>, ) -> anyhow::Result<()> { let writer = async { let mut buf = Vec::new(); @@ -1050,7 +1050,7 @@ impl DhtWorker { .recv_from(&mut buf) .await .context("error reading from UDP socket")?; - match bprotocol::deserialize_message::(&buf[..size]) { + match bprotocol::deserialize_message::(&buf[..size]) { Ok(msg) => match output_tx.send((msg, addr)).await { Ok(_) => {} Err(_) => break, diff --git a/crates/dht/src/peer_store.rs b/crates/dht/src/peer_store.rs index 2a20e3f..8ca8d76 100644 --- a/crates/dht/src/peer_store.rs +++ b/crates/dht/src/peer_store.rs @@ -5,7 +5,7 @@ use std::{ sync::atomic::AtomicU32, }; -use bencode::ByteString; +use bencode::ByteBufOwned; use chrono::{DateTime, Utc}; use librqbit_core::hash_id::Id20; use parking_lot::RwLock; @@ -134,7 +134,7 @@ impl PeerStore { token } - pub fn store_peer(&self, announce: &AnnouncePeer, addr: SocketAddr) -> bool { + pub fn store_peer(&self, announce: &AnnouncePeer, addr: SocketAddr) -> bool { // If the info_hash in announce is too far away from us, don't store it. // If the token doesn't match, don't store it. // If we are out of capacity, don't store it. diff --git a/crates/librqbit/src/api.rs b/crates/librqbit/src/api.rs index 058a490..2538b3b 100644 --- a/crates/librqbit/src/api.rs +++ b/crates/librqbit/src/api.rs @@ -1,7 +1,7 @@ use std::{net::SocketAddr, sync::Arc}; use anyhow::Context; -use buffers::ByteString; +use buffers::ByteBufOwned; use dht::{DhtStats, Id20}; use futures::Stream; use http::StatusCode; @@ -268,7 +268,7 @@ pub struct ApiAddTorrentResponse { fn make_torrent_details( info_hash: &Id20, - info: &TorrentMetaV1Info, + info: &TorrentMetaV1Info, only_files: Option<&[usize]>, ) -> Result { let files = info diff --git a/crates/librqbit/src/chunk_tracker.rs b/crates/librqbit/src/chunk_tracker.rs index dca5b47..7f56b20 100644 --- a/crates/librqbit/src/chunk_tracker.rs +++ b/crates/librqbit/src/chunk_tracker.rs @@ -35,7 +35,7 @@ pub struct ChunkTracker { fn compute_chunk_status(lengths: &Lengths, needed_pieces: &BF) -> BF { let required_size = lengths.chunk_bitfield_bytes(); let vec = vec![0u8; required_size]; - let mut chunk_bf = BF::from_vec(vec); + let mut chunk_bf = BF::from_boxed_slice(vec.into_boxed_slice()); for piece_index in needed_pieces .get(0..lengths.total_pieces() as usize) .unwrap() diff --git a/crates/librqbit/src/create_torrent_file.rs b/crates/librqbit/src/create_torrent_file.rs index fbb9540..1d8f179 100644 --- a/crates/librqbit/src/create_torrent_file.rs +++ b/crates/librqbit/src/create_torrent_file.rs @@ -5,7 +5,7 @@ use std::path::Path; use anyhow::Context; use bencode::bencode_serialize_to_writer; -use buffers::ByteString; +use buffers::ByteBufOwned; use librqbit_core::torrent_metainfo::{TorrentMetaV1File, TorrentMetaV1Info, TorrentMetaV1Owned}; use librqbit_core::Id20; use sha1w::{ISha1, Sha1}; @@ -44,7 +44,7 @@ fn walk_dir_find_paths(dir: &Path, out: &mut Vec>) -> anyhow::Resu Ok(()) } -fn compute_info_hash(t: &TorrentMetaV1Info) -> anyhow::Result { +fn compute_info_hash(t: &TorrentMetaV1Info) -> anyhow::Result { struct W { hash: sha1w::Sha1, } @@ -79,7 +79,7 @@ fn osstr_to_bytes(o: &OsStr) -> Vec { async fn create_torrent_raw<'a>( path: &'a Path, options: CreateTorrentOptions<'a>, -) -> anyhow::Result> { +) -> anyhow::Result> { path.try_exists() .with_context(|| format!("path {:?} doesn't exist", path))?; let basename = path @@ -87,7 +87,7 @@ async fn create_torrent_raw<'a>( .ok_or_else(|| anyhow::anyhow!("cannot determine basename of {:?}", path))?; let is_dir = path.is_dir(); let single_file_mode = !is_dir; - let name: ByteString = match options.name { + let name: ByteBufOwned = match options.name { Some(name) => name.as_bytes().into(), None => osstr_to_bytes(basename).into(), }; @@ -112,7 +112,7 @@ async fn create_torrent_raw<'a>( let mut remaining_piece_length = piece_length; let mut piece_checksum = sha1w::Sha1::new(); let mut piece_hashes = Vec::::new(); - let mut output_files: Vec> = Vec::new(); + let mut output_files: Vec> = Vec::new(); let spawner = BlockingSpawner::default(); @@ -216,7 +216,7 @@ pub async fn create_torrent<'a>( #[cfg(test)] mod tests { - use buffers::ByteBuf; + use buffers::{ByteBuf, ByteBufOwned}; use librqbit_core::torrent_metainfo::torrent_from_bytes; use crate::create_torrent; @@ -238,5 +238,8 @@ mod tests { let deserialized = torrent_from_bytes::(&bytes).unwrap(); assert_eq!(torrent.info_hash(), deserialized.info_hash); + + let deserialized = torrent_from_bytes::(&bytes).unwrap(); + assert_eq!(torrent.info_hash(), deserialized.info_hash); } } diff --git a/crates/librqbit/src/dht_utils.rs b/crates/librqbit/src/dht_utils.rs index 747d1bd..4c2257f 100644 --- a/crates/librqbit/src/dht_utils.rs +++ b/crates/librqbit/src/dht_utils.rs @@ -1,7 +1,7 @@ use std::{collections::HashSet, net::SocketAddr}; use anyhow::Context; -use buffers::ByteString; +use buffers::ByteBufOwned; use futures::{stream::FuturesUnordered, Stream, StreamExt}; use librqbit_core::torrent_metainfo::TorrentMetaV1Info; use tracing::debug; @@ -14,7 +14,7 @@ use librqbit_core::hash_id::Id20; #[derive(Debug)] pub enum ReadMetainfoResult { Found { - info: TorrentMetaV1Info, + info: TorrentMetaV1Info, rx: Rx, seen: HashSet, }, diff --git a/crates/librqbit/src/file_ops.rs b/crates/librqbit/src/file_ops.rs index 6472426..8a2271a 100644 --- a/crates/librqbit/src/file_ops.rs +++ b/crates/librqbit/src/file_ops.rs @@ -9,7 +9,7 @@ use std::{ }; use anyhow::Context; -use buffers::ByteString; +use buffers::ByteBufOwned; use librqbit_core::{ lengths::{ChunkInfo, Lengths, ValidPieceIndex}, torrent_metainfo::{FileIteratorName, TorrentMetaV1Info}, @@ -55,7 +55,7 @@ pub fn update_hash_from_file( } pub(crate) struct FileOps<'a, Sha1> { - torrent: &'a TorrentMetaV1Info, + torrent: &'a TorrentMetaV1Info, files: &'a [Arc>], lengths: &'a Lengths, phantom_data: PhantomData, @@ -63,7 +63,7 @@ pub(crate) struct FileOps<'a, Sha1> { impl<'a, Sha1Impl: ISha1> FileOps<'a, Sha1Impl> { pub fn new( - torrent: &'a TorrentMetaV1Info, + torrent: &'a TorrentMetaV1Info, files: &'a [Arc>], lengths: &'a Lengths, ) -> Self { @@ -80,8 +80,10 @@ impl<'a, Sha1Impl: ISha1> FileOps<'a, Sha1Impl> { only_files: Option<&[usize]>, progress: &AtomicU64, ) -> anyhow::Result { - let mut needed_pieces = BF::from_vec(vec![0u8; self.lengths.piece_bitfield_bytes()]); - let mut have_pieces = BF::from_vec(vec![0u8; self.lengths.piece_bitfield_bytes()]); + let mut needed_pieces = + BF::from_boxed_slice(vec![0u8; self.lengths.piece_bitfield_bytes()].into()); + let mut have_pieces = + BF::from_boxed_slice(vec![0u8; self.lengths.piece_bitfield_bytes()].into()); let mut have_bytes = 0u64; let mut needed_bytes = 0u64; @@ -92,7 +94,7 @@ impl<'a, Sha1Impl: ISha1> FileOps<'a, Sha1Impl> { index: usize, fd: &'a Arc>, len: u64, - name: FileIteratorName<'a, ByteString>, + name: FileIteratorName<'a, ByteBufOwned>, full_file_required: bool, processed_bytes: u64, is_broken: bool, diff --git a/crates/librqbit/src/peer_connection.rs b/crates/librqbit/src/peer_connection.rs index 1ac208d..7994933 100644 --- a/crates/librqbit/src/peer_connection.rs +++ b/crates/librqbit/src/peer_connection.rs @@ -4,7 +4,7 @@ use std::{ }; use anyhow::{bail, Context}; -use buffers::{ByteBuf, ByteString}; +use buffers::{ByteBuf, ByteBufOwned}; use clone_to_owned::CloneToOwned; use librqbit_core::{hash_id::Id20, lengths::ChunkInfo, peer_id::try_decode_peer_id}; use parking_lot::RwLock; @@ -100,7 +100,7 @@ impl PeerConnection { &self, outgoing_chan: tokio::sync::mpsc::UnboundedReceiver, read_buf: ReadBuf, - handshake: Handshake, + handshake: Handshake, mut conn: tokio::net::TcpStream, ) -> anyhow::Result<()> { use tokio::io::AsyncWriteExt; @@ -220,7 +220,7 @@ impl PeerConnection { .read_write_timeout .unwrap_or_else(|| Duration::from_secs(10)); - let extended_handshake: RwLock>> = RwLock::new(None); + let extended_handshake: RwLock>> = RwLock::new(None); let extended_handshake_ref = &extended_handshake; let supports_extended = handshake_supports_extended; diff --git a/crates/librqbit/src/peer_info_reader/mod.rs b/crates/librqbit/src/peer_info_reader/mod.rs index 9cea386..d141f73 100644 --- a/crates/librqbit/src/peer_info_reader/mod.rs +++ b/crates/librqbit/src/peer_info_reader/mod.rs @@ -1,7 +1,7 @@ use std::net::SocketAddr; use bencode::from_bytes; -use buffers::{ByteBuf, ByteString}; +use buffers::{ByteBuf, ByteBufOwned}; use librqbit_core::{ constants::CHUNK_SIZE, hash_id::Id20, @@ -30,9 +30,9 @@ pub(crate) async fn read_metainfo_from_peer( info_hash: Id20, peer_connection_options: Option, spawner: BlockingSpawner, -) -> anyhow::Result> { +) -> anyhow::Result> { let (result_tx, result_rx) = - tokio::sync::oneshot::channel::>>(); + tokio::sync::oneshot::channel::>>(); let (writer_tx, writer_rx) = tokio::sync::mpsc::unbounded_channel::(); let handler = Handler { addr, @@ -131,8 +131,9 @@ struct Handler { addr: SocketAddr, info_hash: Id20, writer_tx: UnboundedSender, - result_tx: - Mutex>>>>, + result_tx: Mutex< + Option>>>, + >, locked: RwLock>, } @@ -169,7 +170,7 @@ impl PeerConnectionHandler for Handler { .record_piece(piece, &data, self.info_hash)?; if piece_ready { let buf = self.locked.write().take().unwrap().buffer; - let info = from_bytes::>(&buf); + let info = from_bytes::>(&buf); self.result_tx .lock() .take() diff --git a/crates/librqbit/src/session.rs b/crates/librqbit/src/session.rs index 010376e..101a6d4 100644 --- a/crates/librqbit/src/session.rs +++ b/crates/librqbit/src/session.rs @@ -21,7 +21,7 @@ use crate::{ }; use anyhow::{bail, Context}; use bencode::{bencode_serialize_to_writer, BencodeDeserializer}; -use buffers::{ByteBuf, ByteBufT, ByteString}; +use buffers::{ByteBuf, ByteBufOwned, ByteBufT}; use clone_to_owned::CloneToOwned; use dht::{Dht, DhtBuilder, DhtConfig, Id20, PersistentDht, PersistentDhtConfig}; use futures::{ @@ -126,14 +126,17 @@ struct SerializedTorrent { serialize_with = "serialize_torrent", deserialize_with = "deserialize_torrent" )] - info: TorrentMetaV1Info, + info: TorrentMetaV1Info, trackers: HashSet, output_folder: PathBuf, only_files: Option>, is_paused: bool, } -fn serialize_torrent(t: &TorrentMetaV1Info, serializer: S) -> Result +fn serialize_torrent( + t: &TorrentMetaV1Info, + serializer: S, +) -> Result where S: Serializer, { @@ -145,7 +148,7 @@ where s.serialize(serializer) } -fn deserialize_torrent<'de, D>(deserializer: D) -> Result, D::Error> +fn deserialize_torrent<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { @@ -155,7 +158,7 @@ where let b = general_purpose::STANDARD_NO_PAD .decode(s) .map_err(D::Error::custom)?; - TorrentMetaV1Info::::deserialize(&mut BencodeDeserializer::new_from_buf(&b)) + TorrentMetaV1Info::::deserialize(&mut BencodeDeserializer::new_from_buf(&b)) .map_err(D::Error::custom) } @@ -216,7 +219,7 @@ fn compute_only_files_regex>( } fn compute_only_files( - info: &TorrentMetaV1Info, + info: &TorrentMetaV1Info, only_files: Option>, only_files_regex: Option, list_only: bool, @@ -303,7 +306,7 @@ pub struct AddTorrentOptions { pub struct ListOnlyResponse { pub info_hash: Id20, - pub info: TorrentMetaV1Info, + pub info: TorrentMetaV1Info, pub only_files: Option>, pub output_folder: PathBuf, pub seen_peers: Vec, @@ -426,7 +429,7 @@ pub(crate) struct CheckedIncomingConnection { pub addr: SocketAddr, pub stream: tokio::net::TcpStream, pub read_buf: ReadBuf, - pub handshake: Handshake, + pub handshake: Handshake, } impl Session { @@ -715,10 +718,10 @@ impl Session { serde_json::from_reader(&mut rdr).context("error deserializing session database")?; let mut futures = Vec::new(); for (id, storrent) in db.torrents.into_iter() { - let trackers: Vec = storrent + let trackers: Vec = storrent .trackers .into_iter() - .map(|t| ByteString(t.into_bytes())) + .map(|t| ByteBufOwned::from(t.into_bytes())) .collect(); let info = TorrentMetaV1Owned { announce: trackers.first().cloned(), @@ -929,7 +932,7 @@ impl Session { fn get_default_subfolder_for_torrent( &self, - info: &TorrentMetaV1Info, + info: &TorrentMetaV1Info, ) -> anyhow::Result> { let files = info .iter_filenames_and_lengths()? @@ -957,7 +960,7 @@ impl Session { async fn main_torrent_info( &self, info_hash: Id20, - info: TorrentMetaV1Info, + info: TorrentMetaV1Info, trackers: Vec, peer_rx: Option, initial_peers: Vec, diff --git a/crates/librqbit/src/torrent_state/live/mod.rs b/crates/librqbit/src/torrent_state/live/mod.rs index 3de7f0c..c0a8ece 100644 --- a/crates/librqbit/src/torrent_state/live/mod.rs +++ b/crates/librqbit/src/torrent_state/live/mod.rs @@ -57,7 +57,7 @@ use std::{ use anyhow::{bail, Context}; use backoff::backoff::Backoff; -use buffers::{ByteBuf, ByteString}; +use buffers::{ByteBuf, ByteBufOwned}; use clone_to_owned::CloneToOwned; use futures::{stream::FuturesUnordered, StreamExt}; use itertools::Itertools; @@ -130,7 +130,7 @@ fn dummy_file() -> anyhow::Result { } fn make_piece_bitfield(lengths: &Lengths) -> BF { - BF::from_vec(vec![0; lengths.piece_bitfield_bytes()]) + BF::from_boxed_slice(vec![0; lengths.piece_bitfield_bytes()].into_boxed_slice()) } pub(crate) struct TorrentStateLocked { @@ -485,7 +485,7 @@ impl TorrentStateLive { &self.meta } - pub fn info(&self) -> &TorrentMetaV1Info { + pub fn info(&self) -> &TorrentMetaV1Info { &self.meta.info } pub fn info_hash(&self) -> Id20 { @@ -1047,7 +1047,7 @@ impl PeerHandler { self.on_bitfield_notify.notify_waiters(); } - fn on_bitfield(&self, bitfield: ByteString) -> anyhow::Result<()> { + fn on_bitfield(&self, bitfield: ByteBufOwned) -> anyhow::Result<()> { if bitfield.len() != self.state.lengths.piece_bitfield_bytes() { anyhow::bail!( "dropping peer as its bitfield has unexpected size. Got {}, expected {}", diff --git a/crates/librqbit/src/torrent_state/live/peer/mod.rs b/crates/librqbit/src/torrent_state/live/peer/mod.rs index 014c975..34c0448 100644 --- a/crates/librqbit/src/torrent_state/live/peer/mod.rs +++ b/crates/librqbit/src/torrent_state/live/peer/mod.rs @@ -198,7 +198,7 @@ impl LivePeerState { LivePeerState { peer_id, peer_interested: false, - bitfield: BF::new(), + bitfield: BF::default(), inflight_requests: Default::default(), tx, } diff --git a/crates/librqbit/src/torrent_state/live/peers/mod.rs b/crates/librqbit/src/torrent_state/live/peers/mod.rs index 2e4b4af..f290986 100644 --- a/crates/librqbit/src/torrent_state/live/peers/mod.rs +++ b/crates/librqbit/src/torrent_state/live/peers/mod.rs @@ -81,9 +81,9 @@ impl PeerStates { prev }) } - pub fn update_bitfield_from_vec(&self, handle: PeerHandle, bitfield: Vec) -> Option<()> { + pub fn update_bitfield_from_vec(&self, handle: PeerHandle, bitfield: Box<[u8]>) -> Option<()> { self.with_live_mut(handle, "update_bitfield_from_vec", |live| { - live.bitfield = BF::from_vec(bitfield); + live.bitfield = BF::from_boxed_slice(bitfield); }) } pub fn mark_peer_connecting(&self, h: PeerHandle) -> anyhow::Result<(PeerRx, PeerTx)> { diff --git a/crates/librqbit/src/torrent_state/mod.rs b/crates/librqbit/src/torrent_state/mod.rs index 4a51778..a01a7f4 100644 --- a/crates/librqbit/src/torrent_state/mod.rs +++ b/crates/librqbit/src/torrent_state/mod.rs @@ -13,7 +13,7 @@ use std::time::Duration; use anyhow::bail; use anyhow::Context; -use buffers::ByteString; +use buffers::ByteBufOwned; use futures::future::BoxFuture; use futures::FutureExt; use librqbit_core::hash_id::Id20; @@ -78,7 +78,7 @@ pub(crate) struct ManagedTorrentOptions { } pub struct ManagedTorrentInfo { - pub info: TorrentMetaV1Info, + pub info: TorrentMetaV1Info, pub info_hash: Id20, pub out_dir: PathBuf, pub(crate) spawner: BlockingSpawner, @@ -410,7 +410,7 @@ impl ManagedTorrent { } pub struct ManagedTorrentBuilder { - info: TorrentMetaV1Info, + info: TorrentMetaV1Info, info_hash: Id20, output_folder: PathBuf, force_tracker_interval: Option, @@ -425,7 +425,7 @@ pub struct ManagedTorrentBuilder { impl ManagedTorrentBuilder { pub fn new>( - info: TorrentMetaV1Info, + info: TorrentMetaV1Info, info_hash: Id20, output_folder: P, ) -> Self { diff --git a/crates/librqbit/src/type_aliases.rs b/crates/librqbit/src/type_aliases.rs index e163fbe..4d5bda6 100644 --- a/crates/librqbit/src/type_aliases.rs +++ b/crates/librqbit/src/type_aliases.rs @@ -2,7 +2,7 @@ use std::net::SocketAddr; use futures::stream::BoxStream; -pub type BF = bitvec::vec::BitVec; +pub type BF = bitvec::boxed::BitBox; pub type PeerHandle = SocketAddr; pub type PeerStream = BoxStream<'static, SocketAddr>; diff --git a/crates/librqbit_core/Cargo.toml b/crates/librqbit_core/Cargo.toml index 9a960f4..6d256f7 100644 --- a/crates/librqbit_core/Cargo.toml +++ b/crates/librqbit_core/Cargo.toml @@ -18,16 +18,16 @@ sha1-rust = ["bencode/sha1-rust"] [dependencies] tracing = "0.1.40" -tokio = {version = "1", features = ["rt-multi-thread", "macros", "time"]} +tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] } hex = "0.4" anyhow = "1" url = "2" -uuid = {version = "1", features = ["v4"]} +uuid = { version = "1", features = ["v4"] } parking_lot = "0.12" -serde = {version = "1", features=["derive"]} -buffers = {path="../buffers", package="librqbit-buffers", version = "2.2.1"} -bencode = {path = "../bencode", default-features=false, package="librqbit-bencode", version="2.2.1"} -clone_to_owned = {path="../clone_to_owned", package="librqbit-clone-to-owned", version = "2.2.1"} +serde = { version = "1", features = ["derive"] } +buffers = { path = "../buffers", package = "librqbit-buffers", version = "2.2.1" } +bencode = { path = "../bencode", default-features = false, package = "librqbit-bencode", version = "2.2.2" } +clone_to_owned = { path = "../clone_to_owned", package = "librqbit-clone-to-owned", version = "2.2.1" } itertools = "0.12" directories = "5" tokio-util = "0.7.10" diff --git a/crates/librqbit_core/src/torrent_metainfo.rs b/crates/librqbit_core/src/torrent_metainfo.rs index 0ec98c8..545e7b8 100644 --- a/crates/librqbit_core/src/torrent_metainfo.rs +++ b/crates/librqbit_core/src/torrent_metainfo.rs @@ -2,7 +2,7 @@ use std::{iter::once, path::PathBuf}; use anyhow::Context; use bencode::BencodeDeserializer; -use buffers::{ByteBuf, ByteString}; +use buffers::{ByteBuf, ByteBufOwned}; use clone_to_owned::CloneToOwned; use itertools::Either; use serde::{Deserialize, Serialize}; @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use crate::hash_id::Id20; pub type TorrentMetaV1Borrowed<'a> = TorrentMetaV1>; -pub type TorrentMetaV1Owned = TorrentMetaV1; +pub type TorrentMetaV1Owned = TorrentMetaV1; /// Parse torrent metainfo from bytes. pub fn torrent_from_bytes<'de, ByteBuf: Deserialize<'de>>( diff --git a/crates/peer_binary_protocol/src/lib.rs b/crates/peer_binary_protocol/src/lib.rs index 2a5f09b..402bbc1 100644 --- a/crates/peer_binary_protocol/src/lib.rs +++ b/crates/peer_binary_protocol/src/lib.rs @@ -5,7 +5,7 @@ pub mod extended; use bincode::Options; -use buffers::{ByteBuf, ByteString}; +use buffers::{ByteBuf, ByteBufOwned}; use byteorder::{ByteOrder, BE}; use clone_to_owned::CloneToOwned; use librqbit_core::{constants::CHUNK_SIZE, hash_id::Id20, lengths::ChunkInfo}; @@ -183,7 +183,7 @@ pub enum Message { } pub type MessageBorrowed<'a> = Message>; -pub type MessageOwned = Message; +pub type MessageOwned = Message; pub type BitfieldBorrowed<'a> = &'a bitvec::slice::BitSlice; pub type BitfieldOwned = bitvec::vec::BitVec;