Revert "transmission: update from 2.13 to 2.22"
[tomato.git] / release / src / router / transmission / libtransmission / stats.c
blob7b74b2ce125c71f82853d767a89b0c6aa0a4b35c
1 /*
2 * This file Copyright (C) 2007-2010 Mnemosyne LLC
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.
10 * $Id: stats.c 9973 2010-01-20 18:48:52Z charles $
13 #include "transmission.h"
14 #include "session.h"
15 #include "bencode.h"
16 #include "platform.h" /* tr_sessionGetConfigDir() */
17 #include "stats.h"
18 #include "utils.h" /* tr_buildPath */
20 /***
21 ****
22 ***/
24 static const struct tr_session_stats STATS_INIT = { 0.0f, 0, 0, 0, 0, 0 };
26 /** @brief Opaque, per-session data structure for bandwidth use statistics */
27 struct tr_stats_handle
29 tr_session_stats single;
30 tr_session_stats old;
31 time_t startTime;
32 tr_bool isDirty;
35 static char*
36 getOldFilename( const tr_session * session )
38 return tr_buildPath( tr_sessionGetConfigDir( session ), "stats.benc", NULL );
41 static char*
42 getFilename( const tr_session * session )
44 return tr_buildPath( tr_sessionGetConfigDir( session ), "stats.json", NULL );
47 static void
48 loadCumulativeStats( const tr_session * session,
49 tr_session_stats * setme )
51 int loaded = FALSE;
52 char * filename;
53 tr_benc top;
55 filename = getFilename( session );
56 loaded = !tr_bencLoadFile( &top, TR_FMT_JSON, filename );
57 tr_free( filename );
59 if( !loaded )
61 filename = getOldFilename( session );
62 loaded = !tr_bencLoadFile( &top, TR_FMT_BENC, filename );
63 tr_free( filename );
66 if( loaded )
68 int64_t i;
70 if( tr_bencDictFindInt( &top, "downloaded-bytes", &i ) )
71 setme->downloadedBytes = (uint64_t) i;
72 if( tr_bencDictFindInt( &top, "files-added", &i ) )
73 setme->filesAdded = (uint64_t) i;
74 if( tr_bencDictFindInt( &top, "seconds-active", &i ) )
75 setme->secondsActive = (uint64_t) i;
76 if( tr_bencDictFindInt( &top, "session-count", &i ) )
77 setme->sessionCount = (uint64_t) i;
78 if( tr_bencDictFindInt( &top, "uploaded-bytes", &i ) )
79 setme->uploadedBytes = (uint64_t) i;
81 tr_bencFree( &top );
85 static void
86 saveCumulativeStats( const tr_session * session,
87 const tr_session_stats * s )
89 char * filename;
90 tr_benc top;
92 tr_bencInitDict( &top, 5 );
93 tr_bencDictAddInt( &top, "downloaded-bytes", s->downloadedBytes );
94 tr_bencDictAddInt( &top, "files-added", s->filesAdded );
95 tr_bencDictAddInt( &top, "seconds-active", s->secondsActive );
96 tr_bencDictAddInt( &top, "session-count", s->sessionCount );
97 tr_bencDictAddInt( &top, "uploaded-bytes", s->uploadedBytes );
99 filename = getFilename( session );
100 tr_deepLog( __FILE__, __LINE__, NULL, "Saving stats to \"%s\"", filename );
101 tr_bencToFile( &top, TR_FMT_JSON, filename );
103 tr_free( filename );
104 tr_bencFree( &top );
107 /***
108 ****
109 ***/
111 void
112 tr_statsInit( tr_session * session )
114 struct tr_stats_handle * stats = tr_new0( struct tr_stats_handle, 1 );
116 loadCumulativeStats( session, &stats->old );
117 stats->single.sessionCount = 1;
118 stats->startTime = tr_time( );
119 session->sessionStats = stats;
122 static struct tr_stats_handle *
123 getStats( const tr_session * session )
125 return session ? session->sessionStats : NULL;
128 void
129 tr_statsSaveDirty( tr_session * session )
131 struct tr_stats_handle * h = getStats( session );
132 if( ( h != NULL ) && h->isDirty )
134 tr_session_stats cumulative = STATS_INIT;
135 tr_sessionGetCumulativeStats( session, &cumulative );
136 saveCumulativeStats( session, &cumulative );
137 h->isDirty = FALSE;
141 void
142 tr_statsClose( tr_session * session )
144 tr_statsSaveDirty( session );
146 tr_free( session->sessionStats );
147 session->sessionStats = NULL;
150 /***
151 ****
152 ***/
154 static void
155 updateRatio( tr_session_stats * setme )
157 setme->ratio = tr_getRatio( setme->uploadedBytes,
158 setme->downloadedBytes );
161 static void
162 addStats( tr_session_stats * setme,
163 const tr_session_stats * a,
164 const tr_session_stats * b )
166 setme->uploadedBytes = a->uploadedBytes + b->uploadedBytes;
167 setme->downloadedBytes = a->downloadedBytes + b->downloadedBytes;
168 setme->filesAdded = a->filesAdded + b->filesAdded;
169 setme->sessionCount = a->sessionCount + b->sessionCount;
170 setme->secondsActive = a->secondsActive + b->secondsActive;
171 updateRatio( setme );
174 void
175 tr_sessionGetStats( const tr_session * session,
176 tr_session_stats * setme )
178 const struct tr_stats_handle * stats = getStats( session );
179 if( stats )
181 *setme = stats->single;
182 setme->secondsActive = tr_time( ) - stats->startTime;
183 updateRatio( setme );
187 void
188 tr_sessionGetCumulativeStats( const tr_session * session,
189 tr_session_stats * setme )
191 const struct tr_stats_handle * stats = getStats( session );
192 tr_session_stats current = STATS_INIT;
194 if( stats )
196 tr_sessionGetStats( session, &current );
197 addStats( setme, &stats->old, &current );
201 void
202 tr_sessionClearStats( tr_session * session )
204 tr_session_stats zero;
206 zero.uploadedBytes = 0;
207 zero.downloadedBytes = 0;
208 zero.ratio = TR_RATIO_NA;
209 zero.filesAdded = 0;
210 zero.sessionCount = 0;
211 zero.secondsActive = 0;
213 session->sessionStats->single = session->sessionStats->old = zero;
214 session->sessionStats->startTime = tr_time( );
221 void
222 tr_statsAddUploaded( tr_session * session,
223 uint32_t bytes )
225 struct tr_stats_handle * s;
227 if( ( s = getStats( session ) ) )
229 s->single.uploadedBytes += bytes;
230 s->isDirty = TRUE;
234 void
235 tr_statsAddDownloaded( tr_session * session,
236 uint32_t bytes )
238 struct tr_stats_handle * s;
240 if( ( s = getStats( session ) ) )
242 s->single.downloadedBytes += bytes;
243 s->isDirty = TRUE;
247 void
248 tr_statsFileCreated( tr_session * session )
250 struct tr_stats_handle * s;
252 if( ( s = getStats( session ) ) )
253 s->single.filesAdded++;