|
|
/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name: PurgeEngine.cpp
Abstract: This file contains the implementation of the MPCPurgeEngine class, that controls the cleaning of the temporary directories.
Revision History: Davide Massarenti (Dmassare) 07/12/99 created
******************************************************************************/
#include "stdafx.h"
HRESULT MPCPurgeEngine::Process() { __ULT_FUNC_ENTRY("MPCPurgeEngine::Process");
HRESULT hr; HRESULT hr2; CISAPIconfig::Iter itInstanceBegin; CISAPIconfig::Iter itInstanceEnd; CISAPIinstance::PathIter itPathBegin; CISAPIinstance::PathIter itPathEnd; double dblNow = MPC::GetSystemTime();
//
// Enumerate all the instances.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, g_Config.GetInstances( itInstanceBegin, itInstanceEnd )); for(;itInstanceBegin != itInstanceEnd; itInstanceBegin++) { __MPC_EXIT_IF_METHOD_FAILS(hr, itInstanceBegin->get_URL ( m_szURL )); __MPC_EXIT_IF_METHOD_FAILS(hr, itInstanceBegin->get_QueueSizeMax ( m_dwQueueSizeMax )); __MPC_EXIT_IF_METHOD_FAILS(hr, itInstanceBegin->get_QueueSizeThreshold( m_dwQueueSizeThreshold )); __MPC_EXIT_IF_METHOD_FAILS(hr, itInstanceBegin->get_MaximumJobAge ( m_dwMaximumJobAge ));
m_dblMaximumJobAge = dblNow - m_dwMaximumJobAge;
MPCServer mpcsServer( NULL, m_szURL.c_str(), NULL ); m_mpcsServer = &mpcsServer;
//
// For each instance, enumerate all the temporary directories.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, itInstanceBegin->GetLocations( itPathBegin, itPathEnd )); for(;itPathBegin != itPathEnd; itPathBegin++) { MPC::FileSystemObject fso( itPathBegin->c_str() );
if(SUCCEEDED(hr2 = fso.Scan( true ))) { DWORD dwTotalSize = 0;
m_lstClients.clear();
__MPC_EXIT_IF_METHOD_FAILS(hr, AnalyzeFolders( &fso, dwTotalSize ));
__MPC_EXIT_IF_METHOD_FAILS(hr, RemoveOldJobs( dwTotalSize ));
if(dwTotalSize > m_dwQueueSizeMax) { while(dwTotalSize && dwTotalSize > m_dwQueueSizeThreshold) { __MPC_EXIT_IF_METHOD_FAILS(hr, RemoveOldestJob ( dwTotalSize )); __MPC_EXIT_IF_METHOD_FAILS(hr, RemoveEmptyClients( dwTotalSize )); } } } } }
hr = S_OK;
__ULT_FUNC_CLEANUP;
__ULT_FUNC_EXIT(hr); }
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
static bool MatchExtension( const MPC::wstring& szPath , LPCWSTR szExt ) { MPC::wstring::size_type iPos;
iPos = szPath.find( szExt, 0 ); if(iPos != MPC::wstring::npos && iPos + wcslen( szExt ) == szPath.length()) { return true; }
return false; }
HRESULT MPCPurgeEngine::AnalyzeFolders( /*[in]*/ MPC::FileSystemObject* fso , /*[in]*/ DWORD& dwTotalSize ) { __ULT_FUNC_ENTRY("MPCPurgeEngine::AnalyzeFolders");
HRESULT hr; HRESULT hr2; MPC::FileSystemObject::List lst; MPC::FileSystemObject::Iter it;
//
// Process all folders.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, fso->EnumerateFolders( lst )); for(it = lst.begin(); it != lst.end(); it++) { __MPC_EXIT_IF_METHOD_FAILS(hr, AnalyzeFolders( *it, dwTotalSize )); }
//
// Process all files.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, fso->EnumerateFiles( lst )); for(it = lst.begin(); it != lst.end(); it++) { MPC::wstring szPath;
__MPC_EXIT_IF_METHOD_FAILS(hr, (*it)->get_Path( szPath ));
if(MatchExtension( szPath, CLIENT_CONST__DB_EXTENSION )) { __MPC_EXIT_IF_METHOD_FAILS(hr, AddClient( szPath, dwTotalSize )); } else if(MatchExtension( szPath, SESSION_CONST__IMG_EXTENSION )) { ; } else { //
// Any other file should be deleted.
//
(void)(*it)->Delete(); } }
hr = S_OK;
__ULT_FUNC_CLEANUP;
__ULT_FUNC_EXIT(hr); }
/////////////////////////////////////////////////////////////////////////////
HRESULT MPCPurgeEngine::AddClient( /*[in]*/ const MPC::wstring& szPath , /*[in/out]*/ DWORD& dwTotalSize ) { __ULT_FUNC_ENTRY("MPCPurgeEngine::AddClient");
HRESULT hr; HRESULT hr2; MPCClient mpccClient( m_mpcsServer, szPath ); Iter itClient = m_lstClients.insert( m_lstClients.end(), MPCPurge_ClientSummary( szPath ) );
if(SUCCEEDED(hr2 = mpccClient.InitFromDisk( false ))) { MPCClient::Iter itBegin; MPCClient::Iter itEnd;
//
// Adjust total count with size of the Directory File.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, mpccClient.GetFileSize( itClient->m_dwFileSize )); dwTotalSize += itClient->m_dwFileSize;
__MPC_EXIT_IF_METHOD_FAILS(hr, mpccClient.GetSessions( itBegin, itEnd )); while(itBegin != itEnd) { MPCPurge_SessionSummary pssSession;
itBegin->get_JobID ( pssSession.m_szJobID ); itBegin->get_LastModified( pssSession.m_dblLastModified ); itBegin->get_CurrentSize ( pssSession.m_dwCurrentSize );
//
// Don't count "committed" jobs in total size, because the file has already been moved.
//
if(itBegin->get_Committed()) { pssSession.m_dwCurrentSize = 0; }
itClient->m_lstSessions.push_back( pssSession );
dwTotalSize += pssSession.m_dwCurrentSize; itBegin++; } }
hr = S_OK;
__ULT_FUNC_CLEANUP;
__ULT_FUNC_EXIT(hr); }
/////////////////////////////////////////////////////////////////////////////
HRESULT MPCPurgeEngine::RemoveOldJobs( /*[in/out]*/ DWORD& dwTotalSize ) { __ULT_FUNC_ENTRY("MPCPurgeEngine::RemoveOldJobs");
HRESULT hr; HRESULT hr2; Iter it;
for(it = m_lstClients.begin(); it != m_lstClients.end(); it++) { MPCPurge_ClientSummary::Iter itSession; MPCClient mpccClient( m_mpcsServer, it->m_szPath ); bool fInitialized = false;
while(it->GetOldestSession( itSession )) { //
// If the oldest session is younger than the limit, leave the loop.
//
if(itSession->m_dblLastModified > m_dblMaximumJobAge) { break; }
__MPC_EXIT_IF_METHOD_FAILS(hr, RemoveSession( mpccClient, fInitialized, it, itSession, dwTotalSize )); } }
hr = S_OK;
__ULT_FUNC_CLEANUP;
__ULT_FUNC_EXIT(hr); }
/////////////////////////////////////////////////////////////////////////////
HRESULT MPCPurgeEngine::RemoveOldestJob( /*[in/out]*/ DWORD& dwTotalSize ) { __ULT_FUNC_ENTRY("MPCPurgeEngine::RemoveOldestJob");
HRESULT hr; HRESULT hr2; Iter it; Iter itOldestClient; double dblOldestClient = DBL_MAX; bool fFound = false;
//
// Look for the oldest job.
//
for(it = m_lstClients.begin(); it != m_lstClients.end(); it++) { if(it->m_dblLastModified < dblOldestClient) { itOldestClient = it; dblOldestClient = it->m_dblLastModified; fFound = true; } }
if(fFound) { MPCPurge_ClientSummary::Iter itSession; MPCClient mpccClient( m_mpcsServer, itOldestClient->m_szPath ); bool fInitialized = false;
if(itOldestClient->GetOldestSession( itSession )) { __MPC_EXIT_IF_METHOD_FAILS(hr, RemoveSession( mpccClient, fInitialized, itOldestClient, itSession, dwTotalSize ));
//
// Update the m_dblLastModified of the MPCPurge_ClientSummary object.
//
itOldestClient->GetOldestSession( itSession ); }
if(fInitialized) { DWORD dwPost;
__MPC_EXIT_IF_METHOD_FAILS(hr, mpccClient.SyncToDisk ( )); __MPC_EXIT_IF_METHOD_FAILS(hr, mpccClient.GetFileSize( dwPost ));
//
// Update Directory File size.
//
dwTotalSize -= itOldestClient->m_dwFileSize; dwTotalSize += dwPost; itOldestClient->m_dwFileSize = dwPost; } }
hr = S_OK;
__ULT_FUNC_CLEANUP;
__ULT_FUNC_EXIT(hr); }
/////////////////////////////////////////////////////////////////////////////
HRESULT MPCPurgeEngine::RemoveSession( /*[in]*/ MPCClient& mpccClient , /*[in/out]*/ bool& fInitialized , /*[in]*/ Iter itClient , /*[in]*/ MPCPurge_ClientSummary::Iter& itSession , /*[in/out]*/ DWORD& dwTotalSize ) { __ULT_FUNC_ENTRY("MPCPurgeEngine::RemoveSession");
HRESULT hr; HRESULT hr2;
//
// Lock the client.
//
if(fInitialized == false) { if(SUCCEEDED(hr2 = mpccClient.InitFromDisk( false ))) { fInitialized = true; } }
if(fInitialized) { MPCClient::Iter itSessionReal;
//
// If the session exists, remove it.
//
if(mpccClient.Find( itSession->m_szJobID, itSessionReal ) == true) { __MPC_EXIT_IF_METHOD_FAILS(hr, itSessionReal->RemoveFile());
mpccClient.Erase( itSessionReal ); }
//
// Update the total size counter and remove the session from memory.
//
dwTotalSize -= itSession->m_dwCurrentSize; itClient->m_lstSessions.erase( itSession ); }
hr = S_OK;
__ULT_FUNC_CLEANUP;
__ULT_FUNC_EXIT(hr); }
/////////////////////////////////////////////////////////////////////////////
HRESULT MPCPurgeEngine::RemoveEmptyClients( /*[in/out]*/ DWORD& dwTotalSize ) { __ULT_FUNC_ENTRY("MPCPurgeEngine::RemoveEmptyClients");
HRESULT hr; Iter it;
for(it = m_lstClients.begin(); it != m_lstClients.end(); it++) { //
// If the client has no more sessions, don't count it.
//
if(it->m_lstSessions.size() == 0) { dwTotalSize -= it->m_dwFileSize;
m_lstClients.erase( it ); it = m_lstClients.begin(); } }
hr = S_OK;
// __ULT_FUNC_CLEANUP;
__ULT_FUNC_EXIT(hr); }
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
MPCPurge_ClientSummary::MPCPurge_ClientSummary( const MPC::wstring& szPath ) { m_szPath = szPath; // MPC::wstring m_szPath;
// List m_lstSessions;
m_dwFileSize = 0; // DWORD m_dwFileSize;
m_dblLastModified = 0; // double m_dblLastModified;
}
bool MPCPurge_ClientSummary::GetOldestSession( /*[out]*/ Iter& itSession ) { Iter it;
m_dblLastModified = DBL_MAX; itSession = m_lstSessions.end();
for(it = m_lstSessions.begin(); it != m_lstSessions.end(); it++) { if(it->m_dblLastModified < m_dblLastModified) { itSession = it; m_dblLastModified = it->m_dblLastModified; } }
return (itSession != m_lstSessions.end()); }
|