]> granicus.if.org Git - transmission/commitdiff
(trunk libT) modify how the "stops" sorted container is used s.t. the container's...
authorJordan Lee <jordan@transmissionbt.com>
Sun, 19 Jun 2011 18:26:04 +0000 (18:26 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Sun, 19 Jun 2011 18:26:04 +0000 (18:26 +0000)
libtransmission/announcer.c

index 1b5d244c8012805272e22992212bdbd47716db0d..d24a2ca67dc76cc4ca8909a3fde438c82727192a 100644 (file)
@@ -101,12 +101,30 @@ compareTransfer( uint64_t a_uploaded, uint64_t a_downloaded,
     return 0;
 }
 
+/**
+ * Comparison function for tr_announce_requests.
+ *
+ * The primary key (amount of data transferred) is used to prioritize
+ * tracker announcements of active torrents. The remaining keys are
+ * used to satisfy the uniqueness requirement of a sorted tr_ptrArray.
+ */
 static int
 compareStops( const void * va, const void * vb )
 {
+    int i;
     const tr_announce_request * a = va;
     const tr_announce_request * b = vb;
-    return compareTransfer( a->up, a->down, b->up, b->down);
+
+    /* primary key: volume of data transferred. */
+    if(( i = compareTransfer( a->up, a->down, b->up, b->down)))
+        return i;
+
+    /* secondary key: the torrent's info_hash */
+    if(( i = memcmp( a->info_hash, b->info_hash, SHA_DIGEST_LENGTH )))
+        return i;
+
+    /* tertiary key: the tracker's announec url */
+    return tr_strcmp0( a->url, b->url );
 }
 
 /***
@@ -896,6 +914,8 @@ announce_request_new( const tr_announcer  * announcer,
     return req;
 }
 
+static void announce_request_free( tr_announce_request * req );
+
 void
 tr_announcerRemoveTorrent( tr_announcer * announcer, tr_torrent * tor )
 {
@@ -911,7 +931,11 @@ tr_announcerRemoveTorrent( tr_announcer * announcer, tr_torrent * tor )
             {
                 const tr_announce_event e = TR_ANNOUNCE_EVENT_STOPPED;
                 tr_announce_request * req = announce_request_new( announcer, tor, tier, e );
-                tr_ptrArrayInsertSorted( &announcer->stops, req, compareStops );
+
+                if( tr_ptrArrayFindSorted( &announcer->stops, req, compareStops ) != NULL )
+                    announce_request_free( req );
+                else
+                    tr_ptrArrayInsertSorted( &announcer->stops, req, compareStops );
             }
         }
 
@@ -1112,6 +1136,14 @@ on_announce_done( const tr_announce_response  * response,
     tr_free( data );
 }
 
+static void
+announce_request_free( tr_announce_request * req )
+{
+    tr_free( req->tracker_id_str );
+    tr_free( req->url );
+    tr_free( req );
+}
+
 static void
 announce_request_delegate( tr_announcer               * announcer,
                            tr_announce_request        * request,
@@ -1127,9 +1159,7 @@ announce_request_delegate( tr_announcer               * announcer,
     else
         tr_err( "Unsupported url: %s", request->url );
 
-    tr_free( request->tracker_id_str );
-    tr_free( request->url );
-    tr_free( request );
+    announce_request_free( request );
 }
 
 static void