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"
16 #include "platform.h" /* tr_sessionGetConfigDir() */
18 #include "utils.h" /* tr_buildPath */
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
;
36 getOldFilename( const tr_session
* session
)
38 return tr_buildPath( tr_sessionGetConfigDir( session
), "stats.benc", NULL
);
42 getFilename( const tr_session
* session
)
44 return tr_buildPath( tr_sessionGetConfigDir( session
), "stats.json", NULL
);
48 loadCumulativeStats( const tr_session
* session
,
49 tr_session_stats
* setme
)
55 filename
= getFilename( session
);
56 loaded
= !tr_bencLoadFile( &top
, TR_FMT_JSON
, filename
);
61 filename
= getOldFilename( session
);
62 loaded
= !tr_bencLoadFile( &top
, TR_FMT_BENC
, filename
);
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
;
86 saveCumulativeStats( const tr_session
* session
,
87 const tr_session_stats
* s
)
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
);
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
;
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
);
142 tr_statsClose( tr_session
* session
)
144 tr_statsSaveDirty( session
);
146 tr_free( session
->sessionStats
);
147 session
->sessionStats
= NULL
;
155 updateRatio( tr_session_stats
* setme
)
157 setme
->ratio
= tr_getRatio( setme
->uploadedBytes
,
158 setme
->downloadedBytes
);
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
);
175 tr_sessionGetStats( const tr_session
* session
,
176 tr_session_stats
* setme
)
178 const struct tr_stats_handle
* stats
= getStats( session
);
181 *setme
= stats
->single
;
182 setme
->secondsActive
= tr_time( ) - stats
->startTime
;
183 updateRatio( setme
);
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
;
196 tr_sessionGetStats( session
, ¤t
);
197 addStats( setme
, &stats
->old
, ¤t
);
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
;
210 zero
.sessionCount
= 0;
211 zero
.secondsActive
= 0;
213 session
->sessionStats
->single
= session
->sessionStats
->old
= zero
;
214 session
->sessionStats
->startTime
= tr_time( );
222 tr_statsAddUploaded( tr_session
* session
,
225 struct tr_stats_handle
* s
;
227 if( ( s
= getStats( session
) ) )
229 s
->single
.uploadedBytes
+= bytes
;
235 tr_statsAddDownloaded( tr_session
* session
,
238 struct tr_stats_handle
* s
;
240 if( ( s
= getStats( session
) ) )
242 s
->single
.downloadedBytes
+= bytes
;
248 tr_statsFileCreated( tr_session
* session
)
250 struct tr_stats_handle
* s
;
252 if( ( s
= getStats( session
) ) )
253 s
->single
.filesAdded
++;