Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 15df3ee

Browse files
committedApr 16, 2024··
feat: new torrent repo implementation using parking_lot Mutex
1 parent 0fa396c commit 15df3ee

File tree

10 files changed

+240
-28
lines changed

10 files changed

+240
-28
lines changed
 

‎packages/torrent-repository/benches/repository_benchmark.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ mod helpers;
55
use criterion::{criterion_group, criterion_main, Criterion};
66
use torrust_tracker_torrent_repository::{
77
TorrentsDashMapMutexStd, TorrentsRwLockStd, TorrentsRwLockStdMutexStd, TorrentsRwLockStdMutexTokio, TorrentsRwLockTokio,
8-
TorrentsRwLockTokioMutexStd, TorrentsRwLockTokioMutexTokio, TorrentsSkipMapMutexStd, TorrentsSkipMapRwLockParkingLot,
8+
TorrentsRwLockTokioMutexStd, TorrentsRwLockTokioMutexTokio, TorrentsSkipMapMutexParkingLot, TorrentsSkipMapMutexStd,
9+
TorrentsSkipMapRwLockParkingLot,
910
};
1011

1112
use crate::helpers::{asyn, sync};
@@ -49,6 +50,10 @@ fn add_one_torrent(c: &mut Criterion) {
4950
b.iter_custom(sync::add_one_torrent::<TorrentsSkipMapMutexStd, _>);
5051
});
5152

53+
group.bench_function("SkipMapMutexParkingLot", |b| {
54+
b.iter_custom(sync::add_one_torrent::<TorrentsSkipMapMutexParkingLot, _>);
55+
});
56+
5257
group.bench_function("SkipMapRwLockParkingLot", |b| {
5358
b.iter_custom(sync::add_one_torrent::<TorrentsSkipMapRwLockParkingLot, _>);
5459
});
@@ -106,6 +111,11 @@ fn add_multiple_torrents_in_parallel(c: &mut Criterion) {
106111
.iter_custom(|iters| sync::add_multiple_torrents_in_parallel::<TorrentsSkipMapMutexStd, _>(&rt, iters, None));
107112
});
108113

