Index: src/libchcore/TSubTaskBase.h =================================================================== diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r20aff533ab239b5b41263bb342879b4ea46fdbf6 --- src/libchcore/TSubTaskBase.h (.../TSubTaskBase.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) +++ src/libchcore/TSubTaskBase.h (.../TSubTaskBase.h) (revision 20aff533ab239b5b41263bb342879b4ea46fdbf6) @@ -26,6 +26,7 @@ #include "libchcore.h" #include "TPath.h" #include "ESubTaskTypes.h" +#include "TSubTaskStatsInfo.h" BEGIN_CHCORE_NAMESPACE @@ -67,19 +68,23 @@ virtual ESubOperationType GetSubOperationType() const = 0; virtual TSubTaskProgressInfo& GetProgressInfo() = 0; + virtual const TSubTaskStatsInfo& GetStatsInfo() const { return m_tSubTaskStats; } +protected: + // some common operations TSubTaskContext& GetContext() { return m_rContext; } const TSubTaskContext& GetContext() const { return m_rContext; } -protected: - // some common operations TSmartPath CalculateDestinationPath(const TFileInfoPtr& spFileInfo, TSmartPath pathDst, int iFlags) const; TSmartPath FindFreeSubstituteName(TSmartPath pathSrcPath, TSmartPath pathDstPath) const; private: TSubTaskBase(const TSubTaskBase&); TSubTaskBase& operator=(const TSubTaskBase&); +protected: + TSubTaskStatsInfo m_tSubTaskStats; + private: TSubTaskContext& m_rContext; }; Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r20aff533ab239b5b41263bb342879b4ea46fdbf6 --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 20aff533ab239b5b41263bb342879b4ea46fdbf6) @@ -126,7 +126,6 @@ boost::unique_lock lock(m_lock); m_ullCurrentFileProcessedSize += ullSizeToAdd; } - } // assume max sectors of 4kB (for rounding) @@ -152,6 +151,8 @@ TSubTaskBase::ESubOperationResult TSubTaskCopyMove::Exec() { + TSubTaskProcessingGuard guard(m_tSubTaskStats); + icpf::log_file& rLog = GetContext().GetLog(); TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition(); @@ -167,13 +168,21 @@ // log rLog.logi(_T("Processing files/folders (ProcessFiles)")); - // update stats + // old stats rLocalStats.SetProcessedSize(rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex())); rLocalStats.SetTotalSize(rFilesCache.CalculateTotalSize()); rLocalStats.SetCurrentIndex(m_tProgressInfo.GetCurrentIndex()); rLocalStats.SetTotalItems(rFilesCache.GetSize()); rLocalStats.SetCurrentPath(TString()); + // new stats + m_tSubTaskStats.SetCurrentBufferIndex(-1); + m_tSubTaskStats.SetTotalCount(rFilesCache.GetSize()); + m_tSubTaskStats.SetProcessedCount(rFilesCache.GetSize()); + m_tSubTaskStats.SetTotalSize(rFilesCache.CalculateTotalSize()); + m_tSubTaskStats.SetProcessedSize(rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex())); + m_tSubTaskStats.SetCurrentPath(TString()); + // now it's time to check if there is enough space on destination device TSubTaskBase::ESubOperationResult eResult = CheckForFreeSpaceFB(); if(eResult != TSubTaskBase::eSubResult_Continue) @@ -240,9 +249,14 @@ TFileInfoPtr spFileInfo = rFilesCache.GetAt(stIndex); TSmartPath pathCurrent = spFileInfo->GetFullFilePath(); + // old stats rLocalStats.SetCurrentIndex(stIndex); rLocalStats.SetCurrentPath(pathCurrent.ToString()); + // new stats + m_tSubTaskStats.SetProcessedCount(stIndex); + m_tSubTaskStats.SetCurrentPath(pathCurrent.ToString()); + // set dest path with filename ccp.pathDstFile = CalculateDestinationPath(spFileInfo, rTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); @@ -283,7 +297,11 @@ } } + // old stats rLocalStats.IncreaseProcessedSize(spFileInfo->GetLength64()); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(spFileInfo->GetLength64()); + spFileInfo->SetFlags(FIF_PROCESSED, FIF_PROCESSED); } else @@ -319,9 +337,15 @@ } m_tProgressInfo.SetCurrentIndex(stIndex); + + // old stats rLocalStats.SetCurrentIndex(stIndex); rLocalStats.SetCurrentPath(TString()); + // new stats + m_tSubTaskStats.SetProcessedCount(stIndex); + m_tSubTaskStats.SetCurrentPath(TString()); + // delete buffer - it's not needed ccp.dbBuffer.Delete(); @@ -389,7 +413,11 @@ else if(!fileSrc.IsOpen()) { // invalid handle = operation skipped by user + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -413,7 +441,11 @@ return eResult; else if(!fileDst.IsOpen()) { + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -426,7 +458,11 @@ return eResult; else if(!fileDst.IsOpen()) { + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -447,7 +483,11 @@ return eResult; else if(bSkip) { + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // old stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -458,13 +498,20 @@ else if(bSkip) { // with either first or second seek we got 'skip' answer... + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } m_tProgressInfo.IncreaseCurrentFileProcessedSize(ullMove); + // old stats rLocalStats.IncreaseProcessedSize(ullMove); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(ullMove); } // if the destination file already exists - truncate it to the current file position @@ -539,7 +586,10 @@ iBufferIndex = TBufferSizes::eBuffer_Default; else iBufferIndex = GetBufferIndex(pData->spSrcFile); + // old stats rLocalStats.SetCurrentBufferIndex(iBufferIndex); + // new stats + m_tSubTaskStats.SetCurrentBufferIndex(iBufferIndex); ulToRead = bNoBuffer ? ROUNDUP(pData->dbBuffer.GetSizes().GetSizeByType((TBufferSizes::EBufferType)iBufferIndex), MAXSECTORSIZE) : pData->dbBuffer.GetSizes().GetSizeByType((TBufferSizes::EBufferType)iBufferIndex); @@ -549,7 +599,11 @@ return eResult; else if(bSkip) { + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // old stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -575,14 +629,21 @@ return eResult; else if(bSkip) { + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // old stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } // increase count of processed data m_tProgressInfo.IncreaseCurrentFileProcessedSize(ulWritten); + // old stats rLocalStats.IncreaseProcessedSize(ulWritten); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(ulWritten); // calculate count of bytes left to be written ulRead -= ulWritten; @@ -603,7 +664,11 @@ return eResult; else if(!fileDst.IsOpen()) { + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // old stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -615,7 +680,11 @@ else if(bSkip) { // with either first or second seek we got 'skip' answer... + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -630,14 +699,22 @@ return eResult; else if(bSkip) { + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } // increase count of processed data m_tProgressInfo.IncreaseCurrentFileProcessedSize(ulRead); + + // old stats rLocalStats.IncreaseProcessedSize(ulRead); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(ulRead); } } } @@ -646,7 +723,10 @@ else { // we don't copy contents, but need to increase processed size + // old stats rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); + // new stats + m_tSubTaskStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); } pData->bProcessed = true; @@ -1108,8 +1188,8 @@ icpf::log_file& rLog = GetContext().GetLog(); TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition(); IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler(); - TTaskLocalStats& rLocalStats = GetContext().GetTaskLocalStats(); TLocalFilesystem& rLocalFilesystem = GetContext().GetLocalFilesystem(); + TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); ull_t ullNeededSize = 0, ullAvailableSize = 0; bool bRetry = false; @@ -1120,7 +1200,7 @@ rLog.logi(_T("Checking for free space on destination disk...")); - ullNeededSize = rLocalStats.GetUnProcessedSize(); // it'd be nice to round up to take cluster size into consideration, + ullNeededSize = rFilesCache.CalculateTotalSize() - rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex()); // it'd be nice to round up to take cluster size into consideration // get free space bool bResult = rLocalFilesystem.GetDynamicFreeSpace(rTaskDefinition.GetDestinationPath(), ullAvailableSize); Index: src/libchcore/TSubTaskDelete.cpp =================================================================== diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r20aff533ab239b5b41263bb342879b4ea46fdbf6 --- src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) +++ src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision 20aff533ab239b5b41263bb342879b4ea46fdbf6) @@ -99,6 +99,8 @@ TSubTaskBase::ESubOperationResult TSubTaskDelete::Exec() { + TSubTaskProcessingGuard guard(m_tSubTaskStats); + // log icpf::log_file& rLog = GetContext().GetLog(); TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); @@ -110,12 +112,21 @@ // log rLog.logi(_T("Deleting files (DeleteFiles)...")); + // old stats rTaskLocalStats.SetProcessedSize(0); rTaskLocalStats.SetTotalSize(0); rTaskLocalStats.SetCurrentIndex(0); rTaskLocalStats.SetTotalItems(rFilesCache.GetSize()); rTaskLocalStats.SetCurrentPath(TString()); + // new stats + m_tSubTaskStats.SetCurrentBufferIndex(-1); + m_tSubTaskStats.SetTotalCount(rFilesCache.GetSize()); + m_tSubTaskStats.SetProcessedCount(0); + m_tSubTaskStats.SetTotalSize(0); + m_tSubTaskStats.SetProcessedSize(0); + m_tSubTaskStats.SetCurrentPath(TString()); + // current processed path BOOL bSuccess; TFileInfoPtr spFileInfo; @@ -129,9 +140,14 @@ m_tProgressInfo.SetCurrentIndex(stIndex); + // old stats rTaskLocalStats.SetCurrentIndex(stIndex); rTaskLocalStats.SetCurrentPath(spFileInfo->GetFullFilePath().ToString()); + // new stats + m_tSubTaskStats.SetProcessedCount(stIndex); + m_tSubTaskStats.SetCurrentPath(spFileInfo->GetFullFilePath().ToString()); + // check for kill flag if(rThreadController.KillRequested()) { @@ -199,9 +215,15 @@ }//while m_tProgressInfo.SetCurrentIndex(stIndex); + + // old stats rTaskLocalStats.SetCurrentIndex(stIndex); rTaskLocalStats.SetCurrentPath(TString()); + // new stats + m_tSubTaskStats.SetProcessedCount(stIndex); + m_tSubTaskStats.SetCurrentPath(TString()); + // log rLog.logi(_T("Deleting files finished")); Index: src/libchcore/TSubTaskFastMove.cpp =================================================================== diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r20aff533ab239b5b41263bb342879b4ea46fdbf6 --- src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) +++ src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision 20aff533ab239b5b41263bb342879b4ea46fdbf6) @@ -101,6 +101,8 @@ TSubTaskFastMove::ESubOperationResult TSubTaskFastMove::Exec() { + TSubTaskProcessingGuard guard(m_tSubTaskStats); + // log icpf::log_file& rLog = GetContext().GetLog(); TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition(); @@ -111,13 +113,21 @@ rLog.logi(_T("Performing initial fast-move operation...")); - // reset progress + // old stats rTaskLocalStats.SetProcessedSize(0); rTaskLocalStats.SetTotalSize(0); rTaskLocalStats.SetCurrentIndex(0); rTaskLocalStats.SetTotalItems(rTaskDefinition.GetSourcePathCount()); rTaskLocalStats.SetCurrentPath(TString()); + // new stats + m_tSubTaskStats.SetCurrentBufferIndex(-1); + m_tSubTaskStats.SetTotalCount(rTaskDefinition.GetSourcePathCount()); + m_tSubTaskStats.SetProcessedCount(0); + m_tSubTaskStats.SetTotalSize(0); + m_tSubTaskStats.SetProcessedSize(0); + m_tSubTaskStats.SetCurrentPath(TString()); + // read filtering options TFileFiltersArray afFilters; GetTaskPropValue(rTaskDefinition.GetConfiguration(), afFilters); @@ -146,9 +156,14 @@ // store currently processed index m_tProgressInfo.SetCurrentIndex(stIndex); + // old stats rTaskLocalStats.SetCurrentIndex(stIndex); rTaskLocalStats.SetCurrentPath(pathCurrent.ToString()); + // new stats + m_tSubTaskStats.SetProcessedCount(stIndex); + m_tSubTaskStats.SetCurrentPath(pathCurrent.ToString()); + // retrieve base path data TBasePathDataPtr spBasePathData = rBasePathDataContainer.GetAt(stIndex); if(!spBasePathData) @@ -169,7 +184,7 @@ bool bExists = TLocalFilesystem::GetFileInfo(pathCurrent, spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths()); if(!bExists) { - FEEDBACK_FILEERROR ferr = { rTaskDefinition.GetSourcePathAt(stIndex).ToString(), NULL, eFastMoveError, ERROR_FILE_NOT_FOUND }; + FEEDBACK_FILEERROR ferr = { pathCurrent.ToString(), NULL, eFastMoveError, ERROR_FILE_NOT_FOUND }; IFeedbackHandler::EFeedbackResult frResult = (IFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(IFeedbackHandler::eFT_FileError, &ferr); switch(frResult) { @@ -270,9 +285,14 @@ } m_tProgressInfo.SetCurrentIndex(stIndex); + + // old stats rTaskLocalStats.SetCurrentIndex(stIndex); rTaskLocalStats.SetCurrentPath(TString()); + // new stats + m_tSubTaskStats.SetProcessedCount(stIndex); + m_tSubTaskStats.SetCurrentPath(TString()); // log rLog.logi(_T("Fast moving finished")); Index: src/libchcore/TSubTaskScanDirectory.cpp =================================================================== diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r20aff533ab239b5b41263bb342879b4ea46fdbf6 --- src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) +++ src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision 20aff533ab239b5b41263bb342879b4ea46fdbf6) @@ -103,6 +103,8 @@ TSubTaskScanDirectories::ESubOperationResult TSubTaskScanDirectories::Exec() { + TSubTaskProcessingGuard guard(m_tSubTaskStats); + // log icpf::log_file& rLog = GetContext().GetLog(); TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); @@ -116,12 +118,22 @@ // reset progress rFilesCache.SetComplete(false); + + // old stats rTaskLocalStats.SetProcessedSize(0); rTaskLocalStats.SetTotalSize(0); rTaskLocalStats.SetCurrentIndex(0); rTaskLocalStats.SetTotalItems(rTaskDefinition.GetSourcePathCount()); rTaskLocalStats.SetCurrentPath(TString()); + // new stats + m_tSubTaskStats.SetCurrentBufferIndex(-1); + m_tSubTaskStats.SetTotalCount(rTaskDefinition.GetSourcePathCount()); + m_tSubTaskStats.SetProcessedCount(0); + m_tSubTaskStats.SetTotalSize(0); + m_tSubTaskStats.SetProcessedSize(0); + m_tSubTaskStats.SetCurrentPath(TString()); + // delete the content of rFilesCache rFilesCache.Clear(); @@ -146,9 +158,14 @@ m_tProgressInfo.SetCurrentIndex(stIndex); + // old stats rTaskLocalStats.SetCurrentIndex(stIndex); rTaskLocalStats.SetCurrentPath(pathCurrent.ToString()); + // new stats + m_tSubTaskStats.SetProcessedCount(stIndex); + m_tSubTaskStats.SetCurrentPath(pathCurrent.ToString()); + bSkipInputPath = false; TFileInfoPtr spFileInfo(boost::make_shared()); @@ -254,9 +271,15 @@ // calc size of all files m_tProgressInfo.SetCurrentIndex(stIndex); + + // old stats rTaskLocalStats.SetCurrentIndex(stIndex); rTaskLocalStats.SetCurrentPath(TString()); + // new stats + m_tSubTaskStats.SetProcessedCount(stIndex); + m_tSubTaskStats.SetCurrentPath(TString()); + rFilesCache.SetComplete(true); // log Index: src/libchcore/TSubTaskStatsInfo.cpp =================================================================== diff -u --- src/libchcore/TSubTaskStatsInfo.cpp (revision 0) +++ src/libchcore/TSubTaskStatsInfo.cpp (revision 20aff533ab239b5b41263bb342879b4ea46fdbf6) @@ -0,0 +1,224 @@ +// ============================================================================ +// Copyright (C) 2001-2012 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +/// @file TSubTaskStatsInfo.cpp +/// @date 2012/02/22 +/// @brief Contains definition of class responsible for tracking stats for subtasks. +// ============================================================================ +#include "stdafx.h" +#include "TSubTaskStatsInfo.h" + +BEGIN_CHCORE_NAMESPACE + +/////////////////////////////////////////////////////////////////////////////////// +// class TSubTaskProcessingGuard +TSubTaskProcessingGuard::TSubTaskProcessingGuard(TSubTaskStatsInfo& rStats) : + m_rStats(rStats) +{ + rStats.MarkAsRunning(); + rStats.EnableTimeTracking(); +} + +TSubTaskProcessingGuard::~TSubTaskProcessingGuard() +{ + m_rStats.DisableTimeTracking(); + m_rStats.MarkAsNotRunning(); +} + +/////////////////////////////////////////////////////////////////////////////////// +// class TSubTaskStatsInfo +TSubTaskStatsInfo::TSubTaskStatsInfo() : + m_bSubTaskIsRunning(false), + m_ullTotalSize(0), + m_ullProcessedSize(0), + m_stTotalCount(0), + m_stProcessedCount(0), + m_iCurrentBufferIndex(0), + m_strCurrentPath(), + m_timeElapsed(0), + m_timeLast(0) +{ +} + +// is running? +void TSubTaskStatsInfo::MarkAsRunning() +{ + boost::unique_lock lock(m_lock); + m_bSubTaskIsRunning = true; +} + +void TSubTaskStatsInfo::MarkAsNotRunning() +{ + boost::unique_lock lock(m_lock); + m_bSubTaskIsRunning = false; +} + +bool TSubTaskStatsInfo::IsRunning() const +{ + boost::shared_lock lock(m_lock); + return m_bSubTaskIsRunning; +} + +// count stats +void TSubTaskStatsInfo::GetCountStats(size_t& stProcessedCount, size_t& stTotalCount) const +{ + boost::shared_lock lock(m_lock); + stProcessedCount = m_stProcessedCount; + stTotalCount = m_stTotalCount; +} + +void TSubTaskStatsInfo::IncreaseProcessedCount(size_t stIncreaseBy) +{ + boost::unique_lock lock(m_lock); + m_stProcessedCount += stIncreaseBy; + _ASSERTE(m_stProcessedCount <= m_stTotalCount); + if(m_stProcessedCount > m_stTotalCount) + THROW_CORE_EXCEPTION(eErr_InternalProblem); +} + +void TSubTaskStatsInfo::SetProcessedCount(size_t stProcessedCount) +{ + boost::unique_lock lock(m_lock); + m_stProcessedCount = stProcessedCount; + _ASSERTE(m_stProcessedCount <= m_stTotalCount); + if(m_stProcessedCount > m_stTotalCount) + THROW_CORE_EXCEPTION(eErr_InternalProblem); +} + +void TSubTaskStatsInfo::SetTotalCount(size_t stCount) +{ + boost::unique_lock lock(m_lock); + m_stTotalCount = stCount; + _ASSERTE(m_stProcessedCount <= m_stTotalCount); + if(m_stProcessedCount > m_stTotalCount) + THROW_CORE_EXCEPTION(eErr_InternalProblem); +} + +// size stats +void TSubTaskStatsInfo::GetSizeStats(unsigned long long& ullProcessedSize, unsigned long long& ullTotalSize) const +{ + boost::shared_lock lock(m_lock); + ullProcessedSize = m_ullProcessedSize; + ullTotalSize = m_ullTotalSize; +} + +void TSubTaskStatsInfo::IncreaseProcessedSize(unsigned long long ullIncreaseBy) +{ + boost::unique_lock lock(m_lock); + m_ullProcessedSize += ullIncreaseBy; + _ASSERTE(m_ullProcessedSize <= m_ullTotalSize); + if(m_ullProcessedSize > m_ullTotalSize) + THROW_CORE_EXCEPTION(eErr_InternalProblem); +} + +void TSubTaskStatsInfo::SetProcessedSize(unsigned long long ullProcessedSize) +{ + boost::unique_lock lock(m_lock); + m_ullProcessedSize = ullProcessedSize; + _ASSERTE(m_ullProcessedSize <= m_ullTotalSize); + if(m_ullProcessedSize > m_ullTotalSize) + THROW_CORE_EXCEPTION(eErr_InternalProblem); +} + +void TSubTaskStatsInfo::SetTotalSize(unsigned long long ullTotalSize) +{ + boost::unique_lock lock(m_lock); + m_ullTotalSize = ullTotalSize; + _ASSERTE(m_ullProcessedSize <= m_ullTotalSize); + if(m_ullProcessedSize > m_ullTotalSize) + THROW_CORE_EXCEPTION(eErr_InternalProblem); +} + +// buffer index +void TSubTaskStatsInfo::SetCurrentBufferIndex(int iCurrentIndex) +{ + boost::unique_lock lock(m_lock); + m_iCurrentBufferIndex = iCurrentIndex; +} + +int TSubTaskStatsInfo::GetCurrentBufferIndex() const +{ + boost::shared_lock lock(m_lock); + return m_iCurrentBufferIndex; +} + +// current path +void TSubTaskStatsInfo::SetCurrentPath(const TString& strPath) +{ + boost::unique_lock lock(m_lock); + m_strCurrentPath = strPath; +} + +const TString& TSubTaskStatsInfo::GetCurrentPath() const +{ + boost::shared_lock lock(m_lock); + return m_strCurrentPath; +} + +// time +void TSubTaskStatsInfo::SetTimeElapsed(time_t timeElapsed) +{ + boost::unique_lock lock(m_lock); + m_timeElapsed = timeElapsed; +} + +time_t TSubTaskStatsInfo::GetTimeElapsed() +{ + boost::upgrade_lock lock(m_lock); + + UpdateTime(lock); + + return m_timeElapsed; +} + +void TSubTaskStatsInfo::EnableTimeTracking() +{ + boost::upgrade_lock lock(m_lock); + if(m_timeLast == -1) + { + boost::upgrade_to_unique_lock lock_upgraded(lock); + m_timeLast = time(NULL); + } +} + +void TSubTaskStatsInfo::DisableTimeTracking() +{ + boost::upgrade_lock lock(m_lock); + + UpdateTime(lock); + + if(m_timeLast != -1) + { + boost::upgrade_to_unique_lock lock_upgraded(lock); + m_timeLast = -1; + } +} + +void TSubTaskStatsInfo::UpdateTime(boost::upgrade_lock& lock) +{ + if(m_timeLast != -1) + { + time_t timeCurrent = time(NULL); + + boost::upgrade_to_unique_lock lock_upgraded(lock); + m_timeElapsed += timeCurrent - m_timeLast; + m_timeLast = timeCurrent; + } +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskStatsInfo.h =================================================================== diff -u --- src/libchcore/TSubTaskStatsInfo.h (revision 0) +++ src/libchcore/TSubTaskStatsInfo.h (revision 20aff533ab239b5b41263bb342879b4ea46fdbf6) @@ -0,0 +1,119 @@ +// ============================================================================ +// Copyright (C) 2001-2012 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +/// @file TSubTaskStatsInfo.h +/// @date 2012/02/22 +/// @brief Contains declaration of class responsible for tracking stats for subtasks. +// ============================================================================ +#ifndef __TSUBTASKSTATSINFO_H__ +#define __TSUBTASKSTATSINFO_H__ + +#include "libchcore.h" +#include "TString.h" + +BEGIN_CHCORE_NAMESPACE + +class TSubTaskStatsInfo; + +// class used to guard scope of the subtask processing ( +class TSubTaskProcessingGuard +{ +public: + TSubTaskProcessingGuard(TSubTaskStatsInfo& rStats); + ~TSubTaskProcessingGuard(); + +private: + TSubTaskProcessingGuard(const TSubTaskProcessingGuard&); + TSubTaskProcessingGuard& operator=(const TSubTaskProcessingGuard&); + +private: + TSubTaskStatsInfo& m_rStats; +}; + +class LIBCHCORE_API TSubTaskStatsInfo +{ +public: + TSubTaskStatsInfo(); + + // is running? + bool IsRunning() const; + + // count stats + void GetCountStats(size_t& stItemIndex, size_t& stItemsCount) const; + + void IncreaseProcessedCount(size_t stIncreaseBy); + void SetProcessedCount(size_t stIndex); + + void SetTotalCount(size_t stCount); + + // size stats + void GetSizeStats(unsigned long long& ullProcessedSize, unsigned long long& ullTotalSize) const; + void IncreaseProcessedSize(unsigned long long ullIncreaseBy); + void SetProcessedSize(unsigned long long ullProcessedSize); + + void SetTotalSize(unsigned long long ullTotalSize); + + // buffer index + void SetCurrentBufferIndex(int iCurrentIndex); + int GetCurrentBufferIndex() const; + + // current path + void SetCurrentPath(const TString& strPath); + const TString& GetCurrentPath() const; + + // time + void SetTimeElapsed(time_t timeElapsed); + time_t GetTimeElapsed(); + +private: + // is running? + void MarkAsRunning(); + void MarkAsNotRunning(); + + // time tracking + void EnableTimeTracking(); + void DisableTimeTracking(); + void UpdateTime(boost::upgrade_lock& lock); + +private: + bool m_bSubTaskIsRunning; + + unsigned long long m_ullTotalSize; + unsigned long long m_ullProcessedSize; + + size_t m_stTotalCount; + size_t m_stProcessedCount; + + int m_iCurrentBufferIndex; + + TString m_strCurrentPath; // currently processed path + + time_t m_timeElapsed; + time_t m_timeLast; + +#pragma warning(push) +#pragma warning(disable: 4251) + mutable boost::shared_mutex m_lock; +#pragma warning(pop) + + friend class TSubTaskProcessingGuard; +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/libchcore.vc90.vcproj =================================================================== diff -u -rbebda797ec6983535a8940f8f9f15453fe6b1785 -r20aff533ab239b5b41263bb342879b4ea46fdbf6 --- src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) +++ src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision 20aff533ab239b5b41263bb342879b4ea46fdbf6) @@ -1,7 +1,7 @@ + + + +