source: trunk/libtransmission/request-list.c @ 8050

Last change on this file since 8050 was 7622, checked in by charles, 13 years ago

(trunk libT) fix the new-code errors reported by ZogG and Rolcol and Spaham

File size: 4.0 KB
Line 
1/*
2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id:$
11 */
12
13#include <assert.h>
14#include "transmission.h"
15#include "request-list.h"
16#include "utils.h"
17
18static int
19compareRequests( const struct peer_request * a,
20                 const struct peer_request * b )
21{
22    if( a->index != b->index )
23        return a->index < b->index ? -1 : 1;
24
25    if( a->offset != b->offset )
26        return a->offset < b->offset ? -1 : 1;
27
28    return 0;
29}
30
31const struct request_list REQUEST_LIST_INIT = { 0, 0, NULL, NULL };
32
33static const int GROW = 8;
34
35static void
36reqListReserve( struct request_list * list, size_t max )
37{
38    if( list->max < max )
39    {
40        list->max = max + GROW;
41        list->fifo = tr_renew( struct peer_request, list->fifo, list->max );
42        list->sort = tr_renew( struct peer_request, list->sort, list->max );
43    }
44}
45
46void
47reqListClear( struct request_list * list )
48{
49    tr_free( list->fifo );
50    tr_free( list->sort );
51    *list = REQUEST_LIST_INIT;
52}
53
54void
55reqListCopy( struct request_list * dest, const struct request_list * src )
56{
57    dest->len = dest->max = src->len;
58    dest->fifo = tr_memdup( src->fifo, dest->len * sizeof( struct peer_request ) );
59    dest->sort = tr_memdup( src->sort, dest->len * sizeof( struct peer_request ) );
60}
61
62typedef int (*compareFunc)(const void * a, const void * b );
63
64static int
65reqListSortPos( const struct request_list * list,
66                const struct peer_request * req,
67                tr_bool                   * exactMatch )
68{
69    return tr_lowerBound( req,
70                          list->sort,
71                          list->len,
72                          sizeof( struct peer_request ), 
73                          (compareFunc)compareRequests,
74                          exactMatch );
75}
76
77void
78reqListAppend( struct request_list *       list,
79               const struct peer_request * req )
80{
81    int low;
82
83    reqListReserve( list, list->len + 8 );
84
85    /* append into list->fifo */
86    list->fifo[list->len] = *req;
87
88    /* insert into list->sort */
89    low = reqListSortPos( list, req, NULL );
90    memmove( &list->sort[low+1], &list->sort[low], (list->len-low)*sizeof(struct peer_request) );
91    list->sort[low] = *req;
92
93    ++list->len;
94}
95
96static tr_bool
97reqListRemoveFromSorted( struct request_list * list, const struct peer_request * key )
98{
99    tr_bool found;
100    const int low = reqListSortPos( list, key, &found );
101    if( found )
102        memmove( &list->sort[low], &list->sort[low+1], (list->len-low-1)*sizeof(struct peer_request));
103    return found;
104}
105
106static void
107reqListRemoveNthFromFifo( struct request_list * list, int n )
108{
109    memmove( &list->fifo[n], &list->fifo[n+1], (list->len-n-1)*sizeof(struct peer_request));
110}
111
112tr_bool
113reqListPop( struct request_list * list,
114            struct peer_request * setme )
115{
116    tr_bool success;
117
118    if( !list->len )
119    {
120        success = FALSE;
121    }
122    else
123    {
124        *setme = list->fifo[0];
125        reqListRemoveNthFromFifo( list, 0 );
126        reqListRemoveFromSorted( list, setme );
127        --list->len;
128        success = TRUE;
129    }
130
131    return success;
132}
133
134tr_bool
135reqListHas( const struct request_list * list,
136            const struct peer_request * key )
137{
138    tr_bool exactMatch;
139    reqListSortPos( list, key, &exactMatch );
140    return exactMatch;
141}
142
143tr_bool
144reqListRemove( struct request_list       * list,
145               const struct peer_request * key )
146{
147    tr_bool found = reqListRemoveFromSorted( list, key );
148
149    if( found )
150    {
151        size_t i;
152        for( i=0; i<list->len; ++i )
153            if( !compareRequests( &list->fifo[i], key ) )
154                break;
155        assert( i < list->len );
156        reqListRemoveNthFromFifo( list, i );
157        --list->len;
158    }
159
160    return found;
161}
Note: See TracBrowser for help on using the repository browser.