114+
group.bench_function("SkipMapMutexParkingLot", |b| {
115+
b.to_async(&rt)
116+
.iter_custom(|iters| sync::add_multiple_torrents_in_parallel::<TorrentsSkipMapMutexParkingLot, _>(&rt, iters, None));
117+
});
118+
109119
group.bench_function("SkipMapRwLockParkingLot", |b| {
110120
b.to_async(&rt)
111121
.iter_custom(|iters| sync::add_multiple_torrents_in_parallel::<TorrentsSkipMapRwLockParkingLot, _>(&rt, iters, None));
@@ -165,6 +175,11 @@ fn update_one_torrent_in_parallel(c: &mut Criterion) {
165175
.iter_custom(|iters| sync::update_one_torrent_in_parallel::<TorrentsSkipMapMutexStd, _>(&rt, iters, None));
166176
});
167177

178+
group.bench_function("SkipMapMutexParkingLot", |b| {
179+
b.to_async(&rt)
180+
.iter_custom(|iters| sync::update_one_torrent_in_parallel::<TorrentsSkipMapMutexParkingLot, _>(&rt, iters, None));
181+
});
182+
168183
group.bench_function("SkipMapRwLockParkingLot", |b| {
169184
b.to_async(&rt)
170185
.iter_custom(|iters| sync::update_one_torrent_in_parallel::<TorrentsSkipMapRwLockParkingLot, _>(&rt, iters, None));
@@ -225,6 +240,12 @@ fn update_multiple_torrents_in_parallel(c: &mut Criterion) {
225240
.iter_custom(|iters| sync::update_multiple_torrents_in_parallel::<TorrentsSkipMapMutexStd, _>(&rt, iters, None));
226241
});
227242

243+
group.bench_function("SkipMapMutexParkingLot", |b| {
244+
b.to_async(&rt).iter_custom(|iters| {
245+
sync::update_multiple_torrents_in_parallel::<TorrentsSkipMapMutexParkingLot, _>(&rt, iters, None)
246+
});
247+
});
248+
228249
group.bench_function("SkipMapRwLockParkingLot", |b| {
229250
b.to_async(&rt).iter_custom(|iters| {
230251
sync::update_multiple_torrents_in_parallel::<TorrentsSkipMapRwLockParkingLot, _>(&rt, iters, None)

‎packages/torrent-repository/src/entry/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub mod mutex_parking_lot;
1212
pub mod mutex_std;
1313
pub mod mutex_tokio;
1414
pub mod peer_list;
15+
pub mod rw_lock_parking_lot;
1516
pub mod single;
1617

1718
pub trait Entry {

‎packages/torrent-repository/src/entry/mutex_parking_lot.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,44 @@ use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
66
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};
77

88
use super::{Entry, EntrySync};
9-
use crate::{EntryRwLockParkingLot, EntrySingle};
9+
use crate::{EntryMutexParkingLot, EntrySingle};
1010

11-
impl EntrySync for EntryRwLockParkingLot {
11+
impl EntrySync for EntryMutexParkingLot {
1212
fn get_swarm_metadata(&self) -> SwarmMetadata {
13-
self.read().get_swarm_metadata()
13+
self.lock().get_swarm_metadata()
1414
}
1515

1616
fn is_good(&self, policy: &TrackerPolicy) -> bool {
17-
self.read().is_good(policy)
17+
self.lock().is_good(policy)
1818
}
1919

2020
fn peers_is_empty(&self) -> bool {
21-
self.read().peers_is_empty()
21+
self.lock().peers_is_empty()
2222
}
2323

2424
fn get_peers_len(&self) -> usize {
25-
self.read().get_peers_len()
25+
self.lock().get_peers_len()
2626
}
2727

2828
fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
29-
self.read().get_peers(limit)
29+
self.lock().get_peers(limit)
3030
}
3131

3232
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
33-
self.read().get_peers_for_client(client, limit)
33+
self.lock().get_peers_for_client(client, limit)
3434
}
3535

3636
fn upsert_peer(&self, peer: &peer::Peer) -> bool {
37-
self.write().upsert_peer(peer)
37+
self.lock().upsert_peer(peer)
3838
}
3939

4040
fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch) {
41-
self.write().remove_inactive_peers(current_cutoff);
41+
self.lock().remove_inactive_peers(current_cutoff);
4242
}
4343
}
4444

45-
impl From<EntrySingle> for EntryRwLockParkingLot {
45+
impl From<EntrySingle> for EntryMutexParkingLot {
4646
fn from(entry: EntrySingle) -> Self {
47-
Arc::new(parking_lot::RwLock::new(entry))
47+
Arc::new(parking_lot::Mutex::new(entry))
4848
}
4949
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use std::net::SocketAddr;
2+
use std::sync::Arc;
3+
4+
use torrust_tracker_configuration::TrackerPolicy;
5+
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
6+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};
7+
8+
use super::{Entry, EntrySync};
9+
use crate::{EntryRwLockParkingLot, EntrySingle};
10+
11+
impl EntrySync for EntryRwLockParkingLot {
12+
fn get_swarm_metadata(&self) -> SwarmMetadata {
13+
self.read().get_swarm_metadata()
14+
}
15+
16+
fn is_good(&self, policy: &TrackerPolicy) -> bool {
17+
self.read().is_good(policy)
18+
}
19+
20+
fn peers_is_empty(&self) -> bool {
21+
self.read().peers_is_empty()
22+
}
23+
24+
fn get_peers_len(&self) -> usize {
25+
self.read().get_peers_len()
26+
}
27+
28+
fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
29+
self.read().get_peers(limit)
30+
}
31+
32+
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
33+
self.read().get_peers_for_client(client, limit)
34+
}
35+
36+
fn upsert_peer(&self, peer: &peer::Peer) -> bool {
37+
self.write().upsert_peer(peer)
38+
}
39+
40+
fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch) {
41+
self.write().remove_inactive_peers(current_cutoff);
42+
}
43+
}
44+
45+
impl From<EntrySingle> for EntryRwLockParkingLot {
46+
fn from(entry: EntrySingle) -> Self {
47+
Arc::new(parking_lot::RwLock::new(entry))
48+
}
49+
}

‎packages/torrent-repository/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub mod repository;
1414
pub type EntrySingle = entry::Torrent;
1515
pub type EntryMutexStd = Arc<std::sync::Mutex<entry::Torrent>>;
1616
pub type EntryMutexTokio = Arc<tokio::sync::Mutex<entry::Torrent>>;
17+
pub type EntryMutexParkingLot = Arc<parking_lot::Mutex<entry::Torrent>>;
1718
pub type EntryRwLockParkingLot = Arc<parking_lot::RwLock<entry::Torrent>>;
1819

1920
// Repos
@@ -26,6 +27,7 @@ pub type TorrentsRwLockTokioMutexStd = RwLockTokio<EntryMutexStd>;
2627
pub type TorrentsRwLockTokioMutexTokio = RwLockTokio<EntryMutexTokio>;
2728

2829
pub type TorrentsSkipMapMutexStd = CrossbeamSkipList<EntryMutexStd>;
30+
pub type TorrentsSkipMapMutexParkingLot = CrossbeamSkipList<EntryMutexParkingLot>;
2931
pub type TorrentsSkipMapRwLockParkingLot = CrossbeamSkipList<EntryRwLockParkingLot>;
3032

3133
pub type TorrentsDashMapMutexStd = XacrimonDashMap<EntryMutexStd>;

‎packages/torrent-repository/src/repository/skip_map_mutex_std.rs

+92-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent
1111
use super::Repository;
1212
use crate::entry::peer_list::PeerList;
1313
use crate::entry::{Entry, EntrySync};
14-
use crate::{EntryMutexStd, EntryRwLockParkingLot, EntrySingle};
14+
use crate::{EntryMutexParkingLot, EntryMutexStd, EntryRwLockParkingLot, EntrySingle};
1515

1616
#[derive(Default, Debug)]
1717
pub struct CrossbeamSkipList<T> {
@@ -199,3 +199,94 @@ where
199199
}
200200
}
201201
}
202+
203+
impl Repository<EntryMutexParkingLot> for CrossbeamSkipList<EntryMutexParkingLot>
204+
where
205+
EntryMutexParkingLot: EntrySync,
206+
EntrySingle: Entry,
207+
{
208+
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) {
209+
let entry = self.torrents.get_or_insert(*info_hash, Arc::default());
210+
entry.value().upsert_peer(peer);
211+
}
212+
213+
fn get_swarm_metadata(&self, info_hash: &InfoHash) -> Option<SwarmMetadata> {
214+
self.torrents.get(info_hash).map(|entry| entry.value().get_swarm_metadata())
215+
}
216+
217+
fn get(&self, key: &InfoHash) -> Option<EntryMutexParkingLot> {
218+
let maybe_entry = self.torrents.get(key);
219+
maybe_entry.map(|entry| entry.value().clone())
220+
}
221+
222+
fn get_metrics(&self) -> TorrentsMetrics {
223+
let mut metrics = TorrentsMetrics::default();
224+
225+
for entry in &self.torrents {
226+
let stats = entry.value().lock().get_swarm_metadata();
227+
metrics.complete += u64::from(stats.complete);
228+
metrics.downloaded += u64::from(stats.downloaded);
229+
metrics.incomplete += u64::from(stats.incomplete);
230+
metrics.torrents += 1;
231+
}
232+
233+
metrics
234+
}
235+
236+
fn get_paginated(&self, pagination: Option<&Pagination>) -> Vec<(InfoHash, EntryMutexParkingLot)> {
237+
match pagination {
238+
Some(pagination) => self
239+
.torrents
240+
.iter()
241+
.skip(pagination.offset as usize)
242+
.take(pagination.limit as usize)
243+
.map(|entry| (*entry.key(), entry.value().clone()))
244+
.collect(),
245+
None => self
246+
.torrents
247+
.iter()
248+
.map(|entry| (*entry.key(), entry.value().clone()))
249+
.collect(),
250+
}
251+
}
252+
253+
fn import_persistent(&self, persistent_torrents: &PersistentTorrents) {
254+
for (info_hash, completed) in persistent_torrents {
255+
if self.torrents.contains_key(info_hash) {
256+
continue;
257+
}
258+
259+
let entry = EntryMutexParkingLot::new(
260+
EntrySingle {
261+
swarm: PeerList::default(),
262+
downloaded: *completed,
263+
}
264+
.into(),
265+
);
266+
267+
// Since SkipMap is lock-free the torrent could have been inserted
268+
// after checking if it exists.
269+
self.torrents.get_or_insert(*info_hash, entry);
270+
}
271+
}
272+
273+
fn remove(&self, key: &InfoHash) -> Option<EntryMutexParkingLot> {
274+
self.torrents.remove(key).map(|entry| entry.value().clone())
275+
}
276+
277+
fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch) {
278+
for entry in &self.torrents {
279+
entry.value().remove_inactive_peers(current_cutoff);
280+
}
281+
}
282+
283+
fn remove_peerless_torrents(&self, policy: &TrackerPolicy) {
284+
for entry in &self.torrents {
285+
if entry.value().is_good(policy) {
286+
continue;
287+
}
288+
289+
entry.remove();
290+
}
291+
}
292+
}

