Index: src/libchcore/TSQLiteSerializerRowData.cpp =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TSQLiteSerializerRowData.cpp (.../TSQLiteSerializerRowData.cpp) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/TSQLiteSerializerRowData.cpp (.../TSQLiteSerializerRowData.cpp) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -21,6 +21,8 @@ #include "TSQLiteStatement.h" #include #include +#include "TSerializerException.h" +#include "ErrorCodes.h" BEGIN_CHCORE_NAMESPACE @@ -194,6 +196,11 @@ ATLTRACE(_T("Executing query: %s\n"), (PCTSTR)strQuery); tStatement.Step(); + + int iChanges = tStatement.Changes(); + _ASSERTE(iChanges == 1); + if(iChanges != 1) + THROW_SERIALIZER_EXCEPTION(eErr_InvalidData, _T("Update query did not update record in the database")); } } Index: src/libchcore/TSQLiteStatement.cpp =================================================================== diff -u -N -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TSQLiteStatement.cpp (.../TSQLiteStatement.cpp) (revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429) +++ src/libchcore/TSQLiteStatement.cpp (.../TSQLiteStatement.cpp) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -86,6 +86,11 @@ } } + int TSQLiteStatement::Changes() + { + return sqlite3_changes((sqlite3*)m_spDatabase->GetHandle()); + } + void TSQLiteStatement::BindValue(int iColumn, bool bValue) { BindValue(iColumn, bValue ? 1 : 0); Index: src/libchcore/TSQLiteStatement.h =================================================================== diff -u -N -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TSQLiteStatement.h (.../TSQLiteStatement.h) (revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429) +++ src/libchcore/TSQLiteStatement.h (.../TSQLiteStatement.h) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -65,6 +65,7 @@ void ClearBindings(); EStepResult Step(); + int Changes(); void Reset(); bool GetBool(int iCol); Index: src/libchcore/TSQLiteTaskSchema.cpp =================================================================== diff -u -N -rb193a95402f2bf4c456fb9d65d111caaf6994823 -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision b193a95402f2bf4c456fb9d65d111caaf6994823) +++ src/libchcore/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -66,6 +66,9 @@ _T(")")); tStatement.Step(); + tStatement.Prepare(_T("CREATE TABLE local_stats(id BIGINT UNIQUE, elapsed_time BIGINT NOT NULL)")); + tStatement.Step(); + // and finally set the database version to current one tVersion.SetVersion(1); } Index: src/libchcore/TSimpleTimer.cpp =================================================================== diff -u -N -r9b8cccbee0fcfeca28a112cc0253a7641f73f74f -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TSimpleTimer.cpp (.../TSimpleTimer.cpp) (revision 9b8cccbee0fcfeca28a112cc0253a7641f73f74f) +++ src/libchcore/TSimpleTimer.cpp (.../TSimpleTimer.cpp) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -76,4 +76,16 @@ m_ullTotalTime = 0; } +void TSimpleTimer::Init(unsigned long long ullTotalTime) +{ + Stop(); + m_ullTotalTime = ullTotalTime; + m_ullLastTime = 0; +} + +bool TSimpleTimer::IsRunning() const +{ + return m_bStarted; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TSimpleTimer.h =================================================================== diff -u -N -r9b8cccbee0fcfeca28a112cc0253a7641f73f74f -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TSimpleTimer.h (.../TSimpleTimer.h) (revision 9b8cccbee0fcfeca28a112cc0253a7641f73f74f) +++ src/libchcore/TSimpleTimer.h (.../TSimpleTimer.h) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -30,12 +30,15 @@ TSimpleTimer(bool bAutostart = false, const ITimestampProviderPtr& spTimestampProvider = ITimestampProviderPtr()); ~TSimpleTimer(); + void Init(unsigned long long ullTotalTime); + void Start(); unsigned long long Stop(); // returns total time unsigned long long Tick(); // returns current timestamp void Reset(); + bool IsRunning() const; unsigned long long GetTotalTime() const { return m_ullTotalTime; } unsigned long long GetLastTimestamp() const { return m_ullLastTime; } Index: src/libchcore/TTask.cpp =================================================================== diff -u -N -rb193a95402f2bf4c456fb9d65d111caaf6994823 -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision b193a95402f2bf4c456fb9d65d111caaf6994823) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -148,6 +148,9 @@ spContainer = m_spSerializer->GetContainer(_T("filters")); m_afFilters.Load(spContainer); + + spContainer = m_spSerializer->GetContainer(_T("local_stats")); + m_tLocalStats.Load(spContainer); } } @@ -173,6 +176,9 @@ spContainer = m_spSerializer->GetContainer(_T("filters")); m_afFilters.Store(spContainer); + + spContainer = m_spSerializer->GetContainer(_T("local_stats")); + m_tLocalStats.Store(spContainer); } m_spSerializer->Flush(); Index: src/libchcore/TTask.h =================================================================== diff -u -N -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TTask.h (.../TTask.h) (revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429) +++ src/libchcore/TTask.h (.../TTask.h) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -152,7 +152,6 @@ TTaskConfigTracker m_cfgTracker; - // current task state (derivatives of the task initial information) // changing slowly or only partially TFileInfoArray m_files; // list of files/directories found during operating on the task input data (filled by search for files) Index: src/libchcore/TTaskLocalStats.cpp =================================================================== diff -u -N -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TTaskLocalStats.cpp (.../TTaskLocalStats.cpp) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTaskLocalStats.cpp (.../TTaskLocalStats.cpp) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -26,6 +26,9 @@ #include #include "DataBuffer.h" #include "TTaskStatsSnapshot.h" +#include "ISerializerContainer.h" +#include "ISerializerRowData.h" +#include "TRowData.h" BEGIN_CHCORE_NAMESPACE @@ -84,8 +87,10 @@ //////////////////////////////////////////////////////////////////////////////// // TTasksGlobalStats members TTaskLocalStatsInfo::TTaskLocalStatsInfo() : + m_tTimer(m_setModifications), m_bTaskIsRunning(false) { + m_setModifications[eMod_Added] = true; } TTaskLocalStatsInfo::~TTaskLocalStatsInfo() @@ -95,15 +100,15 @@ void TTaskLocalStatsInfo::Clear() { m_bTaskIsRunning = false; - m_tTimer.Reset(); + m_tTimer.Modify().Reset(); } void TTaskLocalStatsInfo::GetSnapshot(TTaskStatsSnapshotPtr& spSnapshot) const { boost::upgrade_lock lock(m_lock); UpdateTime(lock); spSnapshot->SetTaskRunning(m_bTaskIsRunning); - spSnapshot->SetTimeElapsed(m_tTimer.GetTotalTime()); + spSnapshot->SetTimeElapsed(m_tTimer.Get().GetTotalTime()); } void TTaskLocalStatsInfo::MarkTaskAsRunning() @@ -127,19 +132,62 @@ void TTaskLocalStatsInfo::EnableTimeTracking() { boost::unique_lock lock(m_lock); - m_tTimer.Start(); + m_tTimer.Modify().Start(); } void TTaskLocalStatsInfo::DisableTimeTracking() { boost::unique_lock lock(m_lock); - m_tTimer.Stop(); + m_tTimer.Modify().Stop(); } void TTaskLocalStatsInfo::UpdateTime(boost::upgrade_lock& lock) const { - boost::upgrade_to_unique_lock lock_upgraded(lock); - m_tTimer.Tick(); + // if the timer is not running then there is no point modifying timer object + if(m_tTimer.Get().IsRunning()) + { + boost::upgrade_to_unique_lock lock_upgraded(lock); + m_tTimer.Modify().Tick(); + } } +void TTaskLocalStatsInfo::Store(const ISerializerContainerPtr& spContainer) const +{ + boost::shared_lock lock(m_lock); + + ISerializerRowDataPtr spRow; + bool bAdded = m_setModifications[eMod_Added]; + if(bAdded) + spRow = spContainer->AddRow(0); + else if(m_setModifications.any()) + spRow = spContainer->GetRow(0); + else + return; + + if(bAdded || m_setModifications[eMod_Timer]) + { + *spRow % TRowData(_T("elapsed_time"), m_tTimer.Get().GetTotalTime()); + m_setModifications.reset(); + } +} + +void TTaskLocalStatsInfo::Load(const ISerializerContainerPtr& spContainer) +{ + boost::unique_lock lock(m_lock); + + IColumnsDefinitionPtr spColumns = spContainer->GetColumnsDefinition(); + if(spColumns->IsEmpty()) + *spColumns % _T("id") % _T("elapsed_time"); + + ISerializerRowReaderPtr spRowReader = spContainer->GetRowReader(); + if(spRowReader->Next()) + { + unsigned long long ullTime = 0; + spRowReader->GetValue(_T("elapsed_time"), ullTime); + m_tTimer.Modify().Init(ullTime); + + m_setModifications.reset(); + } +} + END_CHCORE_NAMESPACE Index: src/libchcore/TTaskLocalStats.h =================================================================== diff -u -N -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -r320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41 --- src/libchcore/TTaskLocalStats.h (.../TTaskLocalStats.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTaskLocalStats.h (.../TTaskLocalStats.h) (revision 320c4eb6ba3a38dcd6fbda6a9a12a8350a153e41) @@ -27,6 +27,7 @@ #include "ESubTaskTypes.h" #include "TSubTaskStatsInfo.h" #include "TTaskStatsSnapshot.h" +#include "TSharedModificationTracker.h" BEGIN_CHCORE_NAMESPACE @@ -68,6 +69,9 @@ bool IsRunning() const; + void Store(const ISerializerContainerPtr& spContainer) const; + void Load(const ISerializerContainerPtr& spContainer); + protected: // running/not running state void MarkTaskAsRunning(); @@ -90,9 +94,20 @@ TTaskLocalStatsInfo& operator=(const TTaskLocalStatsInfo&); private: + enum EModifications + { + eMod_Added, + eMod_Timer, + + eMod_Last + }; + + typedef std::bitset Bitset; + mutable Bitset m_setModifications; + volatile bool m_bTaskIsRunning; - mutable TSimpleTimer m_tTimer; + mutable TSharedModificationTracker m_tTimer; #pragma warning(push) #pragma warning(disable: 4251)