source: trunk/libtransmission/bandwidth.c @ 7148

Last change on this file since 7148 was 7148, checked in by charles, 12 years ago

oops, turn off a debugging message

File size: 3.3 KB
Line 
1/*
2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.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 <limits.h>
14#include "transmission.h"
15#include "bandwidth.h"
16#include "utils.h"
17
18/***
19****
20***/
21
22enum
23{
24    HISTORY_MSEC = 2000,
25    INTERVAL_MSEC = HISTORY_MSEC,
26    GRANULARITY_MSEC = 250,
27    HISTORY_SIZE = ( INTERVAL_MSEC / GRANULARITY_MSEC )
28};
29
30struct bratecontrol
31{
32    int newest;
33    struct { uint64_t date, size; } transfers[HISTORY_SIZE];
34};
35
36static float
37getSpeed( const struct bratecontrol * r )
38{
39    const uint64_t interval_msec = HISTORY_MSEC;
40    uint64_t       bytes = 0;
41    const uint64_t cutoff = tr_date ( ) - interval_msec;
42    int            i = r->newest;
43
44    for( ;; )
45    {
46        if( r->transfers[i].date <= cutoff )
47            break;
48
49        bytes += r->transfers[i].size;
50
51        if( --i == -1 ) i = HISTORY_SIZE - 1; /* circular history */
52        if( i == r->newest ) break; /* we've come all the way around */
53    }
54
55    return ( bytes / 1024.0 ) * ( 1000.0 / interval_msec );
56}
57
58static void
59bytesUsed( struct bratecontrol * r, size_t size )
60{
61    const uint64_t now = tr_date ( );
62
63    if( r->transfers[r->newest].date + GRANULARITY_MSEC >= now )
64        r->transfers[r->newest].size += size;
65    else
66    {
67        if( ++r->newest == HISTORY_SIZE ) r->newest = 0;
68        r->transfers[r->newest].date = now;
69        r->transfers[r->newest].size = size;
70    }
71}
72
73/******
74*******
75*******
76******/
77
78struct tr_bandwidth
79{
80    unsigned int isLimited : 1;
81
82    size_t bytesLeft;
83
84    struct bratecontrol raw;
85    struct bratecontrol piece;
86
87    tr_session * session;
88};
89
90/***
91****
92***/
93
94tr_bandwidth*
95tr_bandwidthNew( tr_session * session )
96{
97    tr_bandwidth * b = tr_new0( tr_bandwidth, 1 );
98    b->session = session;
99    return b;
100}
101
102void
103tr_bandwidthFree( tr_bandwidth * b )
104{
105    tr_free( b );
106}
107
108/***
109****
110***/
111
112void
113tr_bandwidthSetLimited( tr_bandwidth  * b,
114                        size_t          bytesLeft )
115{
116    b->isLimited = 1;
117    b->bytesLeft = bytesLeft;
118}
119
120void
121tr_bandwidthSetUnlimited( tr_bandwidth * b )
122{
123    b->isLimited = 0;
124}
125
126size_t
127tr_bandwidthClamp( const tr_bandwidth  * b,
128                   size_t                byteCount )
129{
130/* const size_t n = byteCount; */
131
132    if( b && b->isLimited )
133        byteCount = MIN( byteCount, b->bytesLeft );
134
135/* if( n != byteCount ) fprintf( stderr, "%p: %zu clamped to %zu\n", b, n, byteCount ); */
136    return byteCount;
137}
138
139/***
140****
141***/
142
143double
144tr_bandwidthGetRawSpeed( const tr_bandwidth * b )
145{
146    return getSpeed( &b->raw );
147}
148
149double
150tr_bandwidthGetPieceSpeed( const tr_bandwidth * b UNUSED )
151{
152    return getSpeed( &b->piece );
153}
154
155void
156tr_bandwidthUsed( tr_bandwidth  * b,
157                  size_t          byteCount,
158                  int             isPieceData )
159{
160    if( b->isLimited && isPieceData )
161    {
162        b->bytesLeft -= MIN( b->bytesLeft, byteCount );
163        /* fprintf( stderr, "%p used %zu bytes ... %zu left\n", b, byteCount, b->bytesLeft ); */
164    }
165
166    bytesUsed( &b->raw, byteCount );
167
168    if( isPieceData )
169        bytesUsed( &b->piece, byteCount );
170}
Note: See TracBrowser for help on using the repository browser.