‎packages/torrent-repository/tests/common/repo.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent
77
use torrust_tracker_torrent_repository::repository::{Repository as _, RepositoryAsync as _};
88
use torrust_tracker_torrent_repository::{
99
EntrySingle, TorrentsDashMapMutexStd, TorrentsRwLockStd, TorrentsRwLockStdMutexStd, TorrentsRwLockStdMutexTokio,
10-
TorrentsRwLockTokio, TorrentsRwLockTokioMutexStd, TorrentsRwLockTokioMutexTokio, TorrentsSkipMapMutexStd,
11-
TorrentsSkipMapRwLockParkingLot,
10+
TorrentsRwLockTokio, TorrentsRwLockTokioMutexStd, TorrentsRwLockTokioMutexTokio, TorrentsSkipMapMutexParkingLot,
11+
TorrentsSkipMapMutexStd, TorrentsSkipMapRwLockParkingLot,
1212
};
1313

1414
#[derive(Debug)]
@@ -20,6 +20,7 @@ pub(crate) enum Repo {
2020
RwLockTokioMutexStd(TorrentsRwLockTokioMutexStd),
2121
RwLockTokioMutexTokio(TorrentsRwLockTokioMutexTokio),
2222
SkipMapMutexStd(TorrentsSkipMapMutexStd),
23+
SkipMapMutexParkingLot(TorrentsSkipMapMutexParkingLot),
2324
SkipMapRwLockParkingLot(TorrentsSkipMapRwLockParkingLot),
2425
DashMapMutexStd(TorrentsDashMapMutexStd),
2526
}
@@ -34,6 +35,7 @@ impl Repo {
3435
Repo::RwLockTokioMutexStd(repo) => repo.upsert_peer(info_hash, peer).await,
3536
Repo::RwLockTokioMutexTokio(repo) => repo.upsert_peer(info_hash, peer).await,
3637
Repo::SkipMapMutexStd(repo) => repo.upsert_peer(info_hash, peer),
38+
Repo::SkipMapMutexParkingLot(repo) => repo.upsert_peer(info_hash, peer),
3739
Repo::SkipMapRwLockParkingLot(repo) => repo.upsert_peer(info_hash, peer),
3840
Repo::DashMapMutexStd(repo) => repo.upsert_peer(info_hash, peer),
3941
}
@@ -48,6 +50,7 @@ impl Repo {
4850
Repo::RwLockTokioMutexStd(repo) => repo.get_swarm_metadata(info_hash).await,
4951
Repo::RwLockTokioMutexTokio(repo) => repo.get_swarm_metadata(info_hash).await,
5052
Repo::SkipMapMutexStd(repo) => repo.get_swarm_metadata(info_hash),
53+
Repo::SkipMapMutexParkingLot(repo) => repo.get_swarm_metadata(info_hash),
5154
Repo::SkipMapRwLockParkingLot(repo) => repo.get_swarm_metadata(info_hash),
5255
Repo::DashMapMutexStd(repo) => repo.get_swarm_metadata(info_hash),
5356
}
@@ -62,6 +65,7 @@ impl Repo {
6265
Repo::RwLockTokioMutexStd(repo) => Some(repo.get(key).await?.lock().unwrap().clone()),
6366
Repo::RwLockTokioMutexTokio(repo) => Some(repo.get(key).await?.lock().await.clone()),
6467
Repo::SkipMapMutexStd(repo) => Some(repo.get(key)?.lock().unwrap().clone()),
68+
Repo::SkipMapMutexParkingLot(repo) => Some(repo.get(key)?.lock().clone()),
6569
Repo::SkipMapRwLockParkingLot(repo) => Some(repo.get(key)?.read().clone()),
6670
Repo::DashMapMutexStd(repo) => Some(repo.get(key)?.lock().unwrap().clone()),
6771
}
@@ -76,6 +80,7 @@ impl Repo {
7680
Repo::RwLockTokioMutexStd(repo) => repo.get_metrics().await,
7781
Repo::RwLockTokioMutexTokio(repo) => repo.get_metrics().await,
7882
Repo::SkipMapMutexStd(repo) => repo.get_metrics(),
83+
Repo::SkipMapMutexParkingLot(repo) => repo.get_metrics(),
7984
Repo::SkipMapRwLockParkingLot(repo) => repo.get_metrics(),
8085
Repo::DashMapMutexStd(repo) => repo.get_metrics(),
8186
}
@@ -117,6 +122,11 @@ impl Repo {
117122
.iter()
118123
.map(|(i, t)| (*i, t.lock().expect("it should get a lock").clone()))
119124
.collect(),
125+
Repo::SkipMapMutexParkingLot(repo) => repo
126+
.get_paginated(pagination)
127+
.iter()
128+
.map(|(i, t)| (*i, t.lock().clone()))
129+
.collect(),
120130
Repo::SkipMapRwLockParkingLot(repo) => repo
121131
.get_paginated(pagination)
122132
.iter()
@@ -139,6 +149,7 @@ impl Repo {
139149
Repo::RwLockTokioMutexStd(repo) => repo.import_persistent(persistent_torrents).await,
140150
Repo::RwLockTokioMutexTokio(repo) => repo.import_persistent(persistent_torrents).await,
141151
Repo::SkipMapMutexStd(repo) => repo.import_persistent(persistent_torrents),
152+
Repo::SkipMapMutexParkingLot(repo) => repo.import_persistent(persistent_torrents),
142153
Repo::SkipMapRwLockParkingLot(repo) => repo.import_persistent(persistent_torrents),
143154
Repo::DashMapMutexStd(repo) => repo.import_persistent(persistent_torrents),
144155
}
@@ -153,6 +164,7 @@ impl Repo {
153164
Repo::RwLockTokioMutexStd(repo) => Some(repo.remove(key).await?.lock().unwrap().clone()),
154165
Repo::RwLockTokioMutexTokio(repo) => Some(repo.remove(key).await?.lock().await.clone()),
155166
Repo::SkipMapMutexStd(repo) => Some(repo.remove(key)?.lock().unwrap().clone()),
167+
Repo::SkipMapMutexParkingLot(repo) => Some(repo.remove(key)?.lock().clone()),
156168
Repo::SkipMapRwLockParkingLot(repo) => Some(repo.remove(key)?.write().clone()),
157169
Repo::DashMapMutexStd(repo) => Some(repo.remove(key)?.lock().unwrap().clone()),
158170
}
@@ -167,6 +179,7 @@ impl Repo {
167179
Repo::RwLockTokioMutexStd(repo) => repo.remove_inactive_peers(current_cutoff).await,
168180
Repo::RwLockTokioMutexTokio(repo) => repo.remove_inactive_peers(current_cutoff).await,
169181
Repo::SkipMapMutexStd(repo) => repo.remove_inactive_peers(current_cutoff),
182+
Repo::SkipMapMutexParkingLot(repo) => repo.remove_inactive_peers(current_cutoff),
170183
Repo::SkipMapRwLockParkingLot(repo) => repo.remove_inactive_peers(current_cutoff),
171184
Repo::DashMapMutexStd(repo) => repo.remove_inactive_peers(current_cutoff),
172185
}
@@ -181,6 +194,7 @@ impl Repo {
181194
Repo::RwLockTokioMutexStd(repo) => repo.remove_peerless_torrents(policy).await,
182195
Repo::RwLockTokioMutexTokio(repo) => repo.remove_peerless_torrents(policy).await,
183196
Repo::SkipMapMutexStd(repo) => repo.remove_peerless_torrents(policy),
197+
Repo::SkipMapMutexParkingLot(repo) => repo.remove_peerless_torrents(policy),
184198
Repo::SkipMapRwLockParkingLot(repo) => repo.remove_peerless_torrents(policy),
185199
Repo::DashMapMutexStd(repo) => repo.remove_peerless_torrents(policy),
186200
}
@@ -209,6 +223,9 @@ impl Repo {
209223
Repo::SkipMapMutexStd(repo) => {
210224
repo.torrents.insert(*info_hash, torrent.into());
211225
}
226+
Repo::SkipMapMutexParkingLot(repo) => {
227+
repo.torrents.insert(*info_hash, torrent.into());
228+
}
212229
Repo::SkipMapRwLockParkingLot(repo) => {
213230
repo.torrents.insert(*info_hash, torrent.into());
214231
}

‎packages/torrent-repository/tests/common/torrent.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ use torrust_tracker_configuration::TrackerPolicy;
55
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
66
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};
77
use torrust_tracker_torrent_repository::entry::{Entry as _, EntryAsync as _, EntrySync as _};
8-
use torrust_tracker_torrent_repository::{EntryMutexStd, EntryMutexTokio, EntryRwLockParkingLot, EntrySingle};
8+
use torrust_tracker_torrent_repository::{
9+
EntryMutexParkingLot, EntryMutexStd, EntryMutexTokio, EntryRwLockParkingLot, EntrySingle,
10+
};
911

1012
#[derive(Debug, Clone)]
1113
pub(crate) enum Torrent {
1214
Single(EntrySingle),
1315
MutexStd(EntryMutexStd),
1416
MutexTokio(EntryMutexTokio),
17+
MutexParkingLot(EntryMutexParkingLot),
1518
RwLockParkingLot(EntryRwLockParkingLot),
1619
}
1720

@@ -21,6 +24,7 @@ impl Torrent {
2124
Torrent::Single(entry) => entry.get_swarm_metadata(),
2225
Torrent::MutexStd(entry) => entry.get_swarm_metadata(),
2326
Torrent::MutexTokio(entry) => entry.clone().get_swarm_metadata().await,
27+
Torrent::MutexParkingLot(entry) => entry.clone().get_swarm_metadata(),
2428
Torrent::RwLockParkingLot(entry) => entry.clone().get_swarm_metadata(),
2529
}
2630
}
@@ -30,6 +34,7 @@ impl Torrent {
3034
Torrent::Single(entry) => entry.is_good(policy),
3135
Torrent::MutexStd(entry) => entry.is_good(policy),
3236
Torrent::MutexTokio(entry) => entry.clone().check_good(policy).await,
37+
Torrent::MutexParkingLot(entry) => entry.is_good(policy),
3338
Torrent::RwLockParkingLot(entry) => entry.is_good(policy),
3439
}
3540
}
@@ -39,6 +44,7 @@ impl Torrent {
3944
Torrent::Single(entry) => entry.peers_is_empty(),
4045
Torrent::MutexStd(entry) => entry.peers_is_empty(),
4146
Torrent::MutexTokio(entry) => entry.clone().peers_is_empty().await,
47+
Torrent::MutexParkingLot(entry) => entry.peers_is_empty(),
4248
Torrent::RwLockParkingLot(entry) => entry.peers_is_empty(),
4349
}
4450
}
@@ -48,6 +54,7 @@ impl Torrent {
4854
Torrent::Single(entry) => entry.get_peers_len(),
4955
Torrent::MutexStd(entry) => entry.get_peers_len(),
5056
Torrent::MutexTokio(entry) => entry.clone().get_peers_len().await,
57+
Torrent::MutexParkingLot(entry) => entry.get_peers_len(),
5158
Torrent::RwLockParkingLot(entry) => entry.get_peers_len(),
5259
}
5360
}
@@ -57,6 +64,7 @@ impl Torrent {
5764
Torrent::Single(entry) => entry.get_peers(limit),
5865
Torrent::MutexStd(entry) => entry.get_peers(limit),
5966
Torrent::MutexTokio(entry) => entry.clone().get_peers(limit).await,
67+
Torrent::MutexParkingLot(entry) => entry.get_peers(limit),
6068
Torrent::RwLockParkingLot(entry) => entry.get_peers(limit),
6169
}
6270
}
@@ -66,6 +74,7 @@ impl Torrent {
6674
Torrent::Single(entry) => entry.get_peers_for_client(client, limit),
6775
Torrent::MutexStd(entry) => entry.get_peers_for_client(client, limit),
6876
Torrent::MutexTokio(entry) => entry.clone().get_peers_for_client(client, limit).await,
77+
Torrent::MutexParkingLot(entry) => entry.get_peers_for_client(client, limit),
6978
Torrent::RwLockParkingLot(entry) => entry.get_peers_for_client(client, limit),
7079
}
7180
}
@@ -75,6 +84,7 @@ impl Torrent {
7584
Torrent::Single(entry) => entry.upsert_peer(peer),
7685
Torrent::MutexStd(entry) => entry.upsert_peer(peer),
7786
Torrent::MutexTokio(entry) => entry.clone().upsert_peer(peer).await,
87+
Torrent::MutexParkingLot(entry) => entry.upsert_peer(peer),
7888
Torrent::RwLockParkingLot(entry) => entry.upsert_peer(peer),
7989
}
8090
}
@@ -84,6 +94,7 @@ impl Torrent {
8494
Torrent::Single(entry) => entry.remove_inactive_peers(current_cutoff),
8595
Torrent::MutexStd(entry) => entry.remove_inactive_peers(current_cutoff),
8696
Torrent::MutexTokio(entry) => entry.clone().remove_inactive_peers(current_cutoff).await,
97+
Torrent::MutexParkingLot(entry) => entry.remove_inactive_peers(current_cutoff),
8798
Torrent::RwLockParkingLot(entry) => entry.remove_inactive_peers(current_cutoff),
8899
}
89100
}

