Store torrent bytes in memory

This commit is contained in:
Igor Katson 2024-08-12 23:43:23 +01:00
parent 41a2cd58b3
commit fe7a1e09ba
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
2 changed files with 45 additions and 2 deletions

View file

@ -119,6 +119,7 @@ impl SessionDatabase {
.map(|u| u.to_string()) .map(|u| u.to_string())
.collect(), .collect(),
info_hash: torrent.info_hash().as_string(), info_hash: torrent.info_hash().as_string(),
torrent_bytes: torrent.info.torrent_bytes.clone(),
info: torrent.info().info.clone(), info: torrent.info().info.clone(),
only_files: torrent.only_files().clone(), only_files: torrent.only_files().clone(),
is_paused: torrent is_paused: torrent
@ -140,6 +141,12 @@ struct SerializedTorrent {
deserialize_with = "deserialize_torrent" deserialize_with = "deserialize_torrent"
)] )]
info: TorrentMetaV1Info<ByteBufOwned>, info: TorrentMetaV1Info<ByteBufOwned>,
#[serde(
serialize_with = "serialize_torrent_bytes",
deserialize_with = "deserialize_torrent_bytes",
default = "empty_bytes"
)]
torrent_bytes: ByteBufOwned,
trackers: HashSet<String>, trackers: HashSet<String>,
output_folder: PathBuf, output_folder: PathBuf,
only_files: Option<Vec<usize>>, only_files: Option<Vec<usize>>,
@ -175,6 +182,32 @@ where
.map_err(D::Error::custom) .map_err(D::Error::custom)
} }
fn serialize_torrent_bytes<S>(t: &ByteBufOwned, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use base64::{engine::general_purpose, Engine as _};
let s = general_purpose::STANDARD_NO_PAD.encode(&t.0);
s.serialize(serializer)
}
fn deserialize_torrent_bytes<'de, D>(deserializer: D) -> Result<ByteBufOwned, D::Error>
where
D: Deserializer<'de>,
{
use base64::{engine::general_purpose, Engine as _};
use serde::de::Error;
let s = String::deserialize(deserializer)?;
let b = general_purpose::STANDARD_NO_PAD
.decode(s)
.map_err(D::Error::custom)?;
Ok(b.into())
}
fn empty_bytes() -> ByteBufOwned {
ByteBufOwned(Vec::new().into_boxed_slice())
}
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct SerializedSessionDatabase { struct SerializedSessionDatabase {
torrents: HashMap<usize, SerializedTorrent>, torrents: HashMap<usize, SerializedTorrent>,
@ -1128,8 +1161,13 @@ impl Session {
})); }));
} }
let mut builder = let mut builder = ManagedTorrentBuilder::new(
ManagedTorrentBuilder::new(info, info_hash, output_folder, storage_factory); info,
info_hash,
torrent_bytes,
output_folder,
storage_factory,
);
builder builder
.allow_overwrite(opts.overwrite) .allow_overwrite(opts.overwrite)
.spawner(self.spawner) .spawner(self.spawner)

View file

@ -99,6 +99,7 @@ pub(crate) struct ManagedTorrentOptions {
pub struct ManagedTorrentInfo { pub struct ManagedTorrentInfo {
pub info: TorrentMetaV1Info<ByteBufOwned>, pub info: TorrentMetaV1Info<ByteBufOwned>,
pub torrent_bytes: ByteBufOwned,
pub info_hash: Id20, pub info_hash: Id20,
pub(crate) spawner: BlockingSpawner, pub(crate) spawner: BlockingSpawner,
pub trackers: HashSet<String>, pub trackers: HashSet<String>,
@ -501,6 +502,7 @@ pub(crate) struct ManagedTorrentBuilder {
info: TorrentMetaV1Info<ByteBufOwned>, info: TorrentMetaV1Info<ByteBufOwned>,
output_folder: PathBuf, output_folder: PathBuf,
info_hash: Id20, info_hash: Id20,
torrent_bytes: ByteBufOwned,
force_tracker_interval: Option<Duration>, force_tracker_interval: Option<Duration>,
peer_connect_timeout: Option<Duration>, peer_connect_timeout: Option<Duration>,
peer_read_write_timeout: Option<Duration>, peer_read_write_timeout: Option<Duration>,
@ -518,12 +520,14 @@ impl ManagedTorrentBuilder {
pub fn new( pub fn new(
info: TorrentMetaV1Info<ByteBufOwned>, info: TorrentMetaV1Info<ByteBufOwned>,
info_hash: Id20, info_hash: Id20,
torrent_bytes: ByteBufOwned,
output_folder: PathBuf, output_folder: PathBuf,
storage_factory: BoxStorageFactory, storage_factory: BoxStorageFactory,
) -> Self { ) -> Self {
Self { Self {
info, info,
info_hash, info_hash,
torrent_bytes,
spawner: None, spawner: None,
force_tracker_interval: None, force_tracker_interval: None,
peer_connect_timeout: None, peer_connect_timeout: None,
@ -608,6 +612,7 @@ impl ManagedTorrentBuilder {
span, span,
file_infos, file_infos,
info: self.info, info: self.info,
torrent_bytes: self.torrent_bytes,
info_hash: self.info_hash, info_hash: self.info_hash,
trackers: self.trackers.into_iter().collect(), trackers: self.trackers.into_iter().collect(),
spawner: self.spawner.unwrap_or_default(), spawner: self.spawner.unwrap_or_default(),