mirror of
https://github.com/transmission/transmission
synced 2024-12-25 17:17:31 +00:00
(trunk libT) speed improvments from wereHamster
This commit is contained in:
parent
55f263312f
commit
5d1c109fc4
3 changed files with 159 additions and 6 deletions
|
@ -158,3 +158,63 @@ tr_list_size( const tr_list * list )
|
|||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Double-linked list with easy memory management and fast
|
||||
* insert/remove operations
|
||||
*/
|
||||
|
||||
void
|
||||
__tr_list_init( struct __tr_list * head )
|
||||
{
|
||||
head->next = head;
|
||||
head->prev = head;
|
||||
}
|
||||
|
||||
void
|
||||
__tr_list_insert( struct __tr_list * list,
|
||||
struct __tr_list * prev,
|
||||
struct __tr_list * next)
|
||||
{
|
||||
next->prev = list;
|
||||
list->next = next;
|
||||
list->prev = prev;
|
||||
prev->next = list;
|
||||
}
|
||||
|
||||
void
|
||||
__tr_list_splice( struct __tr_list * prev,
|
||||
struct __tr_list * next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__tr_list_append( struct __tr_list * head,
|
||||
struct __tr_list * list)
|
||||
{
|
||||
__tr_list_insert( list, head->prev, head );
|
||||
}
|
||||
|
||||
void
|
||||
__tr_list_remove( struct __tr_list * head )
|
||||
{
|
||||
__tr_list_splice( head->prev, head->next );
|
||||
head->next = head->prev = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
__tr_list_destroy( struct __tr_list * head,
|
||||
__tr_list_free_t func)
|
||||
{
|
||||
while ( head->next != head )
|
||||
{
|
||||
struct __tr_list * list = head->next;
|
||||
__tr_list_splice( list->prev, list->next );
|
||||
|
||||
func( list );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,5 +52,80 @@ tr_list* tr_list_find( tr_list * list,
|
|||
const void * b,
|
||||
TrListCompareFunc compare_func );
|
||||
|
||||
|
||||
/*
|
||||
* Double-linked list with easy memory management and fast
|
||||
* insert/remove operations
|
||||
*/
|
||||
|
||||
struct __tr_list
|
||||
{
|
||||
struct __tr_list * next, * prev;
|
||||
};
|
||||
|
||||
#define __tr_list_entry(ptr, type, member) ({ \
|
||||
const struct __tr_list *__mptr = (ptr); \
|
||||
(void *)( (char *)__mptr - offsetof(type,member) ); \
|
||||
})
|
||||
|
||||
typedef int ( *__tr_list_cmp_t ) ( const void * a, const void * b );
|
||||
typedef void ( *__tr_list_free_t )( void * );
|
||||
|
||||
|
||||
/**
|
||||
* __tr_list_init()
|
||||
*
|
||||
* Init @head as an empty list.
|
||||
*/
|
||||
void
|
||||
__tr_list_init( struct __tr_list * head );
|
||||
|
||||
|
||||
/**
|
||||
* __tr_list_insert()
|
||||
*
|
||||
* Insert @list between @prev and @next.
|
||||
*/
|
||||
void
|
||||
__tr_list_insert( struct __tr_list * list,
|
||||
struct __tr_list * prev,
|
||||
struct __tr_list * next);
|
||||
|
||||
/**
|
||||
* __tr_list_splice()
|
||||
*
|
||||
* Connect @prev with @next, removing any nodes that were
|
||||
* in between.
|
||||
*/
|
||||
void
|
||||
__tr_list_splice( struct __tr_list * prev,
|
||||
struct __tr_list * next);
|
||||
|
||||
/**
|
||||
* __tr_list_append()
|
||||
*
|
||||
* Append @list to the end of @head.
|
||||
*/
|
||||
void
|
||||
__tr_list_append( struct __tr_list * head,
|
||||
struct __tr_list * list);
|
||||
|
||||
/**
|
||||
* __tr_list_remove()
|
||||
*
|
||||
* Remove @head from the list it is in.
|
||||
*/
|
||||
void
|
||||
__tr_list_remove( struct __tr_list * head );
|
||||
|
||||
/**
|
||||
* __tr_list_destroy()
|
||||
*
|
||||
* Destroy the list and free all nodes
|
||||
*/
|
||||
void
|
||||
__tr_list_destroy( struct __tr_list * head,
|
||||
__tr_list_free_t func);
|
||||
|
||||
#endif /* TR_LIST_H */
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ struct tr_datatype
|
|||
{
|
||||
tr_bool isPieceData;
|
||||
size_t length;
|
||||
struct __tr_list head;
|
||||
};
|
||||
|
||||
struct tr_peerIo
|
||||
|
@ -106,7 +107,7 @@ struct tr_peerIo
|
|||
|
||||
struct evbuffer * inbuf;
|
||||
struct evbuffer * outbuf;
|
||||
tr_list * outbuf_datatypes; /* struct tr_datatype */
|
||||
struct __tr_list outbuf_datatypes; /* struct tr_datatype */
|
||||
|
||||
struct event event_read;
|
||||
struct event event_write;
|
||||
|
@ -121,7 +122,8 @@ didWriteWrapper( tr_peerIo * io, size_t bytes_transferred )
|
|||
{
|
||||
while( bytes_transferred )
|
||||
{
|
||||
struct tr_datatype * next = io->outbuf_datatypes->data;
|
||||
struct tr_datatype * next = __tr_list_entry( io->outbuf_datatypes.next,
|
||||
struct tr_datatype, head );
|
||||
const size_t payload = MIN( next->length, bytes_transferred );
|
||||
const size_t overhead = getPacketOverhead( payload );
|
||||
|
||||
|
@ -135,8 +137,10 @@ didWriteWrapper( tr_peerIo * io, size_t bytes_transferred )
|
|||
|
||||
bytes_transferred -= payload;
|
||||
next->length -= payload;
|
||||
if( !next->length )
|
||||
tr_free( tr_list_pop_front( &io->outbuf_datatypes ) );
|
||||
if( !next->length ) {
|
||||
__tr_list_remove( io->outbuf_datatypes.next );
|
||||
tr_free( next );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,9 +364,14 @@ tr_peerIoNew( tr_session * session,
|
|||
io->timeCreated = time( NULL );
|
||||
io->inbuf = evbuffer_new( );
|
||||
io->outbuf = evbuffer_new( );
|
||||
|
||||
event_set( &io->event_read, io->socket, EV_READ, event_read_cb, io );
|
||||
event_set( &io->event_write, io->socket, EV_WRITE, event_write_cb, io );
|
||||
|
||||
__tr_list_init( &io->outbuf_datatypes );
|
||||
|
||||
tr_peerIoSetBandwidth( io, session->bandwidth );
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
|
@ -398,6 +407,13 @@ tr_peerIoNewOutgoing( tr_session * session,
|
|||
: tr_peerIoNew( session, addr, port, torrentHash, 0, socket );
|
||||
}
|
||||
|
||||
static void
|
||||
trDatatypeFree( void * data )
|
||||
{
|
||||
struct tr_datatype * dt = __tr_list_entry( data, struct tr_datatype, head );
|
||||
tr_free(dt);
|
||||
}
|
||||
|
||||
static void
|
||||
io_dtor( void * vio )
|
||||
{
|
||||
|
@ -410,7 +426,7 @@ io_dtor( void * vio )
|
|||
evbuffer_free( io->inbuf );
|
||||
tr_netClose( io->socket );
|
||||
tr_cryptoFree( io->crypto );
|
||||
tr_list_free( &io->outbuf_datatypes, tr_free );
|
||||
__tr_list_destroy( &io->outbuf_datatypes, trDatatypeFree );
|
||||
|
||||
io->magicNumber = 0xDEAD;
|
||||
tr_free( io );
|
||||
|
@ -701,7 +717,9 @@ tr_peerIoWrite( tr_peerIo * io,
|
|||
datatype = tr_new( struct tr_datatype, 1 );
|
||||
datatype->isPieceData = isPieceData != 0;
|
||||
datatype->length = writemeLen;
|
||||
tr_list_append( &io->outbuf_datatypes, datatype );
|
||||
|
||||
__tr_list_init( &datatype->head );
|
||||
__tr_list_append( &io->outbuf_datatypes, &datatype->head );
|
||||
|
||||
evbuffer_add( io->outbuf, writeme, writemeLen );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue