Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

436 lines
12 KiB

/******************************************************************************
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());
}