/* Returns amount of removed peers */ static ssize_t clean_single_bucket( ot_peer *peers, size_t peer_count, time_t timedout, int *removed_seeders ) { ot_peer *last_peer = peers + peer_count, *insert_point; time_t timediff; /* Two scan modes: unless there is one peer removed, just increase ot_peertime */ while( peers < last_peer ) { if( ( timediff = timedout + OT_PEERTIME( peers ) ) >= OT_PEER_TIMEOUT ) break; OT_PEERTIME( peers++ ) = timediff; } /* If we at least remove one peer, we have to copy */ insert_point = peers; while( peers < last_peer ) if( ( timediff = timedout + OT_PEERTIME( peers ) ) < OT_PEER_TIMEOUT ) { OT_PEERTIME( peers ) = timediff; memcpy( insert_point++, peers++, sizeof(ot_peer)); } else if( OT_PEERFLAG( peers++ ) & PEER_FLAG_SEEDING ) (*removed_seeders)++; return peers - insert_point; }
size_t add_peer_to_torrent_proxy( ot_hash hash, ot_peer *peer ) { int exactmatch; ot_torrent *torrent; ot_peer *peer_dest; ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); if( !torrent ) return -1; if( !exactmatch ) { /* Create a new torrent entry, then */ memcpy( torrent->hash, hash, sizeof(ot_hash) ); if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { vector_remove_torrent( torrents_list, torrent ); mutex_bucket_unlock_by_hash( hash, 0 ); return -1; } byte_zero( torrent->peer_list, sizeof( ot_peerlist ) ); } /* Check for peer in torrent */ peer_dest = vector_find_or_insert_peer( &(torrent->peer_list->peers), peer, &exactmatch ); if( !peer_dest ) { mutex_bucket_unlock_by_hash( hash, 0 ); return -1; } /* Tell peer that it's fresh */ OT_PEERTIME( peer ) = 0; /* If we hadn't had a match create peer there */ if( !exactmatch ) { torrent->peer_list->peer_count++; if( OT_PEERFLAG(peer) & PEER_FLAG_SEEDING ) torrent->peer_list->seed_count++; } memcpy( peer_dest, peer, sizeof(ot_peer) ); mutex_bucket_unlock_by_hash( hash, 0 ); return 0; }