1- use std:: sync:: Arc ;
2-
31use bittorrent_primitives:: info_hash:: InfoHash ;
42use crossbeam_skiplist:: SkipMap ;
53use torrust_tracker_configuration:: TrackerPolicy ;
@@ -10,7 +8,7 @@ use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent
108use super :: Repository ;
119use crate :: entry:: peer_list:: PeerList ;
1210use crate :: entry:: { Entry , EntrySync } ;
13- use crate :: { EntryMutexParkingLot , EntryMutexStd , EntryRwLockParkingLot , EntrySingle } ;
11+ use crate :: { EntryMutexStd , EntrySingle } ;
1412
1513#[ derive( Default , Debug ) ]
1614pub struct CrossbeamSkipList < T > {
@@ -140,189 +138,3 @@ where
140138 }
141139 }
142140}
143-
144- impl Repository < EntryRwLockParkingLot > for CrossbeamSkipList < EntryRwLockParkingLot >
145- where
146- EntryRwLockParkingLot : EntrySync ,
147- EntrySingle : Entry ,
148- {
149- fn upsert_peer ( & self , info_hash : & InfoHash , peer : & peer:: Peer , _opt_persistent_torrent : Option < PersistentTorrent > ) -> bool {
150- // todo: load persistent torrent data if provided
151-
152- let entry = self . torrents . get_or_insert ( * info_hash, Arc :: default ( ) ) ;
153- entry. value ( ) . upsert_peer ( peer)
154- }
155-
156- fn get_swarm_metadata ( & self , info_hash : & InfoHash ) -> Option < SwarmMetadata > {
157- self . torrents . get ( info_hash) . map ( |entry| entry. value ( ) . get_swarm_metadata ( ) )
158- }
159-
160- fn get ( & self , key : & InfoHash ) -> Option < EntryRwLockParkingLot > {
161- let maybe_entry = self . torrents . get ( key) ;
162- maybe_entry. map ( |entry| entry. value ( ) . clone ( ) )
163- }
164-
165- fn get_metrics ( & self ) -> AggregateSwarmMetadata {
166- let mut metrics = AggregateSwarmMetadata :: default ( ) ;
167-
168- for entry in & self . torrents {
169- let stats = entry. value ( ) . read ( ) . get_swarm_metadata ( ) ;
170- metrics. total_complete += u64:: from ( stats. complete ) ;
171- metrics. total_downloaded += u64:: from ( stats. downloaded ) ;
172- metrics. total_incomplete += u64:: from ( stats. incomplete ) ;
173- metrics. total_torrents += 1 ;
174- }
175-
176- metrics
177- }
178-
179- fn get_paginated ( & self , pagination : Option < & Pagination > ) -> Vec < ( InfoHash , EntryRwLockParkingLot ) > {
180- match pagination {
181- Some ( pagination) => self
182- . torrents
183- . iter ( )
184- . skip ( pagination. offset as usize )
185- . take ( pagination. limit as usize )
186- . map ( |entry| ( * entry. key ( ) , entry. value ( ) . clone ( ) ) )
187- . collect ( ) ,
188- None => self
189- . torrents
190- . iter ( )
191- . map ( |entry| ( * entry. key ( ) , entry. value ( ) . clone ( ) ) )
192- . collect ( ) ,
193- }
194- }
195-
196- fn import_persistent ( & self , persistent_torrents : & PersistentTorrents ) {
197- for ( info_hash, completed) in persistent_torrents {
198- if self . torrents . contains_key ( info_hash) {
199- continue ;
200- }
201-
202- let entry = EntryRwLockParkingLot :: new (
203- EntrySingle {
204- swarm : PeerList :: default ( ) ,
205- downloaded : * completed,
206- }
207- . into ( ) ,
208- ) ;
209-
210- // Since SkipMap is lock-free the torrent could have been inserted
211- // after checking if it exists.
212- self . torrents . get_or_insert ( * info_hash, entry) ;
213- }
214- }
215-
216- fn remove ( & self , key : & InfoHash ) -> Option < EntryRwLockParkingLot > {
217- self . torrents . remove ( key) . map ( |entry| entry. value ( ) . clone ( ) )
218- }
219-
220- fn remove_inactive_peers ( & self , current_cutoff : DurationSinceUnixEpoch ) {
221- for entry in & self . torrents {
222- entry. value ( ) . remove_inactive_peers ( current_cutoff) ;
223- }
224- }
225-
226- fn remove_peerless_torrents ( & self , policy : & TrackerPolicy ) {
227- for entry in & self . torrents {
228- if entry. value ( ) . meets_retaining_policy ( policy) {
229- continue ;
230- }
231-
232- entry. remove ( ) ;
233- }
234- }
235- }
236-
237- impl Repository < EntryMutexParkingLot > for CrossbeamSkipList < EntryMutexParkingLot >
238- where
239- EntryMutexParkingLot : EntrySync ,
240- EntrySingle : Entry ,
241- {
242- fn upsert_peer ( & self , info_hash : & InfoHash , peer : & peer:: Peer , _opt_persistent_torrent : Option < PersistentTorrent > ) -> bool {
243- // todo: load persistent torrent data if provided
244-
245- let entry = self . torrents . get_or_insert ( * info_hash, Arc :: default ( ) ) ;
246- entry. value ( ) . upsert_peer ( peer)
247- }
248-
249- fn get_swarm_metadata ( & self , info_hash : & InfoHash ) -> Option < SwarmMetadata > {
250- self . torrents . get ( info_hash) . map ( |entry| entry. value ( ) . get_swarm_metadata ( ) )
251- }
252-
253- fn get ( & self , key : & InfoHash ) -> Option < EntryMutexParkingLot > {
254- let maybe_entry = self . torrents . get ( key) ;
255- maybe_entry. map ( |entry| entry. value ( ) . clone ( ) )
256- }
257-
258- fn get_metrics ( & self ) -> AggregateSwarmMetadata {
259- let mut metrics = AggregateSwarmMetadata :: default ( ) ;
260-
261- for entry in & self . torrents {
262- let stats = entry. value ( ) . lock ( ) . get_swarm_metadata ( ) ;
263- metrics. total_complete += u64:: from ( stats. complete ) ;
264- metrics. total_downloaded += u64:: from ( stats. downloaded ) ;
265- metrics. total_incomplete += u64:: from ( stats. incomplete ) ;
266- metrics. total_torrents += 1 ;
267- }
268-
269- metrics
270- }
271-
272- fn get_paginated ( & self , pagination : Option < & Pagination > ) -> Vec < ( InfoHash , EntryMutexParkingLot ) > {
273- match pagination {
274- Some ( pagination) => self
275- . torrents
276- . iter ( )
277- . skip ( pagination. offset as usize )
278- . take ( pagination. limit as usize )
279- . map ( |entry| ( * entry. key ( ) , entry. value ( ) . clone ( ) ) )
280- . collect ( ) ,
281- None => self
282- . torrents
283- . iter ( )
284- . map ( |entry| ( * entry. key ( ) , entry. value ( ) . clone ( ) ) )
285- . collect ( ) ,
286- }
287- }
288-
289- fn import_persistent ( & self , persistent_torrents : & PersistentTorrents ) {
290- for ( info_hash, completed) in persistent_torrents {
291- if self . torrents . contains_key ( info_hash) {
292- continue ;
293- }
294-
295- let entry = EntryMutexParkingLot :: new (
296- EntrySingle {
297- swarm : PeerList :: default ( ) ,
298- downloaded : * completed,
299- }
300- . into ( ) ,
301- ) ;
302-
303- // Since SkipMap is lock-free the torrent could have been inserted
304- // after checking if it exists.
305- self . torrents . get_or_insert ( * info_hash, entry) ;
306- }
307- }
308-
309- fn remove ( & self , key : & InfoHash ) -> Option < EntryMutexParkingLot > {
310- self . torrents . remove ( key) . map ( |entry| entry. value ( ) . clone ( ) )
311- }
312-
313- fn remove_inactive_peers ( & self , current_cutoff : DurationSinceUnixEpoch ) {
314- for entry in & self . torrents {
315- entry. value ( ) . remove_inactive_peers ( current_cutoff) ;
316- }
317- }
318-
319- fn remove_peerless_torrents ( & self , policy : & TrackerPolicy ) {
320- for entry in & self . torrents {
321- if entry. value ( ) . meets_retaining_policy ( policy) {
322- continue ;
323- }
324-
325- entry. remove ( ) ;
326- }
327- }
328- }
0 commit comments