mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-04-01 18:25:30 +00:00
Merge pull request #88 from greatest-ape/work-2022-08-06
Use regular IndexMap for PeerMap; replace PeerStatus with is_seeder bool in udp
This commit is contained in:
commit
1097a9d068
8 changed files with 65 additions and 39 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -68,6 +68,7 @@ dependencies = [
|
||||||
"hashbrown 0.12.3",
|
"hashbrown 0.12.3",
|
||||||
"hex",
|
"hex",
|
||||||
"hwloc",
|
"hwloc",
|
||||||
|
"indexmap",
|
||||||
"indexmap-amortized",
|
"indexmap-amortized",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ duplicate = "0.4"
|
||||||
git-testament = "0.2"
|
git-testament = "0.2"
|
||||||
hashbrown = "0.12"
|
hashbrown = "0.12"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
|
indexmap = "1"
|
||||||
indexmap-amortized = "1"
|
indexmap-amortized = "1"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ pub mod privileges;
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "rustls")]
|
||||||
pub mod rustls_config;
|
pub mod rustls_config;
|
||||||
|
|
||||||
|
/// IndexMap using AHash hasher
|
||||||
|
pub type IndexMap<K, V> = indexmap::IndexMap<K, V, RandomState>;
|
||||||
|
|
||||||
/// Amortized IndexMap using AHash hasher
|
/// Amortized IndexMap using AHash hasher
|
||||||
pub type AmortizedIndexMap<K, V> = indexmap_amortized::IndexMap<K, V, RandomState>;
|
pub type AmortizedIndexMap<K, V> = indexmap_amortized::IndexMap<K, V, RandomState>;
|
||||||
|
|
||||||
|
|
@ -104,7 +107,7 @@ impl Drop for PanicSentinel {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn extract_response_peers<K, V, R, F>(
|
pub fn extract_response_peers<K, V, R, F>(
|
||||||
rng: &mut impl Rng,
|
rng: &mut impl Rng,
|
||||||
peer_map: &AmortizedIndexMap<K, V>,
|
peer_map: &IndexMap<K, V>,
|
||||||
max_num_peers_to_take: usize,
|
max_num_peers_to_take: usize,
|
||||||
sender_peer_map_key: K,
|
sender_peer_map_key: K,
|
||||||
peer_conversion_function: F,
|
peer_conversion_function: F,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use rand::SeedableRng;
|
||||||
use smartstring::{LazyCompact, SmartString};
|
use smartstring::{LazyCompact, SmartString};
|
||||||
|
|
||||||
use aquatic_common::access_list::{create_access_list_cache, AccessListArcSwap, AccessListCache};
|
use aquatic_common::access_list::{create_access_list_cache, AccessListArcSwap, AccessListCache};
|
||||||
use aquatic_common::{extract_response_peers, PanicSentinel};
|
use aquatic_common::{extract_response_peers, IndexMap, PanicSentinel};
|
||||||
use aquatic_common::{AmortizedIndexMap, CanonicalSocketAddr};
|
use aquatic_common::{AmortizedIndexMap, CanonicalSocketAddr};
|
||||||
use aquatic_common::{SecondsSinceServerStart, ServerStartInstant, ValidUntil};
|
use aquatic_common::{SecondsSinceServerStart, ServerStartInstant, ValidUntil};
|
||||||
use aquatic_http_protocol::common::*;
|
use aquatic_http_protocol::common::*;
|
||||||
|
|
@ -78,7 +78,7 @@ pub struct PeerMapKey<I: Ip> {
|
||||||
pub ip_or_key: Either<I, SmartString<LazyCompact>>,
|
pub ip_or_key: Either<I, SmartString<LazyCompact>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PeerMap<I> = AmortizedIndexMap<PeerMapKey<I>, Peer<I>>;
|
pub type PeerMap<I> = IndexMap<PeerMapKey<I>, Peer<I>>;
|
||||||
|
|
||||||
pub struct TorrentData<I: Ip> {
|
pub struct TorrentData<I: Ip> {
|
||||||
pub peers: PeerMap<I>,
|
pub peers: PeerMap<I>,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
|
|
||||||
use aquatic_common::{AmortizedIndexMap, SecondsSinceServerStart, ServerStartInstant, ValidUntil};
|
use aquatic_common::{
|
||||||
|
AmortizedIndexMap, IndexMap, SecondsSinceServerStart, ServerStartInstant, ValidUntil,
|
||||||
|
};
|
||||||
use aquatic_http_protocol::common::{AnnounceEvent, InfoHash, PeerId};
|
use aquatic_http_protocol::common::{AnnounceEvent, InfoHash, PeerId};
|
||||||
use aquatic_http_protocol::response::ResponsePeer;
|
use aquatic_http_protocol::response::ResponsePeer;
|
||||||
|
|
||||||
|
|
@ -55,7 +57,7 @@ pub struct PeerMapKey<I: Ip> {
|
||||||
pub ip_address: I,
|
pub ip_address: I,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PeerMap<I> = AmortizedIndexMap<PeerMapKey<I>, Peer<I>>;
|
pub type PeerMap<I> = IndexMap<PeerMapKey<I>, Peer<I>>;
|
||||||
|
|
||||||
pub struct TorrentData<I: Ip> {
|
pub struct TorrentData<I: Ip> {
|
||||||
pub peers: PeerMap<I>,
|
pub peers: PeerMap<I>,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use aquatic_udp_protocol::*;
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
|
||||||
use storage::{Peer, TorrentMap, TorrentMaps};
|
use storage::{TorrentMap, TorrentMaps};
|
||||||
|
|
||||||
pub fn run_swarm_worker(
|
pub fn run_swarm_worker(
|
||||||
_sentinel: PanicSentinel,
|
_sentinel: PanicSentinel,
|
||||||
|
|
@ -145,16 +145,17 @@ fn handle_announce_request<I: Ip>(
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let peer = Peer {
|
|
||||||
ip_address: peer_ip,
|
|
||||||
port: request.port,
|
|
||||||
status: PeerStatus::from_event_and_bytes_left(request.event, request.bytes_left),
|
|
||||||
valid_until: peer_valid_until,
|
|
||||||
};
|
|
||||||
|
|
||||||
let torrent_data = torrents.0.entry(request.info_hash).or_default();
|
let torrent_data = torrents.0.entry(request.info_hash).or_default();
|
||||||
|
|
||||||
torrent_data.update_peer(request.peer_id, peer);
|
let peer_status = PeerStatus::from_event_and_bytes_left(request.event, request.bytes_left);
|
||||||
|
|
||||||
|
torrent_data.update_peer(
|
||||||
|
request.peer_id,
|
||||||
|
peer_ip,
|
||||||
|
request.port,
|
||||||
|
peer_status,
|
||||||
|
peer_valid_until,
|
||||||
|
);
|
||||||
|
|
||||||
let response_peers =
|
let response_peers =
|
||||||
torrent_data.extract_response_peers(rng, request.peer_id, max_num_peers_to_take);
|
torrent_data.extract_response_peers(rng, request.peer_id, max_num_peers_to_take);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use std::net::Ipv4Addr;
|
||||||
use std::net::Ipv6Addr;
|
use std::net::Ipv6Addr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use aquatic_common::IndexMap;
|
||||||
use aquatic_common::SecondsSinceServerStart;
|
use aquatic_common::SecondsSinceServerStart;
|
||||||
use aquatic_common::ServerStartInstant;
|
use aquatic_common::ServerStartInstant;
|
||||||
use aquatic_common::{
|
use aquatic_common::{
|
||||||
|
|
@ -19,15 +20,15 @@ use crate::config::Config;
|
||||||
use super::create_torrent_scrape_statistics;
|
use super::create_torrent_scrape_statistics;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Peer<I: Ip> {
|
struct Peer<I: Ip> {
|
||||||
pub ip_address: I,
|
ip_address: I,
|
||||||
pub port: Port,
|
port: Port,
|
||||||
pub status: PeerStatus,
|
is_seeder: bool,
|
||||||
pub valid_until: ValidUntil,
|
valid_until: ValidUntil,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Ip> Peer<I> {
|
impl<I: Ip> Peer<I> {
|
||||||
pub fn to_response_peer(&self) -> ResponsePeer<I> {
|
fn to_response_peer(&self) -> ResponsePeer<I> {
|
||||||
ResponsePeer {
|
ResponsePeer {
|
||||||
ip_address: self.ip_address,
|
ip_address: self.ip_address,
|
||||||
port: self.port,
|
port: self.port,
|
||||||
|
|
@ -35,7 +36,7 @@ impl<I: Ip> Peer<I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PeerMap<I> = AmortizedIndexMap<PeerId, Peer<I>>;
|
type PeerMap<I> = IndexMap<PeerId, Peer<I>>;
|
||||||
|
|
||||||
pub struct TorrentData<I: Ip> {
|
pub struct TorrentData<I: Ip> {
|
||||||
peers: PeerMap<I>,
|
peers: PeerMap<I>,
|
||||||
|
|
@ -44,14 +45,35 @@ pub struct TorrentData<I: Ip> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Ip> TorrentData<I> {
|
impl<I: Ip> TorrentData<I> {
|
||||||
pub fn update_peer(&mut self, peer_id: PeerId, peer: Peer<I>) {
|
pub fn update_peer(
|
||||||
let opt_removed_peer = match peer.status {
|
&mut self,
|
||||||
|
peer_id: PeerId,
|
||||||
|
ip_address: I,
|
||||||
|
port: Port,
|
||||||
|
status: PeerStatus,
|
||||||
|
valid_until: ValidUntil,
|
||||||
|
) {
|
||||||
|
let opt_removed_peer = match status {
|
||||||
PeerStatus::Leeching => {
|
PeerStatus::Leeching => {
|
||||||
|
let peer = Peer {
|
||||||
|
ip_address,
|
||||||
|
port,
|
||||||
|
is_seeder: false,
|
||||||
|
valid_until,
|
||||||
|
};
|
||||||
|
|
||||||
self.num_leechers += 1;
|
self.num_leechers += 1;
|
||||||
|
|
||||||
self.peers.insert(peer_id, peer)
|
self.peers.insert(peer_id, peer)
|
||||||
}
|
}
|
||||||
PeerStatus::Seeding => {
|
PeerStatus::Seeding => {
|
||||||
|
let peer = Peer {
|
||||||
|
ip_address,
|
||||||
|
port,
|
||||||
|
is_seeder: true,
|
||||||
|
valid_until,
|
||||||
|
};
|
||||||
|
|
||||||
self.num_seeders += 1;
|
self.num_seeders += 1;
|
||||||
|
|
||||||
self.peers.insert(peer_id, peer)
|
self.peers.insert(peer_id, peer)
|
||||||
|
|
@ -59,14 +81,14 @@ impl<I: Ip> TorrentData<I> {
|
||||||
PeerStatus::Stopped => self.peers.remove(&peer_id),
|
PeerStatus::Stopped => self.peers.remove(&peer_id),
|
||||||
};
|
};
|
||||||
|
|
||||||
match opt_removed_peer.map(|peer| peer.status) {
|
match opt_removed_peer.map(|peer| peer.is_seeder) {
|
||||||
Some(PeerStatus::Leeching) => {
|
Some(true) => {
|
||||||
self.num_leechers -= 1;
|
self.num_leechers -= 1;
|
||||||
}
|
}
|
||||||
Some(PeerStatus::Seeding) => {
|
Some(false) => {
|
||||||
self.num_seeders -= 1;
|
self.num_seeders -= 1;
|
||||||
}
|
}
|
||||||
_ => {}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,15 +128,11 @@ impl<I: Ip> TorrentData<I> {
|
||||||
if peer.valid_until.valid(now) {
|
if peer.valid_until.valid(now) {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
match peer.status {
|
if peer.is_seeder {
|
||||||
PeerStatus::Seeding => {
|
self.num_seeders -= 1;
|
||||||
self.num_seeders -= 1;
|
} else {
|
||||||
}
|
self.num_leechers -= 1;
|
||||||
PeerStatus::Leeching => {
|
}
|
||||||
self.num_leechers -= 1;
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
@ -264,7 +282,7 @@ mod tests {
|
||||||
Peer {
|
Peer {
|
||||||
ip_address: Ipv4Addr::from(i.to_be_bytes()),
|
ip_address: Ipv4Addr::from(i.to_be_bytes()),
|
||||||
port: Port(1),
|
port: Port(1),
|
||||||
status: PeerStatus::Leeching,
|
is_seeder: false,
|
||||||
valid_until: ValidUntil::new(ServerStartInstant::new(), 0),
|
valid_until: ValidUntil::new(ServerStartInstant::new(), 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use hashbrown::HashMap;
|
||||||
use rand::{rngs::SmallRng, SeedableRng};
|
use rand::{rngs::SmallRng, SeedableRng};
|
||||||
|
|
||||||
use aquatic_common::{
|
use aquatic_common::{
|
||||||
extract_response_peers, AmortizedIndexMap, PanicSentinel, SecondsSinceServerStart,
|
extract_response_peers, AmortizedIndexMap, IndexMap, PanicSentinel, SecondsSinceServerStart,
|
||||||
ServerStartInstant,
|
ServerStartInstant,
|
||||||
};
|
};
|
||||||
use aquatic_ws_protocol::*;
|
use aquatic_ws_protocol::*;
|
||||||
|
|
@ -53,7 +53,7 @@ struct Peer {
|
||||||
pub valid_until: ValidUntil,
|
pub valid_until: ValidUntil,
|
||||||
}
|
}
|
||||||
|
|
||||||
type PeerMap = AmortizedIndexMap<PeerId, Peer>;
|
type PeerMap = IndexMap<PeerId, Peer>;
|
||||||
|
|
||||||
struct TorrentData {
|
struct TorrentData {
|
||||||
pub peers: PeerMap,
|
pub peers: PeerMap,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue