source: trunk/libtransmission/stats.c @ 6896

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

have tr_buildPath() allocate memory from the heap rather than using an input buffer

  • Property svn:keywords set to Date Rev Author Id
File size: 5.6 KB
Line 
1/*
2 * This file Copyright (C) 2007-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: stats.c 6896 2008-10-14 03:03:29Z charles $
11 */
12
13#include <assert.h>
14
15#include "transmission.h"
16#include "bencode.h"
17#include "platform.h" /* tr_sessionGetConfigDir() */
18#include "stats.h"
19#include "utils.h" /* tr_buildPath */
20
21/***
22****
23***/
24
25struct tr_stats_handle
26{
27    tr_session_stats    single;
28    tr_session_stats    old;
29    time_t              startTime;
30};
31
32static char*
33getOldFilename( const tr_handle * handle )
34{
35    return tr_buildPath( tr_sessionGetConfigDir( handle ), "stats.benc", NULL );
36}
37
38static char*
39getFilename( const tr_handle * handle )
40{
41    return tr_buildPath( tr_sessionGetConfigDir( handle ), "stats.json", NULL );
42}
43
44static void
45loadCumulativeStats( const tr_handle *  handle,
46                     tr_session_stats * setme )
47{
48    int     loaded = FALSE;
49    char   * filename;
50    tr_benc top;
51
52    filename = getFilename( handle );
53    loaded = !tr_bencLoadJSONFile( filename, &top );
54    tr_free( filename );
55
56    if( !loaded )
57    {
58        filename = getOldFilename( handle );
59        loaded = !tr_bencLoadFile( filename, &top );
60        tr_free( filename );
61    }
62
63    if( loaded )
64    {
65        int64_t i;
66
67        if( tr_bencDictFindInt( &top, "downloaded-bytes", &i ) )
68            setme->downloadedBytes = (uint64_t) i;
69        if( tr_bencDictFindInt( &top, "files-added", &i ) )
70            setme->filesAdded = (uint64_t) i;
71        if( tr_bencDictFindInt( &top, "seconds-active", &i ) )
72            setme->secondsActive = (uint64_t) i;
73        if( tr_bencDictFindInt( &top, "session-count", &i ) )
74            setme->sessionCount = (uint64_t) i;
75        if( tr_bencDictFindInt( &top, "uploaded-bytes", &i ) )
76            setme->uploadedBytes = (uint64_t) i;
77
78        tr_bencFree( &top );
79    }
80}
81
82static void
83saveCumulativeStats( const tr_handle *        handle,
84                     const tr_session_stats * s )
85{
86    char * filename;
87    tr_benc top;
88
89    tr_bencInitDict( &top, 5 );
90    tr_bencDictAddInt( &top, "downloaded-bytes", s->downloadedBytes );
91    tr_bencDictAddInt( &top, "files-added",      s->filesAdded );
92    tr_bencDictAddInt( &top, "seconds-active",   s->secondsActive );
93    tr_bencDictAddInt( &top, "session-count",    s->sessionCount );
94    tr_bencDictAddInt( &top, "uploaded-bytes",   s->uploadedBytes );
95
96    filename = getFilename( handle );
97    tr_deepLog( __FILE__, __LINE__, NULL, "Saving stats to \"%s\"", filename );
98    tr_bencSaveJSONFile( filename, &top );
99
100    tr_free( filename );
101    tr_bencFree( &top );
102}
103
104/***
105****
106***/
107
108void
109tr_statsInit( tr_handle * handle )
110{
111    struct tr_stats_handle * stats = tr_new0( struct tr_stats_handle, 1 );
112
113    loadCumulativeStats( handle, &stats->old );
114    stats->single.sessionCount = 1;
115    stats->startTime = time( NULL );
116    handle->sessionStats = stats;
117}
118
119void
120tr_statsClose( tr_handle * handle )
121{
122    tr_session_stats cumulative;
123
124    tr_sessionGetCumulativeStats( handle, &cumulative );
125    saveCumulativeStats( handle, &cumulative );
126
127    tr_free( handle->sessionStats );
128    handle->sessionStats = NULL;
129}
130
131static struct tr_stats_handle *
132getStats( const tr_handle * handle )
133{
134    return handle->sessionStats;
135}
136
137/***
138****
139***/
140
141static void
142updateRatio( tr_session_stats * setme )
143{
144    setme->ratio = tr_getRatio( setme->uploadedBytes,
145                                setme->downloadedBytes );
146}
147
148static void
149addStats( tr_session_stats *       setme,
150          const tr_session_stats * a,
151          const tr_session_stats * b )
152{
153    setme->uploadedBytes   = a->uploadedBytes   + b->uploadedBytes;
154    setme->downloadedBytes = a->downloadedBytes + b->downloadedBytes;
155    setme->filesAdded      = a->filesAdded      + b->filesAdded;
156    setme->sessionCount    = a->sessionCount    + b->sessionCount;
157    setme->secondsActive   = a->secondsActive   + b->secondsActive;
158    updateRatio( setme );
159}
160
161void
162tr_sessionGetStats( const tr_handle *  handle,
163                    tr_session_stats * setme )
164{
165    const struct tr_stats_handle * stats = getStats( handle );
166
167    assert( stats );
168    *setme = stats->single;
169    setme->secondsActive = time( NULL ) - stats->startTime;
170    updateRatio( setme );
171}
172
173void
174tr_sessionGetCumulativeStats( const tr_handle *  handle,
175                              tr_session_stats * setme )
176{
177    const struct tr_stats_handle * stats = getStats( handle );
178    tr_session_stats               current;
179
180    assert( stats );
181    tr_sessionGetStats( handle, &current );
182    addStats( setme, &stats->old, &current );
183}
184
185void
186tr_sessionClearStats( tr_handle * handle )
187{
188    tr_session_stats zero;
189
190    zero.uploadedBytes = 0;
191    zero.downloadedBytes = 0;
192    zero.ratio = TR_RATIO_NA;
193    zero.filesAdded = 0;
194    zero.sessionCount = 0;
195    zero.secondsActive = 0;
196    handle->sessionStats->single = handle->sessionStats->old = zero;
197
198    handle->sessionStats->startTime = time( NULL );
199}
200
201/**
202***
203**/
204
205void
206tr_statsAddUploaded( tr_handle * handle,
207                     uint32_t    bytes )
208{
209    struct tr_stats_handle * s;
210
211    if( ( s = getStats( handle ) ) )
212        s->single.uploadedBytes += bytes;
213}
214
215void
216tr_statsAddDownloaded( tr_handle * handle,
217                       uint32_t    bytes )
218{
219    struct tr_stats_handle * s;
220
221    if( ( s = getStats( handle ) ) )
222        s->single.downloadedBytes += bytes;
223}
224
225void
226tr_statsFileCreated( tr_handle * handle )
227{
228    struct tr_stats_handle * s;
229
230    if( ( s = getStats( handle ) ) )
231        s->single.filesAdded++;
232}
233
Note: See TracBrowser for help on using the repository browser.