Index: src/ch/CfgProperties.h =================================================================== diff -u -r2b57bcded3d6ce4fe87b73dc0227e7ec82628505 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/ch/CfgProperties.h (.../CfgProperties.h) (revision 2b57bcded3d6ce4fe87b73dc0227e7ec82628505) +++ src/ch/CfgProperties.h (.../CfgProperties.h) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -62,6 +62,7 @@ PP_CMPROTECTROFILES, PP_CMLIMITMAXOPERATIONS, PP_CMREADSIZEBEFOREBLOCKING, + PP_CMFASTMOVEBEFOREBLOCKING, PP_CMDEFAULTPRIORITY, PP_CMDISABLEPRIORITYBOOST, @@ -236,6 +237,7 @@ ADAPT_TASK_PROPERTY(PP_CMSETDESTDATE, chcore::eTO_SetDestinationDateTime); ADAPT_TASK_PROPERTY(PP_CMPROTECTROFILES, chcore::eTO_ProtectReadOnlyFiles); ADAPT_TASK_PROPERTY(PP_CMREADSIZEBEFOREBLOCKING, chcore::eTO_ScanDirectoriesBeforeBlocking); +ADAPT_TASK_PROPERTY(PP_CMFASTMOVEBEFOREBLOCKING, chcore::eTO_FastMoveBeforeBlocking); ADAPT_TASK_PROPERTY(PP_CMDEFAULTPRIORITY, chcore::eTO_ThreadPriority); ADAPT_TASK_PROPERTY(PP_CMDISABLEPRIORITYBOOST, chcore::eTO_DisablePriorityBoost); ADAPT_TASK_PROPERTY(PP_CMDELETEAFTERFINISHED, chcore::eTO_DeleteInSeparateSubTask); Index: src/ch/OptionsDlg.cpp =================================================================== diff -u -rdcfc3dd0a3cda2ab5dd3f5b63980acb5a63c855a -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/ch/OptionsDlg.cpp (.../OptionsDlg.cpp) (revision dcfc3dd0a3cda2ab5dd3f5b63980acb5a63c855a) +++ src/ch/OptionsDlg.cpp (.../OptionsDlg.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -283,6 +283,7 @@ PROP_BOOL(IDS_PROTECTROFILES_STRING, GetPropValue(GetConfig())); PROP_UINT(IDS_LIMITOPERATIONS_STRING, GetPropValue(GetConfig())); PROP_BOOL(IDS_READSIZEBEFOREBLOCK_STRING, GetPropValue(GetConfig())); + PROP_BOOL(IDS_FASTMOVEBEFOREBLOCK_STRING, GetPropValue(GetConfig())); PROP_COMBO(IDS_DEFAULTPRIORITY_STRING, MakeCompoundString(IDS_PRIORITY0_STRING, 7, _T("!")), PriorityToIndex(boost::numeric_cast(GetPropValue(GetConfig())))); PROP_BOOL(IDS_CFGDISABLEPRIORITYBOOST_STRING, GetPropValue(GetConfig())); PROP_BOOL(IDS_DELETEAFTERFINISHED_STRING, GetPropValue(GetConfig())); @@ -392,6 +393,7 @@ SetPropValue(rConfig, GetBoolProp(iPosition++)); SetPropValue(rConfig, GetUintProp(iPosition++)); SetPropValue(rConfig, GetBoolProp(iPosition++)); + SetPropValue(rConfig, GetBoolProp(iPosition++)); SetPropValue(rConfig, IndexToPriority(GetIndexProp(iPosition++))); SetPropValue(rConfig, GetBoolProp(iPosition++)); SetPropValue(rConfig, GetBoolProp(iPosition++)); Index: src/ch/ch.rc =================================================================== diff -u -rc6022cc2c68d1f286097697f4ba65098b92db222 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/ch/ch.rc (.../ch.rc) (revision c6022cc2c68d1f286097697f4ba65098b92db222) +++ src/ch/ch.rc (.../ch.rc) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -872,8 +872,9 @@ IDS_SOUNDONERROR_STRING "Sound on error" IDS_SOUNDONFINISH_STRING "Sound on copying finished" IDS_LANGUAGE_STRING "Language" - IDS_READSIZEBEFOREBLOCK_STRING "Read tasks size before blocking" - IDS_USENOBUFFERING_STRING "Disable buffering for large files" + IDS_READSIZEBEFOREBLOCK_STRING "Read tasks size before blocking" + IDS_FASTMOVEBEFOREBLOCK_STRING "Use fast move before blocking" + IDS_USENOBUFFERING_STRING "Disable buffering for large files" IDS_LARGEFILESMINSIZE_STRING "Minimum file size for which buffering should be turned off" IDS_OPTIONSBUFFER_STRING "Buffer" Index: src/ch/resource.h =================================================================== diff -u -rc6022cc2c68d1f286097697f4ba65098b92db222 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/ch/resource.h (.../resource.h) (revision c6022cc2c68d1f286097697f4ba65098b92db222) +++ src/ch/resource.h (.../resource.h) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -525,6 +525,7 @@ #define IDS_CFGLOGLEVEL_VALUES 8100 #define IDS_UPDATE_FREQUENCIES 8101 #define IDS_BUFFER_QUEUE_DEPTH 8102 +#define IDS_FASTMOVEBEFOREBLOCK_STRING 8039 #define IDS_MENUCOPY_STRING 9000 #define IDS_MENUMOVE_STRING 9001 #define IDS_MENUCOPYMOVESPECIAL_STRING 9002 Index: src/libchcore/TFileInfo.cpp =================================================================== diff -u -re8f31b0f922b402878356e130c866c4f3682a7f5 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TFileInfo.cpp (.../TFileInfo.cpp) (revision e8f31b0f922b402878356e130c866c4f3682a7f5) +++ src/libchcore/TFileInfo.cpp (.../TFileInfo.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -183,6 +183,14 @@ return m_uiFlags & eFlag_Processed; } + bool TFileInfo::IsBasePathProcessed() const + { + if(!m_spBasePathData.Get()) + return false; + + return m_spBasePathData.Get()->GetSkipFurtherProcessing(); + } + ULONGLONG TFileInfo::GetLength64() const { return m_uhFileSize; Index: src/libchcore/TFileInfo.h =================================================================== diff -u -ra27d1acf1bda3c25b6dcce0d0eb0278009ce63ae -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TFileInfo.h (.../TFileInfo.h) (revision a27d1acf1bda3c25b6dcce0d0eb0278009ce63ae) +++ src/libchcore/TFileInfo.h (.../TFileInfo.h) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -100,6 +100,7 @@ void MarkAsProcessed(bool bProcessed); bool IsProcessed() const; + bool IsBasePathProcessed() const; void Store(const ISerializerContainerPtr& spContainer) const; static void InitColumns(IColumnsDefinition& rColumns); Index: src/libchcore/TSubTaskArray.cpp =================================================================== diff -u -re8f31b0f922b402878356e130c866c4f3682a7f5 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision e8f31b0f922b402878356e130c866c4f3682a7f5) +++ src/libchcore/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -34,6 +34,7 @@ #include "TCoreException.h" #include "ErrorCodes.h" #include +#include "TTaskConfiguration.h" namespace chcore { @@ -71,30 +72,55 @@ m_eOperationType = rOperationPlan.GetOperationType(); + bool bReadTasksSizeBeforeBlocking = GetTaskPropValue(m_rSubTaskContext.GetConfig()); + bool bFastMoveBeforeBlocking = GetTaskPropValue(m_rSubTaskContext.GetConfig()); + switch (m_eOperationType) { case eOperation_Copy: - { - TSubTaskBasePtr spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); - AddSubTask(spOperation, true); - spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); - AddSubTask(spOperation, false); + { + TSubTaskBasePtr spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); + AddSubTask(spOperation, bReadTasksSizeBeforeBlocking); + spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); + AddSubTask(spOperation, false); - break; - } + break; + } + case eOperation_Move: - { - TSubTaskBasePtr spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); - AddSubTask(spOperation, true); - spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); - AddSubTask(spOperation, false); - spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); - AddSubTask(spOperation, false); - spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); - AddSubTask(spOperation, false); + { + TSubTaskBasePtr spOperation; + bool bReorderFastMove = bReadTasksSizeBeforeBlocking && !bFastMoveBeforeBlocking; - break; - } + // fastmove (if not reordered) + if(!bReorderFastMove) + { + spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); + AddSubTask(spOperation, bFastMoveBeforeBlocking); + } + + // scanning + spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); + AddSubTask(spOperation, bReadTasksSizeBeforeBlocking); + + // fastmove (if reordered) + if(bReorderFastMove) + { + spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); + AddSubTask(spOperation, bFastMoveBeforeBlocking); + } + + // copy/move + spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); + AddSubTask(spOperation, false); + + // delete + spOperation = boost::make_shared(boost::ref(m_rSubTaskContext)); + AddSubTask(spOperation, false); + + break; + } + default: throw TCoreException(eErr_UndefinedOperation, L"Operation type not known to the engine", LOCATION); } Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -rc6022cc2c68d1f286097697f4ba65098b92db222 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision c6022cc2c68d1f286097697f4ba65098b92db222) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -186,6 +186,14 @@ m_tSubTaskStats.SetCurrentItemSilentResume(bCurrentFileSilentResume); bCurrentFileSilentResume = false; + // if the file was already processed (e.g. by fast-move), just consider the file skipped + if(spFileInfo->IsBasePathProcessed()) + { + AdjustProcessedSizeForSkip(spFileInfo); + spFileInfo->MarkAsProcessed(true); + continue; + } + // set dest path with filename ccp.pathDstFile = CalculateDestinationPath(spFileInfo, pathDestination, ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); Index: src/libchcore/TSubTaskDelete.cpp =================================================================== diff -u -ra27d1acf1bda3c25b6dcce0d0eb0278009ce63ae -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision a27d1acf1bda3c25b6dcce0d0eb0278009ce63ae) +++ src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -124,8 +124,9 @@ return TSubTaskBase::eSubResult_KillRequest; } - // current processed element - if (!spFileInfo->IsProcessed()) + // if the file/dir was not processed by copy/move then do not delete + // on the other hand, if the base path was processed (at this this it would be only by fast-move) then skip deleting + if (!spFileInfo->IsProcessed() || spFileInfo->IsBasePathProcessed()) { ++fcIndex; continue; Index: src/libchcore/TSubTaskStatsSnapshot.cpp =================================================================== diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TSubTaskStatsSnapshot.cpp (.../TSubTaskStatsSnapshot.cpp) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/TSubTaskStatsSnapshot.cpp (.../TSubTaskStatsSnapshot.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -102,15 +102,15 @@ double TSubTaskStatsSnapshot::GetAvgSizeSpeed() const { if (m_timeElapsed) - return Math::Div64(m_ullProcessedSize, m_timeElapsed / 1000); + return Math::Div64(m_ullProcessedSize, m_timeElapsed / 1000.0); else return 0.0; } double TSubTaskStatsSnapshot::GetAvgCountSpeed() const { if (m_timeElapsed) - return Math::Div64(m_fcProcessedCount, m_timeElapsed / 1000); + return Math::Div64(m_fcProcessedCount, m_timeElapsed / 1000.0); else return 0.0; } Index: src/libchcore/TTask.cpp =================================================================== diff -u -re8f31b0f922b402878356e130c866c4f3682a7f5 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision e8f31b0f922b402878356e130c866c4f3682a7f5) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -528,15 +528,11 @@ HANDLE hThread = GetCurrentThread(); ::SetThreadPriorityBoost(hThread, GetTaskPropValue(m_tConfiguration)); - // determine when to scan directories - bool bReadTasksSize = GetTaskPropValue(m_tConfiguration); - // initialize subtask array m_tSubTasksArray.InitBeforeExec(); - // exec the estimation subtasks - if (bReadTasksSize) - eResult = m_tSubTasksArray.Execute(spFeedbackHandler, true); + // exec the estimation subtasks + eResult = m_tSubTasksArray.Execute(spFeedbackHandler, true); // go into wait state only in case the preprocessing did not finish the operation already // (only fast move can do that right now) Index: src/libchcore/TTaskConfigTracker.cpp =================================================================== diff -u -re8f31b0f922b402878356e130c866c4f3682a7f5 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TTaskConfigTracker.cpp (.../TTaskConfigTracker.cpp) (revision e8f31b0f922b402878356e130c866c4f3682a7f5) +++ src/libchcore/TTaskConfigTracker.cpp (.../TTaskConfigTracker.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -222,8 +222,10 @@ return eTO_SetDestinationDateTime; else if (strOption == TaskPropData::GetPropertyName()) return eTO_ProtectReadOnlyFiles; - else if (strOption == TaskPropData::GetPropertyName()) + else if(strOption == TaskPropData::GetPropertyName()) return eTO_ScanDirectoriesBeforeBlocking; + else if(strOption == TaskPropData::GetPropertyName()) + return eTO_FastMoveBeforeBlocking; else if (strOption == TaskPropData::GetPropertyName()) return eTO_ThreadPriority; else if (strOption == TaskPropData::GetPropertyName()) Index: src/libchcore/TTaskConfiguration.h =================================================================== diff -u -r54cdc3807a3e7abfb33fa09db6c49d312658b2e5 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TTaskConfiguration.h (.../TTaskConfiguration.h) (revision 54cdc3807a3e7abfb33fa09db6c49d312658b2e5) +++ src/libchcore/TTaskConfiguration.h (.../TTaskConfiguration.h) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -48,6 +48,7 @@ eTO_SetDestinationDateTime, eTO_ProtectReadOnlyFiles, eTO_ScanDirectoriesBeforeBlocking, + eTO_FastMoveBeforeBlocking, eTO_ThreadPriority, eTO_DisablePriorityBoost, eTO_DeleteInSeparateSubTask, @@ -109,7 +110,8 @@ TASK_PROPERTY(eTO_SetDestinationAttributes, bool, _T("Operation.SetDestinationAttributes"), true); TASK_PROPERTY(eTO_SetDestinationDateTime, bool, _T("Operation.SetDestinationTime"), true); TASK_PROPERTY(eTO_ProtectReadOnlyFiles, bool, _T("Operation.ProtectReadOnlyFiles"), false); - TASK_PROPERTY(eTO_ScanDirectoriesBeforeBlocking, bool, _T("Operation.ScanForFilesBeforeBlocking"), true); + TASK_PROPERTY(eTO_ScanDirectoriesBeforeBlocking, bool, _T("Operation.ScanForFilesBeforeBlocking"), false); + TASK_PROPERTY(eTO_FastMoveBeforeBlocking, bool, _T("Operation.FastMoveBeforeBlocking"), false); // Thread settings TASK_PROPERTY(eTO_ThreadPriority, int, _T("Operation.Thread.Priority"), THREAD_PRIORITY_NORMAL); Index: src/libchcore/TTaskOperationPlan.cpp =================================================================== diff -u -re8f31b0f922b402878356e130c866c4f3682a7f5 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TTaskOperationPlan.cpp (.../TTaskOperationPlan.cpp) (revision e8f31b0f922b402878356e130c866c4f3682a7f5) +++ src/libchcore/TTaskOperationPlan.cpp (.../TTaskOperationPlan.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -36,13 +36,9 @@ } TOperationPlan::TOperationPlan(const TOperationPlan& rSrc) : - m_eOperation(eOperation_None), - m_vSubOperations() + m_eOperation(eOperation_None) { - boost::shared_lock src_lock(rSrc.m_lock); - - m_eOperation = rSrc.m_eOperation; - m_vSubOperations = rSrc.m_vSubOperations; + SetOperationType(rSrc.GetOperationType()); } TOperationPlan::~TOperationPlan() @@ -52,50 +48,14 @@ TOperationPlan& TOperationPlan::operator=(const TOperationPlan& rSrc) { if (this != &rSrc) - { - boost::shared_lock src_lock(rSrc.m_lock); - boost::unique_lock lock(m_lock); + SetOperationType(rSrc.GetOperationType()); - m_eOperation = rSrc.m_eOperation; - m_vSubOperations = rSrc.m_vSubOperations; - } - return *this; } void TOperationPlan::SetOperationType(EOperationType eOperation) { - switch (eOperation) - { - case eOperation_None: - throw TCoreException(eErr_InvalidArgument, L"eOperation", LOCATION); - break; - - case eOperation_Copy: - { - boost::unique_lock lock(m_lock); - m_vSubOperations.clear(); - m_vSubOperations.push_back(std::make_pair(eSubOperation_Scanning, 0.05)); - m_vSubOperations.push_back(std::make_pair(eSubOperation_Copying, 0.95)); - break; - } - - case eOperation_Move: - { - boost::unique_lock lock(m_lock); - m_vSubOperations.clear(); - m_vSubOperations.push_back(std::make_pair(eSubOperation_Scanning, 0.05)); - m_vSubOperations.push_back(std::make_pair(eSubOperation_Copying, 0.90)); - m_vSubOperations.push_back(std::make_pair(eSubOperation_Deleting, 0.05)); - break; - } - - BOOST_STATIC_ASSERT(eOperation_Move == eOperation_Max - 1); - - default: - throw TCoreException(eErr_UnhandledCase, L"Unknown operation type", LOCATION); - } - + boost::unique_lock lock(m_lock); m_eOperation = eOperation; } Index: src/libchcore/TTaskOperationPlan.h =================================================================== diff -u -rcb4e9d4b60d62b25ae2cf556c0642601af56c787 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TTaskOperationPlan.h (.../TTaskOperationPlan.h) (revision cb4e9d4b60d62b25ae2cf556c0642601af56c787) +++ src/libchcore/TTaskOperationPlan.h (.../TTaskOperationPlan.h) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -49,8 +49,6 @@ EOperationType m_eOperation; #pragma warning(push) #pragma warning(disable: 4251) - std::vector > m_vSubOperations; ///< Vector of sub-task type and estimated part in the entire task time - mutable boost::shared_mutex m_lock; #pragma warning(pop) }; Index: src/libchcore/TTaskStatsSnapshot.cpp =================================================================== diff -u -rcb4e9d4b60d62b25ae2cf556c0642601af56c787 -rbe569bc86280887eeebb8d3e9489f6fc17c570e6 --- src/libchcore/TTaskStatsSnapshot.cpp (.../TTaskStatsSnapshot.cpp) (revision cb4e9d4b60d62b25ae2cf556c0642601af56c787) +++ src/libchcore/TTaskStatsSnapshot.cpp (.../TTaskStatsSnapshot.cpp) (revision be569bc86280887eeebb8d3e9489f6fc17c570e6) @@ -181,7 +181,7 @@ CalculateProgressAndSpeeds(); if (m_ullTimeElapsed) - return Math::Div64(m_ullProcessedCount, m_ullTimeElapsed / 1000); + return Math::Div64(m_ullProcessedCount, m_ullTimeElapsed / 1000.0); else return 0.0; } @@ -192,7 +192,7 @@ CalculateProgressAndSpeeds(); if (m_ullTimeElapsed) - return Math::Div64(m_ullProcessedSize, m_ullTimeElapsed / 1000); + return Math::Div64(m_ullProcessedSize, m_ullTimeElapsed / 1000.0); else return 0.0; }