1
0
Fork 0
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:
Charles Kerr 2008-12-22 19:16:06 +00:00
parent 55f263312f
commit 5d1c109fc4
3 changed files with 159 additions and 6 deletions

View file

@ -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 );
}
}

View file

@ -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 */

View file

@ -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 );
}