‎packages/torrent-repository/tests/entry/mod.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ use torrust_tracker_configuration::{TrackerPolicy, TORRENT_PEERS_LIMIT};
99
use torrust_tracker_primitives::announce_event::AnnounceEvent;
1010
use torrust_tracker_primitives::peer::Peer;
1111
use torrust_tracker_primitives::{peer, NumberOfBytes};
12-
use torrust_tracker_torrent_repository::{EntryMutexStd, EntryMutexTokio, EntryRwLockParkingLot, EntrySingle};
12+
use torrust_tracker_torrent_repository::{
13+
EntryMutexParkingLot, EntryMutexStd, EntryMutexTokio, EntryRwLockParkingLot, EntrySingle,
14+
};
1315

1416
use crate::common::torrent::Torrent;
1517
use crate::common::torrent_peer_builder::{a_completed_peer, a_started_peer};
@@ -29,6 +31,11 @@ fn mutex_tokio() -> Torrent {
2931
Torrent::MutexTokio(EntryMutexTokio::default())
3032
}
3133

34+
#[fixture]
35+
fn mutex_parking_lot() -> Torrent {
36+
Torrent::MutexParkingLot(EntryMutexParkingLot::default())
37+
}
38+
3239
#[fixture]
3340
fn rw_lock_parking_lot() -> Torrent {
3441
Torrent::RwLockParkingLot(EntryRwLockParkingLot::default())
@@ -104,7 +111,7 @@ async fn make(torrent: &mut Torrent, makes: &Makes) -> Vec<Peer> {
104111
#[case::empty(&Makes::Empty)]
105112
#[tokio::test]
106113
async fn it_should_be_empty_by_default(
107-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
114+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
108115
#[case] makes: &Makes,
109116
) {
110117
make(&mut torrent, makes).await;
@@ -120,7 +127,7 @@ async fn it_should_be_empty_by_default(
120127
#[case::three(&Makes::Three)]
121128
#[tokio::test]
122129
async fn it_should_check_if_entry_is_good(
123-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
130+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
124131
#[case] makes: &Makes,
125132
#[values(policy_none(), policy_persist(), policy_remove(), policy_remove_persist())] policy: TrackerPolicy,
126133
) {
@@ -158,7 +165,7 @@ async fn it_should_check_if_entry_is_good(
158165
#[case::three(&Makes::Three)]
159166
#[tokio::test]
160167
async fn it_should_get_peers_for_torrent_entry(
161-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
168+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
162169
#[case] makes: &Makes,
163170
) {
164171
let peers = make(&mut torrent, makes).await;
@@ -217,7 +224,7 @@ async fn it_should_update_a_peer(#[values(single(), mutex_std(), mutex_tokio())]
217224
#[case::three(&Makes::Three)]
218225
#[tokio::test]
219226
async fn it_should_remove_a_peer_upon_stopped_announcement(
220-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
227+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
221228
#[case] makes: &Makes,
222229
) {
223230
use torrust_tracker_primitives::peer::ReadInfo as _;
@@ -258,7 +265,7 @@ async fn it_should_remove_a_peer_upon_stopped_announcement(
258265
#[case::three(&Makes::Three)]
259266
#[tokio::test]
260267
async fn it_should_handle_a_peer_completed_announcement_and_update_the_downloaded_statistic(
261-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
268+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
262269
#[case] makes: &Makes,
263270
) {
264271
make(&mut torrent, makes).await;
@@ -289,7 +296,7 @@ async fn it_should_handle_a_peer_completed_announcement_and_update_the_downloade
289296
#[case::three(&Makes::Three)]
290297
#[tokio::test]
291298
async fn it_should_update_a_peer_as_a_seeder(
292-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
299+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(),rw_lock_parking_lot())] mut torrent: Torrent,
293300
#[case] makes: &Makes,
294301
) {
295302
let peers = make(&mut torrent, makes).await;
@@ -321,7 +328,7 @@ async fn it_should_update_a_peer_as_a_seeder(
321328
#[case::three(&Makes::Three)]
322329
#[tokio::test]
323330
async fn it_should_update_a_peer_as_incomplete(
324-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
331+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
325332
#[case] makes: &Makes,
326333
) {
327334
let peers = make(&mut torrent, makes).await;
@@ -353,7 +360,7 @@ async fn it_should_update_a_peer_as_incomplete(
353360
#[case::three(&Makes::Three)]
354361
#[tokio::test]
355362
async fn it_should_get_peers_excluding_the_client_socket(
356-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
363+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
357364
#[case] makes: &Makes,
358365
) {
359366
make(&mut torrent, makes).await;
@@ -385,7 +392,7 @@ async fn it_should_get_peers_excluding_the_client_socket(
385392
#[case::three(&Makes::Three)]
386393
#[tokio::test]
387394
async fn it_should_limit_the_number_of_peers_returned(
388-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
395+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
389396
#[case] makes: &Makes,
390397
) {
391398
make(&mut torrent, makes).await;
@@ -410,7 +417,7 @@ async fn it_should_limit_the_number_of_peers_returned(
410417
#[case::three(&Makes::Three)]
411418
#[tokio::test]
412419
async fn it_should_remove_inactive_peers_beyond_cutoff(
413-
#[values(single(), mutex_std(), mutex_tokio(), rw_lock_parking_lot())] mut torrent: Torrent,
420+
#[values(single(), mutex_std(), mutex_tokio(), mutex_parking_lot(), rw_lock_parking_lot())] mut torrent: Torrent,
414421
#[case] makes: &Makes,
415422
) {
416423
const TIMEOUT: Duration = Duration::from_secs(120);

‎packages/torrent-repository/tests/repository/mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ fn skip_list_mutex_std() -> Repo {
5353
Repo::SkipMapMutexStd(CrossbeamSkipList::default())
5454
}
5555

56+
#[fixture]
57+
fn skip_list_mutex_parking_lot() -> Repo {
58+
Repo::SkipMapMutexParkingLot(CrossbeamSkipList::default())
59+
}
60+
5661
#[fixture]
5762
fn skip_list_rw_lock_parking_lot() -> Repo {
5863
Repo::SkipMapRwLockParkingLot(CrossbeamSkipList::default())
@@ -252,6 +257,7 @@ async fn it_should_get_a_torrent_entry(
252257
tokio_mutex(),
253258
tokio_tokio(),
254259
skip_list_mutex_std(),
260+
skip_list_mutex_parking_lot(),
255261
skip_list_rw_lock_parking_lot(),
256262
dash_map_std()
257263
)]
@@ -286,6 +292,7 @@ async fn it_should_get_paginated_entries_in_a_stable_or_sorted_order(
286292
tokio_mutex(),
287293
tokio_tokio(),
288294
skip_list_mutex_std(),
295+
skip_list_mutex_parking_lot(),
289296
skip_list_rw_lock_parking_lot()
290297
)]
291298
repo: Repo,
@@ -329,6 +336,7 @@ async fn it_should_get_paginated(
329336
tokio_mutex(),
330337
tokio_tokio(),
331338
skip_list_mutex_std(),
339+
skip_list_mutex_parking_lot(),
332340
skip_list_rw_lock_parking_lot()
333341
)]
334342
repo: Repo,
@@ -387,6 +395,7 @@ async fn it_should_get_metrics(
387395
tokio_mutex(),
388396
tokio_tokio(),
389397
skip_list_mutex_std(),
398+
skip_list_mutex_parking_lot(),
390399
skip_list_rw_lock_parking_lot(),
391400
dash_map_std()
392401
)]
@@ -430,6 +439,7 @@ async fn it_should_import_persistent_torrents(
430439
tokio_mutex(),
431440
tokio_tokio(),
432441
skip_list_mutex_std(),
442+
skip_list_mutex_parking_lot(),
433443
skip_list_rw_lock_parking_lot(),
434444
dash_map_std()
435445
)]
@@ -470,6 +480,7 @@ async fn it_should_remove_an_entry(
470480
tokio_mutex(),
471481
tokio_tokio(),
472482
skip_list_mutex_std(),
483+
skip_list_mutex_parking_lot(),
473484
skip_list_rw_lock_parking_lot(),
474485
dash_map_std()
475486
)]
@@ -508,6 +519,7 @@ async fn it_should_remove_inactive_peers(
508519
tokio_mutex(),
509520
tokio_tokio(),
510521
skip_list_mutex_std(),
522+
skip_list_mutex_parking_lot(),
511523
skip_list_rw_lock_parking_lot(),
512524
dash_map_std()
513525
)]
@@ -607,6 +619,7 @@ async fn it_should_remove_peerless_torrents(
607619
tokio_mutex(),
608620
tokio_tokio(),
609621
skip_list_mutex_std(),
622+
skip_list_mutex_parking_lot(),
610623
skip_list_rw_lock_parking_lot(),
611624
dash_map_std()
612625
)]

0 commit comments

Comments
 (0)
Please sign in to comment.