source: trunk/libtransmission/stats.c @ 3978

Last change on this file since 3978 was 3978, checked in by livings124, 15 years ago

avoid divide-by-0 in stats

File size: 5.4 KB
Line 
1/*
2 * This file Copyright (C) 2007 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: peer-msgs.c 3906 2007-11-20 17:29:56Z charles $
11 */
12
13#include <string.h> /* memset */
14
15#include "transmission.h"
16#include "bencode.h"
17#include "platform.h" /* tr_getPrefsDirectory */
18#include "utils.h" /* tr_buildPath */
19
20/***
21****
22***/
23
24struct tr_stats_handle
25{
26    tr_session_stats single;
27    tr_session_stats cumulative;
28    uint32_t bytes_up;
29    uint32_t bytes_down;
30    time_t startTime;
31};
32
33static void
34parseCumulativeStats( tr_session_stats  * setme,
35                      const uint8_t     * content,
36                      size_t              len )
37{
38    benc_val_t top;
39
40    if( !tr_bencLoad( content, len, &top, NULL ) )
41    {
42        const benc_val_t * val;
43
44        if(( val = tr_bencDictFindType( &top, "uploaded-mib", TYPE_INT )))
45            setme->uploadedMiB = (uint64_t) tr_bencGetInt( val );
46
47        if(( val = tr_bencDictFindType( &top, "downloaded-mib", TYPE_INT )))
48            setme->downloadedMiB = (uint64_t) tr_bencGetInt( val );
49
50        if(( val = tr_bencDictFindType( &top, "files-added", TYPE_INT )))
51            setme->filesAdded = (uint64_t) tr_bencGetInt( val );
52
53        if(( val = tr_bencDictFindType( &top, "session-count", TYPE_INT )))
54            setme->sessionCount = (uint64_t) tr_bencGetInt( val );
55
56        if(( val = tr_bencDictFindType( &top, "seconds-active", TYPE_INT )))
57            setme->secondsActive = (uint64_t) tr_bencGetInt( val );
58
59        tr_bencFree( &top );
60    }
61}
62
63static char*
64getFilename( char * buf, size_t buflen )
65{
66    tr_buildPath( buf, buflen, tr_getPrefsDirectory(), "stats.benc", NULL );
67    return buf;
68}
69
70static void
71loadCumulativeStats( tr_session_stats * setme )
72{
73    size_t len;
74    uint8_t * content;
75    char filename[MAX_PATH_LENGTH];
76
77    getFilename( filename, sizeof(filename) );
78    content = tr_loadFile( filename, &len );
79    if( content != NULL )
80        parseCumulativeStats( setme, content, len );
81
82    tr_free( content );
83}
84
85static void
86saveCumulativeStats( const tr_session_stats * stats )
87{
88    FILE * fp;
89    char * str;
90    char filename[MAX_PATH_LENGTH];
91    int len;
92    benc_val_t top, *val;
93
94    tr_bencInit( &top, TYPE_DICT );
95    tr_bencDictReserve( &top, 5 );
96    tr_bencInitInt( tr_bencDictAdd( &top, "uploaded-mib" ), stats->uploadedMiB );
97    tr_bencInitInt( tr_bencDictAdd( &top, "downloaded-mib" ), stats->downloadedMiB );
98    tr_bencInitInt( tr_bencDictAdd( &top, "files-added" ), stats->filesAdded );
99    tr_bencInitInt( tr_bencDictAdd( &top, "session-count" ), stats->sessionCount );
100    tr_bencInitInt( tr_bencDictAdd( &top, "seconds-active" ), stats->secondsActive );
101
102    str = tr_bencSave( &top, &len );
103    getFilename( filename, sizeof(filename) );
104    fp = fopen( filename, "wb+" );
105    fwrite( str, 1, len, fp );
106    fclose( fp );
107    tr_free( str );
108
109    tr_bencFree( &top );
110}
111
112/***
113****
114***/
115
116void
117tr_statsInit( tr_handle * handle )
118{
119    struct tr_stats_handle * stats = tr_new0( struct tr_stats_handle, 1 );
120    loadCumulativeStats( &stats->cumulative );
121    stats->cumulative.sessionCount++;
122    stats->startTime = time(NULL);
123    handle->sessionStats = stats;
124}
125
126void
127tr_statsClose( tr_handle * handle )
128{
129    tr_session_stats tmp;
130    tr_getCumulativeSessionStats( handle, &tmp );
131    saveCumulativeStats( &tmp );
132
133    tr_free( handle->sessionStats );
134    handle->sessionStats = NULL;
135}
136
137void
138tr_getSessionStats( const tr_handle   * handle,
139                    tr_session_stats  * setme )
140{
141    const struct tr_stats_handle * stats = handle->sessionStats;
142    *setme = stats->single;
143    setme->ratio = setme->downloadedMiB ? (double)setme->uploadedMiB / (double)setme->downloadedMiB : TR_RATIO_NA;
144    setme->secondsActive += (time(NULL) - stats->startTime );
145}
146
147void
148tr_getCumulativeSessionStats( const tr_handle   * handle,
149                              tr_session_stats  * setme )
150{
151    const struct tr_stats_handle * stats = handle->sessionStats;
152    *setme = stats->cumulative;
153    setme->ratio = setme->downloadedMiB ? (double)setme->uploadedMiB / (double)setme->downloadedMiB : TR_RATIO_NA;
154    setme->secondsActive += (time(NULL) - stats->startTime );
155}
156
157/**
158***
159**/
160
161#define MiB 1048576
162
163void
164tr_statsAddUploaded( tr_handle * handle, uint32_t bytes )
165{
166    struct tr_stats_handle * stats = handle->sessionStats;
167    stats->bytes_up += bytes;
168    if( stats->bytes_up >= MiB )
169    {
170        const uint32_t megs = stats->bytes_up / MiB;
171        stats->bytes_up %= MiB;
172        stats->single.uploadedMiB += megs;
173        stats->cumulative.uploadedMiB += megs;
174    }
175}
176
177void
178tr_statsAddDownloaded( tr_handle * handle, uint32_t bytes )
179{
180    struct tr_stats_handle * stats = handle->sessionStats;
181    stats->bytes_down += bytes;
182    if( stats->bytes_down >= MiB )
183    {
184        const uint32_t megs = stats->bytes_down / MiB;
185        stats->bytes_down %= MiB;
186        stats->single.downloadedMiB += megs;
187        stats->cumulative.downloadedMiB += megs;
188    }
189}
190
191void
192tr_torrentAdded( tr_handle * handle, const tr_torrent * torrent )
193{
194    struct tr_stats_handle * stats = handle->sessionStats;
195    stats->cumulative.filesAdded += torrent->info.fileCount;
196    stats->single.filesAdded += torrent->info.fileCount;
197}
Note: See TracBrowser for help on using the repository browser.