2626import java .util .concurrent .locks .ReentrantLock ;
2727
2828import de .binfalse .bflog .LOGGER ;
29+ import de .unirostock .sems .cbarchive .web .dataholder .StatisticData ;
2930import de .unirostock .sems .cbarchive .web .dataholder .Workspace ;
3031
3132public class QuotaManager {
@@ -49,6 +50,12 @@ public static QuotaManager getInstance() {
4950 protected Map <String , Long > workspaceCache = new HashMap <String , Long >();
5051 protected WorkspaceManager workspaceManager = null ;
5152 protected long totalSize = 0L ;
53+
54+ protected Thread workerThread = null ;
55+ protected long workerExecutionTime = 0L ;
56+
57+ protected StatisticData stats = null ;
58+ protected Date statsTimestamp = null ;
5259
5360 private QuotaManager () {
5461
@@ -71,7 +78,10 @@ public long getTotalSize() {
7178 */
7279 public void forceAsyncScan ( boolean storeSettingsAfterwards ) {
7380
74- new Thread ( new Worker (this , storeSettingsAfterwards ) ).start ();
81+ if ( workerThread == null || workerThread .isAlive () == false ) {
82+ workerThread = new Thread ( new Worker (this , storeSettingsAfterwards ) );
83+ workerThread .start ();
84+ }
7585
7686 }
7787
@@ -103,7 +113,33 @@ public long updateWorkspace( String workspaceId ) {
103113 else
104114 return updateWorkspace ( workspace );
105115 }
106-
116+
117+ public StatisticData getStats () {
118+
119+ // if cache is ok
120+ if ( stats != null && statsTimestamp != null && (new Date ().getTime () - statsTimestamp .getTime () + workerExecutionTime )/1000 < Fields .MAX_STATS_AGE )
121+ return stats ;
122+ else {
123+ generateStats ();
124+ return stats ;
125+ }
126+ }
127+
128+ private void generateStats () {
129+
130+ if ( (workerThread == null || workerThread .isAlive () == false ) && workerLock .tryLock () ) {
131+ workerThread = new Thread ( new Worker (this , true ) );
132+ workerLock .unlock ();
133+ workerThread .start ();
134+ }
135+
136+ // wait for the thread to finish
137+ while ( workerThread .isAlive () ) {
138+ workerLock .lock ();
139+ }
140+ workerLock .unlock ();
141+ }
142+
107143 /**
108144 * Updates the size of the workspace
109145 * @param workspace
@@ -170,6 +206,7 @@ public Worker( QuotaManager quotaManager, boolean storeSettingsAfterwards ) {
170206
171207 @ Override
172208 public void run () {
209+ long startTime = new Date ().getTime ();
173210
174211 // runs only once per time
175212 if ( quotaManager .workerLock .tryLock () == false )
@@ -178,29 +215,60 @@ public void run() {
178215 LOGGER .info ("start full quota scan" );
179216
180217 // scan all workspaces
181- long totalSize = 0 ;
182- long size = 0 ;
218+ long totalSize = 0L ;
219+ long totalArchiveCount = 0L ;
220+ long totalWorkspaceAge = 0L ;
221+ long workspaceCount = 0L ;
183222 Map <String , Long > cache = new HashMap <String , Long >();
223+ Date now = new Date ();
224+ long nowTime = now .getTime ();
184225
185226 // clone collection in order to not get the iterator broken by some manipulations form other threads
186227 List <Workspace > collection = new ArrayList <Workspace >( quotaManager .workspaceManager .workspaces .values () );
187228 for ( Workspace workspace : collection ) {
188229
189- size = quotaManager .scanWorkspace (workspace );
190- if ( size > 0 )
230+ long size = quotaManager .scanWorkspace (workspace );
231+ if ( size > 0 ) {
191232 cache .put ( workspace .getWorkspaceId (), size );
192- totalSize += size ;
233+
234+ totalSize += size ;
235+ totalArchiveCount += workspace .getArchives ().size ();
236+ totalWorkspaceAge += (nowTime - workspace .getLastseen ().getTime ())/1000 ;
237+ workspaceCount ++;
238+ }
193239 }
194240
241+ // generate stats
242+ StatisticData stats = new StatisticData ();
243+ stats .setGenerated (now );
244+
245+ stats .setTotalSize (totalSize );
246+ stats .setWorkspaceCount (workspaceCount );
247+ stats .setSizePerWorkspace ( (double ) totalSize / (double ) workspaceCount );
248+ stats .setArchivesPerWorkspace ( (double ) totalArchiveCount / (double ) workspaceCount );
249+ stats .setAvgWorkspaceAge ( (double ) totalWorkspaceAge / (double ) workspaceCount );
250+
251+ if ( Fields .QUOTA_WORKSPACE_SIZE != Fields .QUOTA_UNLIMITED )
252+ stats .setAvgWorkspaceSizeQuota ( (double ) Fields .QUOTA_WORKSPACE_SIZE / stats .getSizePerWorkspace () );
253+ if ( Fields .QUOTA_TOTAL_SIZE != Fields .QUOTA_UNLIMITED )
254+ stats .setTotalQuota ( (double ) Fields .QUOTA_TOTAL_SIZE / (double ) totalSize );
255+ if ( Fields .QUOTA_ARCHIVE_LIMIT != Fields .QUOTA_UNLIMITED )
256+ stats .setAvgArchiveCountQuota ( (double ) Fields .QUOTA_ARCHIVE_LIMIT / stats .getArchivesPerWorkspace () );
257+
195258 // tranfer the results to the main class
196259 quotaManager .workspaceCache = cache ;
197260 quotaManager .totalSize = totalSize ;
261+ quotaManager .stats = stats ;
262+ quotaManager .statsTimestamp = now ;
198263
199264 // store settings to disk, if needed
200265 if ( storeSettings )
201266 quotaManager .workspaceManager .storeSettings ();
202267
203268 LOGGER .info ("finished full quota scan" );
269+
270+ // save duration of execution
271+ quotaManager .workerExecutionTime = new Date ().getTime () - startTime ;
204272 // give dobby a sock
205273 quotaManager .workerLock .unlock ();
206274 }
0 commit comments