Index: src/ch/ch.rc =================================================================== diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/ch/ch.rc (.../ch.rc) (revision d88274a4bbfd4ef005d44c4d179b7596cb627486) +++ src/ch/ch.rc (.../ch.rc) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -809,7 +809,7 @@ "Changed:\n%count paths primarily got from clipboard" IDS_TASKNOTPAUSED_STRING "Selected task isn't paused" IDS_TASKNOTSELECTED_STRING "Task not selected" - IDS_NONEINPUTFILE_STRING "(waiting...)" + IDS_NONEINPUTFILE_STRING "none" END STRINGTABLE Fisheye: Tag bebda797ec6983535a8940f8f9f15453fe6b1785 refers to a dead (removed) revision in file `src/libchcore/TBasicProgressInfo.cpp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag bebda797ec6983535a8940f8f9f15453fe6b1785 refers to a dead (removed) revision in file `src/libchcore/TBasicProgressInfo.h'. Fisheye: No comparison available. Pass `N' to diff? Index: src/libchcore/TSubTaskArray.cpp =================================================================== diff -u -r297ce850732d4243414c851df145ca97bd696baa -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision 297ce850732d4243414c851df145ca97bd696baa) +++ src/libchcore/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -28,15 +28,101 @@ #include "TSubTaskCopyMove.h" #include "TSubTaskDelete.h" #include "TSubTaskContext.h" -#include "TBasicProgressInfo.h" #include "TTaskLocalStats.h" #include "TSubTaskFastMove.h" +#include "SerializationHelpers.h" +#include "TBinarySerializer.h" BEGIN_CHCORE_NAMESPACE -TSubTasksArray::TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) : - m_rSubTaskContext(rSubTaskContext) +namespace details { + /////////////////////////////////////////////////////////////////////////// + // TTaskBasicProgressInfo + + TTaskBasicProgressInfo::TTaskBasicProgressInfo() : + m_stSubOperationIndex(0) + { + } + + TTaskBasicProgressInfo::~TTaskBasicProgressInfo() + { + } + + void TTaskBasicProgressInfo::ResetProgress() + { + boost::unique_lock lock(m_lock); + m_stSubOperationIndex = 0; + } + + void TTaskBasicProgressInfo::SetSubOperationIndex(size_t stSubOperationIndex) + { + boost::unique_lock lock(m_lock); + m_stSubOperationIndex = stSubOperationIndex; + } + + size_t TTaskBasicProgressInfo::GetSubOperationIndex() const + { + boost::shared_lock lock(m_lock); + return m_stSubOperationIndex; + } + + void TTaskBasicProgressInfo::IncreaseSubOperationIndex() + { + boost::unique_lock lock(m_lock); + ++m_stSubOperationIndex; + } + + void TTaskBasicProgressInfo::Serialize(TReadBinarySerializer& rSerializer) + { + using Serializers::Serialize; + + size_t stSubOperationIndex = 0; + Serialize(rSerializer, stSubOperationIndex); + + boost::unique_lock lock(m_lock); + + m_stSubOperationIndex = stSubOperationIndex; + } + + void TTaskBasicProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const + { + using Serializers::Serialize; + + size_t stSubOperationIndex = 0; + { + boost::shared_lock lock(m_lock); + stSubOperationIndex = m_stSubOperationIndex; + } + + Serialize(rSerializer, stSubOperationIndex); + } +} + +/////////////////////////////////////////////////////////////////////////// +// TSubTasksArray + +TSubTasksArray::TSubTasksArray() : + m_pSubTaskContext(NULL) +{ +} + + TSubTasksArray::TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) : +m_pSubTaskContext(NULL) +{ + Init(rOperationPlan, rSubTaskContext); +} + +TSubTasksArray::~TSubTasksArray() +{ +} + +void TSubTasksArray::Init(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext) +{ + m_vSubTasks.clear(); + m_tProgressInfo.ResetProgress(); + m_pSubTaskContext = &rSubTaskContext; + switch(rOperationPlan.GetOperationType()) { case eOperation_Copy: @@ -66,24 +152,56 @@ } } -TSubTasksArray::~TSubTasksArray() +void TSubTasksArray::ResetProgress() { + m_tProgressInfo.ResetProgress(); + + boost::tuples::tuple tupleRow; + BOOST_FOREACH(tupleRow, m_vSubTasks) + { + if(tupleRow.get<0>() == NULL) + THROW_CORE_EXCEPTION(eErr_InternalProblem); + + tupleRow.get<0>()->GetProgressInfo().ResetProgress(); + } } +void TSubTasksArray::SerializeProgress(TReadBinarySerializer& rSerializer) +{ + m_tProgressInfo.Serialize(rSerializer); + boost::tuples::tuple tupleRow; + BOOST_FOREACH(tupleRow, m_vSubTasks) + { + tupleRow.get<0>()->GetProgressInfo().Serialize(rSerializer); + } +} + +void TSubTasksArray::SerializeProgress(TWriteBinarySerializer& rSerializer) const +{ + m_tProgressInfo.Serialize(rSerializer); + boost::tuples::tuple tupleRow; + BOOST_FOREACH(tupleRow, m_vSubTasks) + { + tupleRow.get<0>()->GetProgressInfo().Serialize(rSerializer); + } +} + TSubTaskBase::ESubOperationResult TSubTasksArray::Execute(bool bRunOnlyEstimationSubTasks) { + if(!m_pSubTaskContext) + THROW_CORE_EXCEPTION(eErr_InternalProblem); + TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; - TTaskBasicProgressInfo& rBasicProgressInfo = m_rSubTaskContext.GetTaskBasicProgressInfo(); - size_t stSubOperationIndex = m_rSubTaskContext.GetTaskBasicProgressInfo().GetSubOperationIndex(); + size_t stSubOperationIndex = m_tProgressInfo.GetSubOperationIndex(); for(; stSubOperationIndex < m_vSubTasks.size() && eResult == TSubTaskBase::eSubResult_Continue; ++stSubOperationIndex) { boost::tuples::tuple& rCurrentSubTask = m_vSubTasks[stSubOperationIndex]; TSubTaskBasePtr spCurrentSubTask = rCurrentSubTask.get<0>(); - m_rSubTaskContext.GetTaskLocalStats().SetCurrentSubOperationType(spCurrentSubTask->GetSubOperationType()); + m_pSubTaskContext->GetTaskLocalStats().SetCurrentSubOperationType(spCurrentSubTask->GetSubOperationType()); // set current sub-operation index to allow resuming - m_rSubTaskContext.GetTaskBasicProgressInfo().SetSubOperationIndex(stSubOperationIndex); + m_tProgressInfo.SetSubOperationIndex(stSubOperationIndex); // if we run in estimation mode only, then stop processing and return to the caller if(bRunOnlyEstimationSubTasks && !rCurrentSubTask.get<2>()) @@ -93,11 +211,6 @@ } eResult = spCurrentSubTask->Exec(); - if(eResult == TSubTaskBase::eSubResult_Continue) - { - // reset progress for each subtask - rBasicProgressInfo.SetCurrentIndex(0); - } } return eResult; Index: src/libchcore/TSubTaskArray.h =================================================================== diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskArray.h (.../TSubTaskArray.h) (revision 835e0344e9677ff02eb3b539061c48c9f3a616ce) +++ src/libchcore/TSubTaskArray.h (.../TSubTaskArray.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -32,24 +32,71 @@ class TOperationPlan; class TSubTaskContext; +class TReadBinarySerializer; +class TWriteBinarySerializer; + +namespace details +{ + /////////////////////////////////////////////////////////////////////////// + // TTaskBasicProgressInfo + + class LIBCHCORE_API TTaskBasicProgressInfo + { + public: + TTaskBasicProgressInfo(); + ~TTaskBasicProgressInfo(); + + void ResetProgress(); + + void SetSubOperationIndex(size_t stSubOperationIndex); + size_t GetSubOperationIndex() const; + void IncreaseSubOperationIndex(); + + void Serialize(TReadBinarySerializer& rSerializer); + void Serialize(TWriteBinarySerializer& rSerializer) const; + + private: + TTaskBasicProgressInfo(const TTaskBasicProgressInfo& rSrc); + + private: + volatile size_t m_stSubOperationIndex; // index of sub-operation from TOperationDescription + +#pragma warning(push) +#pragma warning(disable: 4251) + mutable boost::shared_mutex m_lock; +#pragma warning(pop) + }; +} + +/////////////////////////////////////////////////////////////////////////// +// TTaskBasicProgressInfo class LIBCHCORE_API TSubTasksArray { public: + TSubTasksArray(); TSubTasksArray(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext); ~TSubTasksArray(); + void Init(const TOperationPlan& rOperationPlan, TSubTaskContext& rSubTaskContext); + void ResetProgress(); + + void SerializeProgress(TReadBinarySerializer& rSerializer); + void SerializeProgress(TWriteBinarySerializer& rSerializer) const; + TSubTaskBase::ESubOperationResult Execute(bool bRunOnlyEstimationSubTasks); private: TSubTasksArray(const TSubTasksArray& rSrc); TSubTasksArray& operator=(const TSubTasksArray& rSrc); private: + TSubTaskContext* m_pSubTaskContext; + #pragma warning(push) #pragma warning(disable: 4251) std::vector > m_vSubTasks; // pointer to the subtask object / part of the whole process / is this the part of estimation? + details::TTaskBasicProgressInfo m_tProgressInfo; #pragma warning(pop) - TSubTaskContext& m_rSubTaskContext; }; END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskBase.h =================================================================== diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskBase.h (.../TSubTaskBase.h) (revision d88274a4bbfd4ef005d44c4d179b7596cb627486) +++ src/libchcore/TSubTaskBase.h (.../TSubTaskBase.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -36,6 +36,17 @@ /////////////////////////////////////////////////////////////////////////// // TSubTaskBase +class LIBCHCORE_API TSubTaskProgressInfo +{ +public: + virtual ~TSubTaskProgressInfo() {} + + virtual void Serialize(TReadBinarySerializer& rSerializer) = 0; + virtual void Serialize(TWriteBinarySerializer& rSerializer) const = 0; + + virtual void ResetProgress() = 0; +}; + class LIBCHCORE_API TSubTaskBase { public: @@ -55,6 +66,8 @@ virtual ESubOperationResult Exec() = 0; virtual ESubOperationType GetSubOperationType() const = 0; + virtual TSubTaskProgressInfo& GetProgressInfo() = 0; + TSubTaskContext& GetContext() { return m_rContext; } const TSubTaskContext& GetContext() const { return m_rContext; } Index: src/libchcore/TSubTaskContext.cpp =================================================================== diff -u -r4d20d0e58f37f06ac91287015b960308db54d47e -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskContext.cpp (.../TSubTaskContext.cpp) (revision 4d20d0e58f37f06ac91287015b960308db54d47e) +++ src/libchcore/TSubTaskContext.cpp (.../TSubTaskContext.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -26,13 +26,12 @@ BEGIN_CHCORE_NAMESPACE TSubTaskContext::TSubTaskContext(TTaskDefinition& rTaskDefinition, TBasePathDataContainer& rBasePathDataContainer, TFileInfoArray& rFilesCache, TTaskLocalStats& rTaskLocalStats, - TTaskBasicProgressInfo& rTaskBasicProgressInfo, TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, IFeedbackHandler* piFeedbackHandler, + TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, IFeedbackHandler* piFeedbackHandler, TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal) : m_rTaskDefinition(rTaskDefinition), m_rBasePathDataContainer(rBasePathDataContainer), m_rFilesCache(rFilesCache), m_rTaskLocalStats(rTaskLocalStats), - m_rTaskBasicProgressInfo(rTaskBasicProgressInfo), m_rCfgTracker(rCfgTracker), m_rLog(rLog), m_piFeedbackHandler(piFeedbackHandler), Index: src/libchcore/TSubTaskContext.h =================================================================== diff -u -r4d20d0e58f37f06ac91287015b960308db54d47e -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskContext.h (.../TSubTaskContext.h) (revision 4d20d0e58f37f06ac91287015b960308db54d47e) +++ src/libchcore/TSubTaskContext.h (.../TSubTaskContext.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -49,7 +49,7 @@ { public: TSubTaskContext(TTaskDefinition& rTaskDefinition, TBasePathDataContainer& rBasePathDataContainer, TFileInfoArray& rFilesCache, TTaskLocalStats& rTaskLocalStats, - TTaskBasicProgressInfo& rTaskBasicProgressInfo, TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, + TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, IFeedbackHandler* piFeedbackHandler, TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal); ~TSubTaskContext(); @@ -65,9 +65,6 @@ TTaskLocalStats& GetTaskLocalStats() { return m_rTaskLocalStats; } const TTaskLocalStats& GetTaskLocalStats() const { return m_rTaskLocalStats; } - TTaskBasicProgressInfo& GetTaskBasicProgressInfo() { return m_rTaskBasicProgressInfo; } - const TTaskBasicProgressInfo& GetTaskBasicProgressInfo() const { return m_rTaskBasicProgressInfo; } - TTaskConfigTracker& GetCfgTracker() { return m_rCfgTracker; } const TTaskConfigTracker& GetCfgTracker() const { return m_rCfgTracker; } @@ -98,7 +95,6 @@ // local stats for task TTaskLocalStats& m_rTaskLocalStats; - TTaskBasicProgressInfo& m_rTaskBasicProgressInfo; // configuration changes tracking TTaskConfigTracker& m_rCfgTracker; Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -r297ce850732d4243414c851df145ca97bd696baa -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 297ce850732d4243414c851df145ca97bd696baa) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -29,7 +29,6 @@ #include "DataBuffer.h" #include "../libicpf/log.h" #include "TTaskLocalStats.h" -#include "TBasicProgressInfo.h" #include "TTaskConfigTracker.h" #include "TWorkerThreadController.h" #include "FeedbackHandlerBase.h" @@ -38,9 +37,98 @@ #include #include "TFileInfo.h" #include "TFileInfoArray.h" +#include "SerializationHelpers.h" +#include "TBinarySerializer.h" BEGIN_CHCORE_NAMESPACE +namespace details +{ + /////////////////////////////////////////////////////////////////////////////////////////////////// + // class TCopyMoveProgressInfo + + TCopyMoveProgressInfo::TCopyMoveProgressInfo() : + m_stCurrentIndex(0), + m_ullCurrentFileProcessedSize(0) + { + } + + TCopyMoveProgressInfo::~TCopyMoveProgressInfo() + { + } + + void TCopyMoveProgressInfo::Serialize(TReadBinarySerializer& rSerializer) + { + size_t stIndex = 0; + unsigned long long ullFilePos = 0; + + Serializers::Serialize(rSerializer, stIndex); + Serializers::Serialize(rSerializer, ullFilePos); + + boost::unique_lock lock(m_lock); + m_stCurrentIndex = stIndex; + m_ullCurrentFileProcessedSize = ullFilePos; + } + + void TCopyMoveProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const + { + size_t stIndex = 0; + unsigned long long ullFilePos = 0; + + { + boost::shared_lock lock(m_lock); + stIndex = m_stCurrentIndex; + ullFilePos = m_ullCurrentFileProcessedSize; + } + + Serializers::Serialize(rSerializer, stIndex); + Serializers::Serialize(rSerializer, ullFilePos); + } + + void TCopyMoveProgressInfo::ResetProgress() + { + boost::unique_lock lock(m_lock); + m_stCurrentIndex = 0; + } + + void TCopyMoveProgressInfo::SetCurrentIndex(size_t stIndex) + { + boost::unique_lock lock(m_lock); + m_stCurrentIndex = stIndex; + } + + void TCopyMoveProgressInfo::IncreaseCurrentIndex() + { + boost::unique_lock lock(m_lock); + ++m_stCurrentIndex; + } + + size_t TCopyMoveProgressInfo::GetCurrentIndex() const + { + boost::shared_lock lock(m_lock); + return m_stCurrentIndex; + } + + void TCopyMoveProgressInfo::SetCurrentFileProcessedSize(unsigned long long ullSize) + { + boost::unique_lock lock(m_lock); + m_ullCurrentFileProcessedSize = ullSize; + } + + unsigned long long TCopyMoveProgressInfo::GetCurrentFileProcessedSize() const + { + boost::shared_lock lock(m_lock); + return m_ullCurrentFileProcessedSize; + } + + void TCopyMoveProgressInfo::IncreaseCurrentFileProcessedSize(unsigned long long ullSizeToAdd) + { + boost::unique_lock lock(m_lock); + m_ullCurrentFileProcessedSize += ullSizeToAdd; + } + +} + // assume max sectors of 4kB (for rounding) #define MAXSECTORSIZE 4096 @@ -54,6 +142,9 @@ bool bProcessed; // has the element been processed ? (false if skipped) }; +/////////////////////////////////////////////////////////////////////////////////////////////////// +// class TSubTaskCopyMove + TSubTaskCopyMove::TSubTaskCopyMove(TSubTaskContext& tSubTaskContext) : TSubTaskBase(tSubTaskContext) { @@ -65,7 +156,6 @@ TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition(); TTaskConfigTracker& rCfgTracker = GetContext().GetCfgTracker(); - TTaskBasicProgressInfo& rBasicProgressInfo = GetContext().GetTaskBasicProgressInfo(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler(); TTaskLocalStats& rLocalStats = GetContext().GetTaskLocalStats(); @@ -77,8 +167,12 @@ // log rLog.logi(_T("Processing files/folders (ProcessFiles)")); - // count how much has been done (updates also a member in TSubTaskCopyMoveArray) - rLocalStats.SetProcessedSize(rFilesCache.CalculatePartialSize(rBasicProgressInfo.GetCurrentIndex())); + // update stats + rLocalStats.SetProcessedSize(rFilesCache.CalculatePartialSize(m_tProgressInfo.GetCurrentIndex())); + rLocalStats.SetTotalSize(rFilesCache.CalculateTotalSize()); + rLocalStats.SetCurrentIndex(m_tProgressInfo.GetCurrentIndex()); + rLocalStats.SetTotalItems(rFilesCache.GetSize()); + rLocalStats.SetCurrentPath(TString()); // now it's time to check if there is enough space on destination device TSubTaskBase::ESubOperationResult eResult = CheckForFreeSpaceFB(); @@ -125,13 +219,14 @@ strFormat.Replace(_T("%filecount"), boost::lexical_cast(stSize).c_str()); strFormat.Replace(_T("%ignorefolders"), boost::lexical_cast(bIgnoreFolders).c_str()); strFormat.Replace(_T("%dstpath"), rTaskDefinition.GetDestinationPath().ToString()); - strFormat.Replace(_T("%currindex"), boost::lexical_cast(rBasicProgressInfo.GetCurrentIndex()).c_str()); + strFormat.Replace(_T("%currindex"), boost::lexical_cast(m_tProgressInfo.GetCurrentIndex()).c_str()); rLog.logi(strFormat); - for(size_t stIndex = rBasicProgressInfo.GetCurrentIndex(); stIndex < stSize; stIndex++) + size_t stIndex = m_tProgressInfo.GetCurrentIndex(); + for(; stIndex < stSize; stIndex++) { - rBasicProgressInfo.SetCurrentIndex(stIndex); + m_tProgressInfo.SetCurrentIndex(stIndex); // should we kill ? if(rThreadController.KillRequested()) @@ -142,19 +237,23 @@ } // next file to be copied - TFileInfoPtr spFileInfo = rFilesCache.GetAt(rBasicProgressInfo.GetCurrentIndex()); + TFileInfoPtr spFileInfo = rFilesCache.GetAt(stIndex); + TSmartPath pathCurrent = spFileInfo->GetFullFilePath(); + rLocalStats.SetCurrentIndex(stIndex); + rLocalStats.SetCurrentPath(pathCurrent.ToString()); + // set dest path with filename ccp.pathDstFile = CalculateDestinationPath(spFileInfo, rTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); // are the files/folders lie on the same partition ? bool bMove = rTaskDefinition.GetOperationType() == eOperation_Move; - TSmartPath pathCurrent = spFileInfo->GetFullFilePath(); + // if folder - create it if(spFileInfo->IsDirectory()) { bool bRetry = true; - if(bRetry && !TLocalFilesystem::CreateDirectory(ccp.pathDstFile, false) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS ) + if(bRetry && !TLocalFilesystem::CreateDirectory(ccp.pathDstFile, false) && (dwLastError = GetLastError()) != ERROR_ALREADY_EXISTS) { // log strFormat = _T("Error %errno while calling CreateDirectory %path (ProcessFiles)"); @@ -219,12 +318,13 @@ TLocalFilesystem::SetAttributes(ccp.pathDstFile, spFileInfo->GetAttributes()); // as above } + m_tProgressInfo.SetCurrentIndex(stIndex); + rLocalStats.SetCurrentIndex(stIndex); + rLocalStats.SetCurrentPath(TString()); + // delete buffer - it's not needed ccp.dbBuffer.Delete(); - // to look better (as 100%) - increase current index by 1 - rBasicProgressInfo.SetCurrentIndex(stSize); - // log rLog.logi(_T("Finished processing in ProcessFiles")); @@ -263,7 +363,6 @@ TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CustomCopyFileFB(CUSTOM_COPY_PARAMS* pData) { TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition(); - TTaskBasicProgressInfo& rBasicProgressInfo = GetContext().GetTaskBasicProgressInfo(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); TTaskLocalStats& rLocalStats = GetContext().GetTaskLocalStats(); icpf::log_file& rLog = GetContext().GetLog(); @@ -290,7 +389,7 @@ else if(!fileSrc.IsOpen()) { // invalid handle = operation skipped by user - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -305,7 +404,7 @@ unsigned long long ullSeekTo = 0; bool bDstFileFreshlyCreated = false; - if(rBasicProgressInfo.GetCurrentFileProcessedSize() == 0) + if(m_tProgressInfo.GetCurrentFileProcessedSize() == 0) { // open destination file for case, when we start operation on this file (i.e. it is not resume of the // old operation) @@ -314,7 +413,7 @@ return eResult; else if(!fileDst.IsOpen()) { - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -327,12 +426,12 @@ return eResult; else if(!fileDst.IsOpen()) { - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } - ullSeekTo = rBasicProgressInfo.GetCurrentFileProcessedSize(); + ullSeekTo = m_tProgressInfo.GetCurrentFileProcessedSize(); } if(!pData->bOnlyCreate) @@ -348,7 +447,7 @@ return eResult; else if(bSkip) { - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -359,12 +458,12 @@ else if(bSkip) { // with either first or second seek we got 'skip' answer... - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } - rBasicProgressInfo.IncreaseCurrentFileProcessedSize(ullMove); + m_tProgressInfo.IncreaseCurrentFileProcessedSize(ullMove); rLocalStats.IncreaseProcessedSize(ullMove); } @@ -450,7 +549,7 @@ return eResult; else if(bSkip) { - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -476,13 +575,13 @@ return eResult; else if(bSkip) { - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } // increase count of processed data - rBasicProgressInfo.IncreaseCurrentFileProcessedSize(ulWritten); + m_tProgressInfo.IncreaseCurrentFileProcessedSize(ulWritten); rLocalStats.IncreaseProcessedSize(ulWritten); // calculate count of bytes left to be written @@ -504,19 +603,19 @@ return eResult; else if(!fileDst.IsOpen()) { - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } // move file pointer to the end of destination file - eResult = SetFilePointerFB(fileDst, rBasicProgressInfo.GetCurrentFileProcessedSize(), pData->pathDstFile, bSkip); + eResult = SetFilePointerFB(fileDst, m_tProgressInfo.GetCurrentFileProcessedSize(), pData->pathDstFile, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) { // with either first or second seek we got 'skip' answer... - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } @@ -531,13 +630,13 @@ return eResult; else if(bSkip) { - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); pData->bProcessed = false; return TSubTaskBase::eSubResult_Continue; } // increase count of processed data - rBasicProgressInfo.IncreaseCurrentFileProcessedSize(ulRead); + m_tProgressInfo.IncreaseCurrentFileProcessedSize(ulRead); rLocalStats.IncreaseProcessedSize(ulRead); } } @@ -547,11 +646,11 @@ else { // we don't copy contents, but need to increase processed size - rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - rBasicProgressInfo.GetCurrentFileProcessedSize()); + rLocalStats.IncreaseProcessedSize(pData->spSrcFile->GetLength64() - m_tProgressInfo.GetCurrentFileProcessedSize()); } pData->bProcessed = true; - rBasicProgressInfo.SetCurrentFileProcessedSize(0); + m_tProgressInfo.SetCurrentFileProcessedSize(0); return TSubTaskBase::eSubResult_Continue; } Index: src/libchcore/TSubTaskCopyMove.h =================================================================== diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision d88274a4bbfd4ef005d44c4d179b7596cb627486) +++ src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -32,7 +32,42 @@ class TLocalFilesystemFile; typedef boost::shared_ptr TFileInfoPtr; struct CUSTOM_COPY_PARAMS; +class TReadBinarySerializer; +class TWriteBinarySerializer; +namespace details +{ + /////////////////////////////////////////////////////////////////////////// + // TCopyMoveProgressInfo + + class TCopyMoveProgressInfo : public TSubTaskProgressInfo + { + public: + TCopyMoveProgressInfo(); + virtual ~TCopyMoveProgressInfo(); + + virtual void Serialize(TReadBinarySerializer& rSerializer); + virtual void Serialize(TWriteBinarySerializer& rSerializer) const; + + virtual void ResetProgress(); + + // file being processed + void SetCurrentIndex(size_t stIndex); + void IncreaseCurrentIndex(); + size_t GetCurrentIndex() const; + + // part of file being processed + void SetCurrentFileProcessedSize(unsigned long long ullSize); + unsigned long long GetCurrentFileProcessedSize() const; + void IncreaseCurrentFileProcessedSize(unsigned long long ullSizeToAdd); + + private: + volatile size_t m_stCurrentIndex; + volatile unsigned long long m_ullCurrentFileProcessedSize; // count of bytes processed for current file + mutable boost::shared_mutex m_lock; + }; +} + class LIBCHCORE_API TSubTaskCopyMove : public TSubTaskBase { public: @@ -41,6 +76,8 @@ virtual ESubOperationResult Exec(); virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Copying; } + virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; } + private: int GetBufferIndex(const TFileInfoPtr& spFileInfo); @@ -58,6 +95,12 @@ ESubOperationResult CreateDirectoryFB(const TSmartPath& pathDirectory); ESubOperationResult CheckForFreeSpaceFB(); + +private: +#pragma warning(push) +#pragma warning(disable: 4251) + details::TCopyMoveProgressInfo m_tProgressInfo; +#pragma warning(pop) }; END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskDelete.cpp =================================================================== diff -u -r297ce850732d4243414c851df145ca97bd696baa -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision 297ce850732d4243414c851df145ca97bd696baa) +++ src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -23,7 +23,6 @@ #include "stdafx.h" #include "TSubTaskDelete.h" #include "TSubTaskContext.h" -#include "TBasicProgressInfo.h" #include "TWorkerThreadController.h" #include "TTaskConfiguration.h" #include "TTaskDefinition.h" @@ -33,9 +32,66 @@ #include #include "TFileInfoArray.h" #include "TFileInfo.h" +#include "SerializationHelpers.h" +#include "TBinarySerializer.h" +#include "TTaskLocalStats.h" BEGIN_CHCORE_NAMESPACE +namespace details +{ + /////////////////////////////////////////////////////////////////////////////////////////////////// + // class TDeleteProgressInfo + + TDeleteProgressInfo::TDeleteProgressInfo() : + m_stCurrentIndex(0) + { + } + + TDeleteProgressInfo::~TDeleteProgressInfo() + { + } + + void TDeleteProgressInfo::Serialize(TReadBinarySerializer& rSerializer) + { + boost::unique_lock lock(m_lock); + Serializers::Serialize(rSerializer, m_stCurrentIndex); + } + + void TDeleteProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const + { + boost::shared_lock lock(m_lock); + Serializers::Serialize(rSerializer, m_stCurrentIndex); + } + + void TDeleteProgressInfo::ResetProgress() + { + boost::unique_lock lock(m_lock); + m_stCurrentIndex = 0; + } + + void TDeleteProgressInfo::SetCurrentIndex(size_t stIndex) + { + boost::unique_lock lock(m_lock); + m_stCurrentIndex = stIndex; + } + + void TDeleteProgressInfo::IncreaseCurrentIndex() + { + boost::unique_lock lock(m_lock); + ++m_stCurrentIndex; + } + + size_t TDeleteProgressInfo::GetCurrentIndex() const + { + boost::shared_lock lock(m_lock); + return m_stCurrentIndex; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// class TSubTaskDelete + TSubTaskDelete::TSubTaskDelete(TSubTaskContext& rContext) : TSubTaskBase(rContext) { @@ -47,25 +103,35 @@ icpf::log_file& rLog = GetContext().GetLog(); TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition(); - TTaskBasicProgressInfo& rBasicProgressInfo = GetContext().GetTaskBasicProgressInfo(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler(); + TTaskLocalStats& rTaskLocalStats = GetContext().GetTaskLocalStats(); // log rLog.logi(_T("Deleting files (DeleteFiles)...")); + rTaskLocalStats.SetProcessedSize(0); + rTaskLocalStats.SetTotalSize(0); + rTaskLocalStats.SetCurrentIndex(0); + rTaskLocalStats.SetTotalItems(rFilesCache.GetSize()); + rTaskLocalStats.SetCurrentPath(TString()); + // current processed path BOOL bSuccess; TFileInfoPtr spFileInfo; TString strFormat; // index points to 0 or next item to process - size_t stIndex = rBasicProgressInfo.GetCurrentIndex(); + size_t stIndex = m_tProgressInfo.GetCurrentIndex(); while(stIndex < rFilesCache.GetSize()) { - // set index in pTask to currently deleted element - rBasicProgressInfo.SetCurrentIndex(stIndex); + spFileInfo = rFilesCache.GetAt(rFilesCache.GetSize() - stIndex - 1); + m_tProgressInfo.SetCurrentIndex(stIndex); + + rTaskLocalStats.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentPath(spFileInfo->GetFullFilePath().ToString()); + // check for kill flag if(rThreadController.KillRequested()) { @@ -75,7 +141,6 @@ } // current processed element - spFileInfo = rFilesCache.GetAt(rFilesCache.GetSize() - stIndex - 1); if(!(spFileInfo->GetFlags() & FIF_PROCESSED)) { ++stIndex; @@ -133,8 +198,9 @@ ++stIndex; }//while - // add 1 to current index - rBasicProgressInfo.IncreaseCurrentIndex(); + m_tProgressInfo.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentPath(TString()); // log rLog.logi(_T("Deleting files finished")); Index: src/libchcore/TSubTaskDelete.h =================================================================== diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskDelete.h (.../TSubTaskDelete.h) (revision 835e0344e9677ff02eb3b539061c48c9f3a616ce) +++ src/libchcore/TSubTaskDelete.h (.../TSubTaskDelete.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -28,13 +28,53 @@ BEGIN_CHCORE_NAMESPACE +class TReadBinarySerializer; +class TWriteBinarySerializer; + +namespace details +{ + /////////////////////////////////////////////////////////////////////////// + // TDeleteProgressInfo + + class TDeleteProgressInfo : public TSubTaskProgressInfo + { + public: + TDeleteProgressInfo(); + virtual ~TDeleteProgressInfo(); + + virtual void Serialize(TReadBinarySerializer& rSerializer); + virtual void Serialize(TWriteBinarySerializer& rSerializer) const; + + virtual void ResetProgress(); + + void SetCurrentIndex(size_t stIndex); + void IncreaseCurrentIndex(); + size_t GetCurrentIndex() const; + + private: + size_t m_stCurrentIndex; + mutable boost::shared_mutex m_lock; + }; +} + +/////////////////////////////////////////////////////////////////////////// +// TSubTaskDelete + class LIBCHCORE_API TSubTaskDelete : public TSubTaskBase { public: TSubTaskDelete(TSubTaskContext& rContext); virtual ESubOperationResult Exec(); virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Deleting; } + + virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; } + +private: +#pragma warning(push) +#pragma warning(disable: 4251) + details::TDeleteProgressInfo m_tProgressInfo; +#pragma warning(pop) }; END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskFastMove.cpp =================================================================== diff -u -r297ce850732d4243414c851df145ca97bd696baa -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision 297ce850732d4243414c851df145ca97bd696baa) +++ src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -33,11 +33,63 @@ #include "TTaskLocalStats.h" #include "..\libicpf\log.h" #include "TFileInfo.h" -#include "TBasicProgressInfo.h" #include +#include "SerializationHelpers.h" +#include "TBinarySerializer.h" BEGIN_CHCORE_NAMESPACE +namespace details +{ + /////////////////////////////////////////////////////////////////////////////////////////////////// + // class TFastMoveProgressInfo + + TFastMoveProgressInfo::TFastMoveProgressInfo() : + m_stCurrentIndex(0) + { + } + + TFastMoveProgressInfo::~TFastMoveProgressInfo() + { + } + + void TFastMoveProgressInfo::Serialize(TReadBinarySerializer& rSerializer) + { + boost::unique_lock lock(m_lock); + Serializers::Serialize(rSerializer, m_stCurrentIndex); + } + + void TFastMoveProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const + { + boost::shared_lock lock(m_lock); + Serializers::Serialize(rSerializer, m_stCurrentIndex); + } + + void TFastMoveProgressInfo::ResetProgress() + { + boost::unique_lock lock(m_lock); + m_stCurrentIndex = 0; + } + + void TFastMoveProgressInfo::SetCurrentIndex(size_t stIndex) + { + boost::unique_lock lock(m_lock); + m_stCurrentIndex = stIndex; + } + + void TFastMoveProgressInfo::IncreaseCurrentIndex() + { + boost::unique_lock lock(m_lock); + ++m_stCurrentIndex; + } + + size_t TFastMoveProgressInfo::GetCurrentIndex() const + { + boost::shared_lock lock(m_lock); + return m_stCurrentIndex; + } +} + TSubTaskFastMove::TSubTaskFastMove(TSubTaskContext& rContext) : TSubTaskBase(rContext) { @@ -55,14 +107,16 @@ IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); TTaskLocalStats& rTaskLocalStats = GetContext().GetTaskLocalStats(); - TTaskBasicProgressInfo& rProgressInfo = GetContext().GetTaskBasicProgressInfo(); TBasePathDataContainer& rBasePathDataContainer = GetContext().GetBasePathDataContainer(); rLog.logi(_T("Performing initial fast-move operation...")); // reset progress rTaskLocalStats.SetProcessedSize(0); rTaskLocalStats.SetTotalSize(0); + rTaskLocalStats.SetCurrentIndex(0); + rTaskLocalStats.SetTotalItems(rTaskDefinition.GetSourcePathCount()); + rTaskLocalStats.SetCurrentPath(TString()); // read filtering options TFileFiltersArray afFilters; @@ -84,11 +138,17 @@ bool bSkipInputPath = false; size_t stSize = rTaskDefinition.GetSourcePathCount(); - for(size_t stIndex = rProgressInfo.GetCurrentIndex(); stIndex < stSize ; stIndex++) + size_t stIndex = m_tProgressInfo.GetCurrentIndex(); + for(; stIndex < stSize ; stIndex++) { + TSmartPath pathCurrent = rTaskDefinition.GetSourcePathAt(stIndex); + // store currently processed index - rProgressInfo.SetCurrentIndex(stIndex); + m_tProgressInfo.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentPath(pathCurrent.ToString()); + // retrieve base path data TBasePathDataPtr spBasePathData = rBasePathDataContainer.GetAt(stIndex); if(!spBasePathData) @@ -106,7 +166,7 @@ bRetry = false; // read attributes of src file/folder - bool bExists = TLocalFilesystem::GetFileInfo(rTaskDefinition.GetSourcePathAt(stIndex), spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths()); + bool bExists = TLocalFilesystem::GetFileInfo(pathCurrent, spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths()); if(!bExists) { FEEDBACK_FILEERROR ferr = { rTaskDefinition.GetSourcePathAt(stIndex).ToString(), NULL, eFastMoveError, ERROR_FILE_NOT_FOUND }; @@ -209,6 +269,11 @@ } } + m_tProgressInfo.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentPath(TString()); + + // log rLog.logi(_T("Fast moving finished")); Index: src/libchcore/TSubTaskFastMove.h =================================================================== diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskFastMove.h (.../TSubTaskFastMove.h) (revision d88274a4bbfd4ef005d44c4d179b7596cb627486) +++ src/libchcore/TSubTaskFastMove.h (.../TSubTaskFastMove.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -30,7 +30,35 @@ BEGIN_CHCORE_NAMESPACE class TFileFiltersArray; +class TReadBinarySerializer; +class TWriteBinarySerializer; +namespace details +{ + /////////////////////////////////////////////////////////////////////////// + // TFastMoveProgressInfo + + class TFastMoveProgressInfo : public TSubTaskProgressInfo + { + public: + TFastMoveProgressInfo(); + virtual ~TFastMoveProgressInfo(); + + virtual void Serialize(TReadBinarySerializer& rSerializer); + virtual void Serialize(TWriteBinarySerializer& rSerializer) const; + + virtual void ResetProgress(); + + void SetCurrentIndex(size_t stIndex); + void IncreaseCurrentIndex(); + size_t GetCurrentIndex() const; + + private: + size_t m_stCurrentIndex; + mutable boost::shared_mutex m_lock; + }; +} + /////////////////////////////////////////////////////////////////////////// // TSubTaskFastMove @@ -43,8 +71,16 @@ virtual ESubOperationResult Exec(); virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; } + virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; } + private: int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters); + +private: +#pragma warning(push) +#pragma warning(disable: 4251) + details::TFastMoveProgressInfo m_tProgressInfo; +#pragma warning(pop) }; END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskScanDirectory.cpp =================================================================== diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision d88274a4bbfd4ef005d44c4d179b7596cb627486) +++ src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -25,7 +25,6 @@ #include "TSubTaskContext.h" #include "TTaskConfiguration.h" #include "TTaskDefinition.h" -//#include "FeedbackHandler.h" #include "TLocalFilesystem.h" #include "FeedbackHandlerBase.h" #include "TBasePathData.h" @@ -35,9 +34,64 @@ #include "..\libicpf\log.h" #include "TFileInfoArray.h" #include "TFileInfo.h" +#include "SerializationHelpers.h" +#include "TBinarySerializer.h" BEGIN_CHCORE_NAMESPACE +namespace details +{ + /////////////////////////////////////////////////////////////////////////////////////////////////// + // class TScanDirectoriesProgressInfo + + TScanDirectoriesProgressInfo::TScanDirectoriesProgressInfo() : + m_stCurrentIndex(0) + { + } + + TScanDirectoriesProgressInfo::~TScanDirectoriesProgressInfo() + { + } + + void TScanDirectoriesProgressInfo::Serialize(TReadBinarySerializer& rSerializer) + { + boost::unique_lock lock(m_lock); + Serializers::Serialize(rSerializer, m_stCurrentIndex); + } + + void TScanDirectoriesProgressInfo::Serialize(TWriteBinarySerializer& rSerializer) const + { + boost::shared_lock lock(m_lock); + Serializers::Serialize(rSerializer, m_stCurrentIndex); + } + + void TScanDirectoriesProgressInfo::ResetProgress() + { + boost::unique_lock lock(m_lock); + m_stCurrentIndex = 0; + } + + void TScanDirectoriesProgressInfo::SetCurrentIndex(size_t stIndex) + { + boost::unique_lock lock(m_lock); + m_stCurrentIndex = stIndex; + } + + void TScanDirectoriesProgressInfo::IncreaseCurrentIndex() + { + boost::unique_lock lock(m_lock); + ++m_stCurrentIndex; + } + + size_t TScanDirectoriesProgressInfo::GetCurrentIndex() const + { + boost::shared_lock lock(m_lock); + return m_stCurrentIndex; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// class TSubTaskScanDirectories TSubTaskScanDirectories::TSubTaskScanDirectories(TSubTaskContext& rContext) : TSubTaskBase(rContext) { @@ -64,6 +118,9 @@ rFilesCache.SetComplete(false); rTaskLocalStats.SetProcessedSize(0); rTaskLocalStats.SetTotalSize(0); + rTaskLocalStats.SetCurrentIndex(0); + rTaskLocalStats.SetTotalItems(rTaskDefinition.GetSourcePathCount()); + rTaskLocalStats.SetCurrentPath(TString()); // delete the content of rFilesCache rFilesCache.Clear(); @@ -81,8 +138,17 @@ bool bSkipInputPath = false; size_t stSize = rTaskDefinition.GetSourcePathCount(); - for(size_t stIndex = 0; stIndex < stSize ; stIndex++) + // NOTE: in theory, we should resume the scanning, but in practice we are always restarting scanning if interrupted. + size_t stIndex = 0; // m_tProgressInfo.GetCurrentIndex() + for(; stIndex < stSize; stIndex++) { + TSmartPath pathCurrent = rTaskDefinition.GetSourcePathAt(stIndex); + + m_tProgressInfo.SetCurrentIndex(stIndex); + + rTaskLocalStats.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentPath(pathCurrent.ToString()); + bSkipInputPath = false; TFileInfoPtr spFileInfo(boost::make_shared()); @@ -101,7 +167,7 @@ bRetry = false; // read attributes of src file/folder - bool bExists = TLocalFilesystem::GetFileInfo(rTaskDefinition.GetSourcePathAt(stIndex), spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths()); + bool bExists = TLocalFilesystem::GetFileInfo(pathCurrent, spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths()); if(!bExists) { FEEDBACK_FILEERROR ferr = { rTaskDefinition.GetSourcePathAt(stIndex).ToString(), NULL, eFastMoveError, ERROR_FILE_NOT_FOUND }; @@ -187,7 +253,10 @@ } // calc size of all files - rTaskLocalStats.SetTotalSize(rFilesCache.CalculateTotalSize()); + m_tProgressInfo.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentIndex(stIndex); + rTaskLocalStats.SetCurrentPath(TString()); + rFilesCache.SetComplete(true); // log Index: src/libchcore/TSubTaskScanDirectory.h =================================================================== diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TSubTaskScanDirectory.h (.../TSubTaskScanDirectory.h) (revision 835e0344e9677ff02eb3b539061c48c9f3a616ce) +++ src/libchcore/TSubTaskScanDirectory.h (.../TSubTaskScanDirectory.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -30,7 +30,35 @@ BEGIN_CHCORE_NAMESPACE class TFileFiltersArray; +class TReadBinarySerializer; +class TWriteBinarySerializer; +namespace details +{ + /////////////////////////////////////////////////////////////////////////// + // TScanDirectoriesProgressInfo + + class TScanDirectoriesProgressInfo : public TSubTaskProgressInfo + { + public: + TScanDirectoriesProgressInfo(); + virtual ~TScanDirectoriesProgressInfo(); + + virtual void Serialize(TReadBinarySerializer& rSerializer); + virtual void Serialize(TWriteBinarySerializer& rSerializer) const; + + virtual void ResetProgress(); + + void SetCurrentIndex(size_t stIndex); + void IncreaseCurrentIndex(); + size_t GetCurrentIndex() const; + + private: + size_t m_stCurrentIndex; + mutable boost::shared_mutex m_lock; + }; +} + /////////////////////////////////////////////////////////////////////////// // TSubTaskScanDirectories @@ -43,8 +71,16 @@ virtual ESubOperationResult Exec(); virtual ESubOperationType GetSubOperationType() const { return eSubOperation_Scanning; } + virtual TSubTaskProgressInfo& GetProgressInfo() { return m_tProgressInfo; } + private: int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters); + +private: +#pragma warning(push) +#pragma warning(disable: 4251) + details::TScanDirectoriesProgressInfo m_tProgressInfo; +#pragma warning(pop) }; END_CHCORE_NAMESPACE Index: src/libchcore/TTask.cpp =================================================================== diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision 835e0344e9677ff02eb3b539061c48c9f3a616ce) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -27,7 +27,6 @@ #pragma warning(pop) #include -#include "TSubTaskContext.h" #include "TSubTaskScanDirectory.h" #include "TSubTaskCopyMove.h" #include "TSubTaskDelete.h" @@ -56,7 +55,8 @@ m_bOftenStateModified(false), m_stSessionUniqueID(stSessionUniqueID), m_localStats(), - m_eCurrentState(eTaskState_None) + m_eCurrentState(eTaskState_None), + m_tSubTaskContext(m_tTaskDefinition, m_arrSourcePathsInfo, m_files, m_localStats, m_cfgTracker, m_log, piFeedbackHandler, m_workerThread, m_fsLocal) { BOOST_ASSERT(piFeedbackHandler); } @@ -72,6 +72,7 @@ { m_tTaskDefinition = rTaskDefinition; + m_tSubTasksArray.Init(m_tTaskDefinition.GetOperationPlan(), m_tSubTaskContext); m_arrSourcePathsInfo.SetCount(m_tTaskDefinition.GetSourcePathCount()); m_files.Clear(); } @@ -132,17 +133,6 @@ SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), nPriority); } -void TTask::CalculateProcessedSize() -{ - boost::shared_lock lock(m_lock); - CalculateProcessedSizeNL(); -} - -void TTask::CalculateProcessedSizeNL() -{ - m_localStats.SetProcessedSize(m_files.CalculatePartialSize(m_tTaskBasicProgressInfo.GetCurrentIndex())); -} - void TTask::Load(const TSmartPath& strPath) { using Serializers::Serialize; @@ -168,17 +158,14 @@ m_arrSourcePathsInfo.Serialize(readSerializer, true); m_files.Serialize(readSerializer, false); - CalculateTotalSizeNL(); - /////////////////////////////////// // and often changing data TSmartPath pathOftenChangingPath = GetRelatedPathNL(ePathType_TaskOftenChangingState); readSerializer.Init(pathOftenChangingPath); - Serialize(readSerializer, m_tTaskBasicProgressInfo); + m_tSubTasksArray.Init(m_tTaskDefinition.GetOperationPlan(), m_tSubTaskContext); + m_tSubTasksArray.SerializeProgress(readSerializer); - CalculateProcessedSizeNL(); - // load task state, convert "waiting" state to "processing" int iState = eTaskState_None; Serialize(readSerializer, iState); @@ -238,7 +225,7 @@ TWriteBinarySerializer writeSerializer; writeSerializer.Init(GetRelatedPathNL(ePathType_TaskOftenChangingState)); - Serialize(writeSerializer, m_tTaskBasicProgressInfo); + m_tSubTasksArray.SerializeProgress(writeSerializer); // store current state (convert from waiting to processing state before storing) int iState = m_eCurrentState; @@ -299,7 +286,7 @@ SetTaskState(eTaskState_None); m_localStats.SetTimeElapsed(0); - m_tTaskBasicProgressInfo.SetCurrentIndex(0); + m_tSubTasksArray.ResetProgress(); BeginProcessing(); } @@ -329,68 +316,24 @@ void TTask::GetMiniSnapshot(TASK_MINI_DISPLAY_DATA *pData) { boost::shared_lock lock(m_lock); - size_t stCurrentIndex = m_tTaskBasicProgressInfo.GetCurrentIndex(); - - if(stCurrentIndex < m_files.GetSize()) - pData->m_strPath = m_files.GetAt(stCurrentIndex)->GetFullFilePath().GetFileName().ToString(); - else - { - if(m_files.GetSize() > 0) - pData->m_strPath = m_files.GetAt(0)->GetFullFilePath().GetFileName().ToString(); - else - { - if(m_tTaskDefinition.GetSourcePathCount() > 0) - pData->m_strPath = m_tTaskDefinition.GetSourcePathAt(0).GetFileName().ToString(); - else - pData->m_strPath.Clear(); - } - } - + pData->m_strPath = m_localStats.GetCurrentPath(); pData->m_eTaskState = m_eCurrentState; - - // percents pData->m_nPercent = m_localStats.GetProgressInPercent(); } void TTask::GetSnapshot(TASK_DISPLAY_DATA *pData) { boost::unique_lock lock(m_lock); - size_t stCurrentIndex = m_tTaskBasicProgressInfo.GetCurrentIndex(); - if(stCurrentIndex < m_files.GetSize()) - { - pData->m_strFullFilePath = m_files.GetAt(stCurrentIndex)->GetFullFilePath().ToString(); - pData->m_strFileName = m_files.GetAt(stCurrentIndex)->GetFullFilePath().GetFileName().ToString(); - } - else - { - if(m_files.GetSize() > 0) - { - pData->m_strFullFilePath = m_files.GetAt(0)->GetFullFilePath().ToString(); - pData->m_strFileName = m_files.GetAt(0)->GetFullFilePath().GetFileName().ToString(); - } - else - { - if(m_tTaskDefinition.GetSourcePathCount() > 0) - { - pData->m_strFullFilePath = m_tTaskDefinition.GetSourcePathAt(0).ToString(); - pData->m_strFileName = m_tTaskDefinition.GetSourcePathAt(0).GetFileName().ToString(); - } - else - { - pData->m_strFullFilePath.Clear(); - pData->m_strFileName.Clear(); - } - } - } - + pData->m_strFullFilePath = m_localStats.GetCurrentPath(); + pData->m_strFileName = chcore::PathFromString(pData->m_strFullFilePath).GetFileName().ToString(); pData->m_nPriority = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); pData->m_pathDstPath = m_tTaskDefinition.GetDestinationPath(); pData->m_pafFilters = &m_afFilters; pData->m_eTaskState = m_eCurrentState; - pData->m_stIndex = stCurrentIndex; + pData->m_stIndex = m_localStats.GetCurrentIndex(); + pData->m_stSize = m_localStats.GetTotalItems(); pData->m_ullProcessedSize = m_localStats.GetProcessedSize(); - pData->m_stSize = m_files.GetSize(); pData->m_ullSizeAll = m_localStats.GetTotalSize(); pData->m_strUniqueName = m_tTaskDefinition.GetTaskUniqueID(); pData->m_eOperationType = m_tTaskDefinition.GetOperationType(); @@ -399,10 +342,7 @@ pData->m_bIgnoreDirectories = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); pData->m_bCreateEmptyFiles = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); - if(m_files.GetSize() > 0) - pData->m_iCurrentBufferIndex = m_localStats.GetCurrentBufferIndex(); - else - pData->m_iCurrentBufferIndex = TBufferSizes::eBuffer_Default; + pData->m_iCurrentBufferIndex = m_localStats.GetCurrentBufferIndex(); switch(pData->m_iCurrentBufferIndex) { @@ -521,11 +461,6 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -void TTask::CalculateTotalSizeNL() -{ - m_localStats.SetTotalSize(m_files.CalculateTotalSize()); -} - void TTask::SetForceFlagNL(bool bFlag) { m_bForce=bFlag; @@ -615,19 +550,16 @@ m_localStats.EnableTimeTracking(); // prepare context for subtasks - TSubTaskContext tSubTaskContext(m_tTaskDefinition, m_arrSourcePathsInfo, m_files, m_localStats, m_tTaskBasicProgressInfo, m_cfgTracker, m_log, m_piFeedbackHandler, m_workerThread, m_fsLocal); - TSubTasksArray tOperation(m_tTaskDefinition.GetOperationPlan(), tSubTaskContext); - if(bReadTasksSize) - eResult = tOperation.Execute(true); + eResult = m_tSubTasksArray.Execute(true); if(eResult == TSubTaskBase::eSubResult_Continue) { m_localStats.DisableTimeTracking(); eResult = CheckForWaitState(); // operation limiting m_localStats.EnableTimeTracking(); } if(eResult == TSubTaskBase::eSubResult_Continue) - eResult = tOperation.Execute(false); + eResult = m_tSubTasksArray.Execute(false); // change status to finished if(eResult == TSubTaskBase::eSubResult_Continue) Index: src/libchcore/TTask.h =================================================================== diff -u -rba802caea92ee56a154d1da3fe89a4b2f7875f0e -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TTask.h (.../TTask.h) (revision ba802caea92ee56a154d1da3fe89a4b2f7875f0e) +++ src/libchcore/TTask.h (.../TTask.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -27,10 +27,11 @@ #include "TBasePathData.h" #include "TSubTaskBase.h" #include "TTaskLocalStats.h" -#include "TBasicProgressInfo.h" #include "..\libicpf\log.h" #include "TLocalFilesystem.h" #include "TFileInfoArray.h" +#include "TSubTaskArray.h" +#include "TSubTaskContext.h" BEGIN_CHCORE_NAMESPACE @@ -179,11 +180,6 @@ void SetStatusNL(UINT nStatus, UINT nMask); UINT GetStatusNL(UINT nMask = 0xffffffff); - void CalculateProcessedSize(); - void CalculateProcessedSizeNL(); - - void CalculateTotalSizeNL(); - void DeleteProgress(); void SetForceFlagNL(bool bFlag = true); @@ -207,6 +203,9 @@ // task initial information (needed to start a task); might be a bit processed. TTaskDefinition m_tTaskDefinition; + TSubTasksArray m_tSubTasksArray; + TSubTaskContext m_tSubTaskContext; + TTaskConfigTracker m_cfgTracker; TBasePathDataContainer m_arrSourcePathsInfo; @@ -218,8 +217,6 @@ // changing fast volatile ETaskCurrentState m_eCurrentState; // current state of processing this task represents - TTaskBasicProgressInfo m_tTaskBasicProgressInfo; // task progress information - // task control variables (per-session state) TTaskLocalStats m_localStats; // local statistics Index: src/libchcore/TTaskLocalStats.cpp =================================================================== diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TTaskLocalStats.cpp (.../TTaskLocalStats.cpp) (revision 835e0344e9677ff02eb3b539061c48c9f3a616ce) +++ src/libchcore/TTaskLocalStats.cpp (.../TTaskLocalStats.cpp) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -30,13 +30,15 @@ //////////////////////////////////////////////////////////////////////////////// // TTasksGlobalStats members TTaskLocalStats::TTaskLocalStats() : -m_prtGlobalStats(NULL), -m_ullProcessedSize(0), -m_ullTotalSize(0), -m_bTaskIsRunning(false), -m_timeElapsed(0), -m_timeLast(-1), -m_iCurrentBufferIndex(0) + m_prtGlobalStats(NULL), + m_ullProcessedSize(0), + m_ullTotalSize(0), + m_stCurrentIndex(0), + m_stTotalItems(0), + m_bTaskIsRunning(false), + m_timeElapsed(0), + m_timeLast(-1), + m_iCurrentBufferIndex(0) { } @@ -156,6 +158,30 @@ return m_ullTotalSize; } +size_t TTaskLocalStats::GetCurrentIndex() const +{ + boost::shared_lock lock(m_lock); + return m_stCurrentIndex; +} + +void TTaskLocalStats::SetCurrentIndex(size_t stIndex) +{ + boost::unique_lock lock(m_lock); + m_stCurrentIndex = stIndex; +} + +size_t TTaskLocalStats::GetTotalItems() +{ + boost::shared_lock lock(m_lock); + return m_stTotalItems; +} + +void TTaskLocalStats::SetTotalItems(size_t stCount) +{ + boost::unique_lock lock(m_lock); + m_stTotalItems = stCount; +} + int TTaskLocalStats::GetProgressInPercent() const { boost::shared_lock lock(m_lock); @@ -168,6 +194,18 @@ return boost::numeric_cast(ullPercent); } +void TTaskLocalStats::SetCurrentPath(const TString& strPath) +{ + boost::unique_lock lock(m_lock); + m_strCurrentPath = strPath; +} + +const TString& TTaskLocalStats::GetCurrentPath() const +{ + boost::shared_lock lock(m_lock); + return m_strCurrentPath; +} + void TTaskLocalStats::MarkTaskAsRunning() { boost::unique_lock lock(m_lock); Index: src/libchcore/TTaskLocalStats.h =================================================================== diff -u -r835e0344e9677ff02eb3b539061c48c9f3a616ce -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/TTaskLocalStats.h (.../TTaskLocalStats.h) (revision 835e0344e9677ff02eb3b539061c48c9f3a616ce) +++ src/libchcore/TTaskLocalStats.h (.../TTaskLocalStats.h) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -25,6 +25,7 @@ #include "libchcore.h" #include "ESubTaskTypes.h" +#include "TString.h" BEGIN_CHCORE_NAMESPACE @@ -50,8 +51,17 @@ void SetTotalSize(unsigned long long ullSet); unsigned long long GetTotalSize() const; + size_t GetCurrentIndex() const; + void SetCurrentIndex(size_t stIndex); + + size_t GetTotalItems(); + void SetTotalItems(size_t stCount); + int GetProgressInPercent() const; + void SetCurrentPath(const TString& strPath); + const TString& GetCurrentPath() const; + void MarkTaskAsRunning(); void MarkTaskAsNotRunning(); bool IsRunning() const; @@ -73,6 +83,9 @@ volatile unsigned long long m_ullProcessedSize; volatile unsigned long long m_ullTotalSize; + volatile size_t m_stCurrentIndex; + volatile size_t m_stTotalItems; + volatile bool m_bTaskIsRunning; // time @@ -83,6 +96,8 @@ volatile ESubOperationType m_eCurrentSubOperationType; + TString m_strCurrentPath; + #pragma warning(push) #pragma warning(disable: 4251) mutable boost::shared_mutex m_lock; Index: src/libchcore/libchcore.vc90.vcproj =================================================================== diff -u -rd88274a4bbfd4ef005d44c4d179b7596cb627486 -rbebda797ec6983535a8940f8f9f15453fe6b1785 --- src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision d88274a4bbfd4ef005d44c4d179b7596cb627486) +++ src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision bebda797ec6983535a8940f8f9f15453fe6b1785) @@ -1,7 +1,7 @@ - - - -