Index: src/libchcore/TIntrusiveSerializableItem.cpp =================================================================== diff -u -N --- src/libchcore/TIntrusiveSerializableItem.cpp (revision 0) +++ src/libchcore/TIntrusiveSerializableItem.cpp (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -0,0 +1,76 @@ +// ============================================================================ +// Copyright (C) 2001-2014 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. +// ============================================================================ +#include "stdafx.h" +#include "TIntrusiveSerializableItem.h" + +BEGIN_CHCORE_NAMESPACE + +TIntrusiveSerializableItem::TIntrusiveSerializableItem() : + m_stObjectID(0), + m_iModifications(0) +{ +} + +TIntrusiveSerializableItem::TIntrusiveSerializableItem(size_t stObjectID, int iModifications) : + m_stObjectID(stObjectID), + m_iModifications(iModifications) +{ +} + +TIntrusiveSerializableItem::~TIntrusiveSerializableItem() +{ +} + +void TIntrusiveSerializableItem::SetModification(int iFlags, int iMask) +{ + m_iModifications &= ~iMask; + m_iModifications |= (iFlags & iMask); +} + +int TIntrusiveSerializableItem::GetModifications() const +{ + return m_iModifications; +} + +bool TIntrusiveSerializableItem::IsAdded() const +{ + return m_iModifications & eMod_Added; +} + +bool TIntrusiveSerializableItem::IsModified() const +{ + return m_iModifications != 0; +} + +void TIntrusiveSerializableItem::SetObjectID(size_t stObjectID) +{ + m_stObjectID = stObjectID; +} + +size_t TIntrusiveSerializableItem::GetObjectID() const +{ + return m_stObjectID; +} + +void TIntrusiveSerializableItem::ResetModifications() +{ + m_iModifications = eMod_None; +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TIntrusiveSerializableItem.h =================================================================== diff -u -N --- src/libchcore/TIntrusiveSerializableItem.h (revision 0) +++ src/libchcore/TIntrusiveSerializableItem.h (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -0,0 +1,61 @@ +// ============================================================================ +// Copyright (C) 2001-2014 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. +// ============================================================================ +#ifndef __TINTRUSIVESERIALIZABLEITEM_H__ +#define __TINTRUSIVESERIALIZABLEITEM_H__ + +#include "libchcore.h" +#include + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TIntrusiveSerializableItem +{ +public: + enum EModificationFlags + { + eMod_None = 0, + eMod_Added = 1, + eMod_Modified = 2, // a base for derived classes to implement own modified states + }; + +public: + TIntrusiveSerializableItem(); + TIntrusiveSerializableItem(size_t stObjectID, int iModifications = eMod_None); + virtual ~TIntrusiveSerializableItem(); + + void SetModification(int iFlags, int iMask = std::numeric_limits::max()); + int GetModifications() const; + void ResetModifications(); + + bool IsAdded() const; + bool IsModified() const; // has modifications? added state is also considered a modification + + void SetObjectID(size_t stObjectID); + size_t GetObjectID() const; + +protected: + size_t m_stObjectID; + int m_iModifications; +}; + +typedef boost::shared_ptr TIntrusiveSerializableItemPtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TSQLiteSerializer.cpp =================================================================== diff -u -N -r9479911a096555a7504c5c8a8eaee83ecb63440c -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/TSQLiteSerializer.cpp (.../TSQLiteSerializer.cpp) (revision 9479911a096555a7504c5c8a8eaee83ecb63440c) +++ src/libchcore/TSQLiteSerializer.cpp (.../TSQLiteSerializer.cpp) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -38,7 +38,7 @@ ISerializerContainerPtr TSQLiteSerializer::GetContainer(const TString& strContainerName) { - std::map::iterator iterMap = m_mapContainers.find(strContainerName); + ContainerMap::iterator iterMap = m_mapContainers.find(strContainerName); if(iterMap == m_mapContainers.end()) iterMap = m_mapContainers.insert(std::make_pair( strContainerName, Index: src/libchcore/TSQLiteSerializer.h =================================================================== diff -u -N -r9479911a096555a7504c5c8a8eaee83ecb63440c -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/TSQLiteSerializer.h (.../TSQLiteSerializer.h) (revision 9479911a096555a7504c5c8a8eaee83ecb63440c) +++ src/libchcore/TSQLiteSerializer.h (.../TSQLiteSerializer.h) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -26,6 +26,7 @@ #include "TString.h" #include "ISerializerContainer.h" #include "TPath.h" +#include "TSQLiteSerializerContainer.h" #include "ISQLiteSerializerSchema.h" BEGIN_CHCORE_NAMESPACE @@ -45,7 +46,9 @@ #pragma warning(disable: 4251) sqlite::TSQLiteDatabasePtr m_spDatabase; ISerializerSchemaPtr m_spSchema; - std::map m_mapContainers; + + typedef std::map ContainerMap; + ContainerMap m_mapContainers; #pragma warning(pop) }; Index: src/libchcore/TSQLiteSerializerContainer.cpp =================================================================== diff -u -N -r9479911a096555a7504c5c8a8eaee83ecb63440c -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/TSQLiteSerializerContainer.cpp (.../TSQLiteSerializerContainer.cpp) (revision 9479911a096555a7504c5c8a8eaee83ecb63440c) +++ src/libchcore/TSQLiteSerializerContainer.cpp (.../TSQLiteSerializerContainer.cpp) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -48,24 +48,24 @@ chcore::ISerializerRowWriterPtr TSQLiteSerializerContainer::AddRow(size_t stRowID) { - std::map::iterator iterInsert = m_mapRows.insert( + RowMap::iterator iterInsert = m_mapRows.insert( std::make_pair(stRowID, TSQLiteSerializerRowWriterPtr(new TSQLiteSerializerRowWriter(stRowID, m_spColumns, true))) ).first; return (*iterInsert).second; } ISerializerRowWriterPtr TSQLiteSerializerContainer::GetRow(size_t stRowID) { - std::map::iterator iterFnd = m_mapRows.find(stRowID); + RowMap::iterator iterFnd = m_mapRows.find(stRowID); if(iterFnd == m_mapRows.end()) - iterFnd = m_mapRows.insert(std::make_pair(stRowID, ISerializerRowWriterPtr(new TSQLiteSerializerRowWriter(stRowID, m_spColumns, false)))).first; + iterFnd = m_mapRows.insert(std::make_pair(stRowID, TSQLiteSerializerRowWriterPtr(new TSQLiteSerializerRowWriter(stRowID, m_spColumns, false)))).first; return (*iterFnd).second; } void TSQLiteSerializerContainer::DeleteRow(size_t stRowID) { - std::map::iterator iterFnd = m_mapRows.find(stRowID); + RowMap::iterator iterFnd = m_mapRows.find(stRowID); if(iterFnd != m_mapRows.end()) { m_mapRows.erase(iterFnd); Index: src/libchcore/TSQLiteSerializerContainer.h =================================================================== diff -u -N -r9479911a096555a7504c5c8a8eaee83ecb63440c -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/TSQLiteSerializerContainer.h (.../TSQLiteSerializerContainer.h) (revision 9479911a096555a7504c5c8a8eaee83ecb63440c) +++ src/libchcore/TSQLiteSerializerContainer.h (.../TSQLiteSerializerContainer.h) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -20,13 +20,13 @@ #define __TSQLITESERIALIZERCONTAINER_H__ #include "libchcore.h" -#include "ISerializerRowWriter.h" #include "ISerializerRowReader.h" #include "ISerializerContainer.h" #include #include #include "TSQLiteColumnDefinition.h" #include "TSQLiteDatabase.h" +#include "TSQLiteSerializerRowWriter.h" BEGIN_CHCORE_NAMESPACE @@ -51,7 +51,9 @@ #pragma warning(disable: 4251) boost::optional m_stParentID; - std::map m_mapRows; + typedef std::map RowMap; // maps row id to row data + RowMap m_mapRows; + TSQLiteColumnDefinitionPtr m_spColumns; std::set m_setDeleteItems; Index: src/libchcore/TSQLiteTaskManagerSchema.cpp =================================================================== diff -u -N -rd32a79f0e9220bad2c6eeb5e8a986228b6e832fb -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/TSQLiteTaskManagerSchema.cpp (.../TSQLiteTaskManagerSchema.cpp) (revision d32a79f0e9220bad2c6eeb5e8a986228b6e832fb) +++ src/libchcore/TSQLiteTaskManagerSchema.cpp (.../TSQLiteTaskManagerSchema.cpp) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -45,7 +45,7 @@ if(tVersion.GetVersion() == 0) { TSQLiteStatement tStatement(spDatabase); - tStatement.Prepare(_T("CREATE TABLE tasks(task_id BIGINT UNIQUE, task_order INT, path VARCHAR(32768))")); + tStatement.Prepare(_T("CREATE TABLE tasks(id BIGINT UNIQUE PRIMARY KEY, task_order INT NOT NULL, path VARCHAR(32768) NOT NULL)")); tStatement.Step(); // and finally set the database version to current one Index: src/libchcore/TTaskInfo.cpp =================================================================== diff -u -N -r9479911a096555a7504c5c8a8eaee83ecb63440c -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/TTaskInfo.cpp (.../TTaskInfo.cpp) (revision 9479911a096555a7504c5c8a8eaee83ecb63440c) +++ src/libchcore/TTaskInfo.cpp (.../TTaskInfo.cpp) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -26,31 +26,19 @@ BEGIN_CHCORE_NAMESPACE TTaskInfoEntry::TTaskInfoEntry() : - m_tTaskID(0), - m_iOrder(0), - m_iModificationType(eMod_None) + TIntrusiveSerializableItem(), + m_iOrder(0) { } -TTaskInfoEntry::TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask, int iModification /*= eMod_None*/) : - m_tTaskID(tTaskID), +TTaskInfoEntry::TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask, int iModification) : + TIntrusiveSerializableItem(tTaskID, iModification), m_pathSerializeLocation(pathTask), m_iOrder(iOrder), - m_spTask(spTask), - m_iModificationType(iModification) + m_spTask(spTask) { } -taskid_t TTaskInfoEntry::GetTaskID() const -{ - return m_tTaskID; -} - -void TTaskInfoEntry::SetTaskID(taskid_t tTaskID) -{ - m_tTaskID = tTaskID; -} - TSmartPath TTaskInfoEntry::GetTaskSerializeLocation() const { return m_pathSerializeLocation; @@ -83,64 +71,40 @@ m_iOrder = iOrder; } -int TTaskInfoEntry::GetModifications() const -{ - return m_iModificationType; -} - -void TTaskInfoEntry::SetModification(int iModification, int iMask) -{ - m_iModificationType &= ~iMask; - m_iModificationType |= iModification; -} - -void TTaskInfoEntry::ResetModifications() -{ - m_iModificationType = 0; -} - -bool TTaskInfoEntry::IsAdded() const -{ - return m_iModificationType & eMod_Added; -} - -bool TTaskInfoEntry::IsModified() const -{ - return (m_iModificationType & ~eMod_Added) != eMod_None; -} - void TTaskInfoEntry::Store(const ISerializerContainerPtr& spContainer) { - if(m_iModificationType == eMod_None) + if(!IsModified()) return; - if(m_iModificationType & eMod_Added) + if(IsAdded()) { - ISerializerRowWriterPtr spRow = spContainer->AddRow(m_tTaskID); + ISerializerRowWriterPtr spRow = spContainer->AddRow(GetObjectID()); *spRow % TRowData(_T("path"), m_pathSerializeLocation) % TRowData(_T("task_order"), m_iOrder); } else { - ISerializerRowWriterPtr spRow = spContainer->GetRow(m_tTaskID); - if(m_iModificationType & eMod_TaskPath) + ISerializerRowWriterPtr spRow = spContainer->GetRow(GetObjectID()); + if(GetModifications() & eMod_TaskPath) *spRow % TRowData(_T("path"), m_pathSerializeLocation); - else if(m_iModificationType & eMod_Order) + else if(GetModifications() & eMod_Order) *spRow % TRowData(_T("task_order"), m_iOrder); } + + ResetModifications(); } bool TTaskInfoEntry::Load(const ISerializerRowReaderPtr& spRowReader) { IColumnsDefinitionPtr spColumns = spRowReader->GetColumnsDefinitions(); if(spColumns->IsEmpty()) - *spColumns % _T("task_id") % _T("path") % _T("task_order"); + *spColumns % _T("id") % _T("path") % _T("task_order"); bool bResult = spRowReader->Next(); if(bResult) { - spRowReader->GetValue(_T("task_id"), m_tTaskID); + spRowReader->GetValue(_T("id"), m_stObjectID); spRowReader->GetValue(_T("path"), m_pathSerializeLocation); spRowReader->GetValue(_T("task_order"), m_iOrder); } @@ -164,7 +128,7 @@ THROW_CORE_EXCEPTION(eErr_BoundsExceeded); std::vector::iterator iter = m_vTaskInfos.begin() + stIndex; - taskid_t tTaskID = (*iter).GetTaskID(); + taskid_t tTaskID = (*iter).GetObjectID(); m_vTaskInfos.erase(m_vTaskInfos.begin() + stIndex); m_setRemovedTasks.insert(tTaskID); } @@ -173,7 +137,7 @@ { BOOST_FOREACH(TTaskInfoEntry& rEntry, m_vTaskInfos) { - m_setRemovedTasks.insert(rEntry.GetTaskID()); + m_setRemovedTasks.insert(rEntry.GetObjectID()); } m_vTaskInfos.clear(); } @@ -203,7 +167,7 @@ { for(std::vector::const_iterator iter = m_vTaskInfos.begin(); iter != m_vTaskInfos.end(); ++iter) { - if((*iter).GetTaskID() == tTaskID) + if((*iter).GetObjectID() == tTaskID) { rInfo = *iter; return true; @@ -218,21 +182,6 @@ return m_vTaskInfos.empty(); } -void TTaskInfoContainer::GetDiffAndResetModifications(TTaskInfoContainer& rDiff) -{ - rDiff.Clear(); - rDiff.ClearModifications(); - - rDiff.m_setRemovedTasks.insert(m_setRemovedTasks.begin(), m_setRemovedTasks.end()); - BOOST_FOREACH(TTaskInfoEntry& rEntry, m_vTaskInfos) - { - if(rEntry.GetModifications() != TTaskInfoEntry::eMod_None) - rDiff.m_vTaskInfos.push_back(rEntry); - } - - ClearModifications(); -} - bool TTaskInfoContainer::HasDeletions() const { return !m_setRemovedTasks.empty(); @@ -277,29 +226,6 @@ return *iter; } -void TTaskInfoContainer::RestoreModifications(const TTaskInfoContainer& tDataDiff) throw() -{ - m_setRemovedTasks.insert(tDataDiff.m_setRemovedTasks.begin(), tDataDiff.m_setRemovedTasks.end()); - - for(std::vector::const_iterator iterOther = tDataDiff.m_vTaskInfos.begin(); iterOther != tDataDiff.m_vTaskInfos.end(); ++iterOther) - { - bool bFound = false; - - for(std::vector::iterator iterThis = m_vTaskInfos.begin(); iterThis != m_vTaskInfos.end(); ++iterThis) - { - if((*iterThis).GetTaskID() == (*iterOther).GetTaskID()) - { - (*iterThis).SetModification((*iterOther).GetModifications(), (*iterOther).GetModifications()); - bFound = true; - break; - } - } - - // this method is used in catch clause, so no exception allowed here - _ASSERTE(bFound); - } -} - void TTaskInfoContainer::ClearModifications() { m_setRemovedTasks.clear(); @@ -338,4 +264,19 @@ } } +taskid_t TTaskInfoContainer::GetLastTaskID() const +{ + taskid_t tLastTaskID = NoTaskID; + + BOOST_FOREACH(const TTaskInfoEntry& rEntry, m_vTaskInfos) + { + tLastTaskID = std::max(rEntry.GetObjectID(), tLastTaskID); + } + + if(!m_setRemovedTasks.empty()) + tLastTaskID = std::max(*m_setRemovedTasks.rbegin(), tLastTaskID); + + return tLastTaskID; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TTaskInfo.h =================================================================== diff -u -N -r9479911a096555a7504c5c8a8eaee83ecb63440c -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/TTaskInfo.h (.../TTaskInfo.h) (revision 9479911a096555a7504c5c8a8eaee83ecb63440c) +++ src/libchcore/TTaskInfo.h (.../TTaskInfo.h) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -25,30 +25,26 @@ #include "TPath.h" #include "TaskID.h" #include "ISerializerContainer.h" +#include "TIntrusiveSerializableItem.h" BEGIN_CHCORE_NAMESPACE class TTask; typedef boost::shared_ptr TTaskPtr; -class LIBCHCORE_API TTaskInfoEntry +class LIBCHCORE_API TTaskInfoEntry : public TIntrusiveSerializableItem { public: - enum EModificationInfo + enum ETIEntryInfo { - eMod_None = 0, - eMod_Added = 1, - eMod_TaskPath = 4, - eMod_Order = 8, + eMod_TaskPath = TIntrusiveSerializableItem::eMod_Modified, + eMod_Order = TIntrusiveSerializableItem::eMod_Modified << 1, }; public: TTaskInfoEntry(); TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask, int iModification = eMod_None); - taskid_t GetTaskID() const; - void SetTaskID(taskid_t tTaskID); - TSmartPath GetTaskSerializeLocation() const; void SetTaskSerializeLocation(const TSmartPath& pathTask); @@ -58,25 +54,16 @@ int GetOrder() const; void SetOrder(int iOrder); - int GetModifications() const; - void SetModification(int iModification, int iMask); - void ResetModifications(); - - bool IsAdded() const; - bool IsModified() const; - void Store(const ISerializerContainerPtr& spContainer); bool Load(const ISerializerRowReaderPtr& spRowReader); private: - taskid_t m_tTaskID; TSmartPath m_pathSerializeLocation; #pragma warning(push) #pragma warning(disable:4251) TTaskPtr m_spTask; #pragma warning(pop) int m_iOrder; - int m_iModificationType; // added/modified/not changed (wo deleted status) }; class LIBCHCORE_API TTaskInfoContainer @@ -90,6 +77,8 @@ TTaskInfoEntry& GetAt(size_t stIndex); const TTaskInfoEntry& GetAt(size_t stIndex) const; + taskid_t GetLastTaskID() const; + bool GetByTaskID(taskid_t tTaskID, TTaskInfoEntry& rInfo) const; size_t GetCount() const; @@ -104,8 +93,6 @@ void Store(const ISerializerContainerPtr& spContainer); void Load(const ISerializerContainerPtr& spContainer); - void GetDiffAndResetModifications(TTaskInfoContainer& rDiff); - void RestoreModifications(const TTaskInfoContainer& tDataDiff) throw(); void ClearModifications(); bool HasDeletions() const; Index: src/libchcore/TTaskManager.cpp =================================================================== diff -u -N -rd32a79f0e9220bad2c6eeb5e8a986228b6e832fb -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision d32a79f0e9220bad2c6eeb5e8a986228b6e832fb) +++ src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -370,7 +370,7 @@ TTaskStatsSnapshotPtr spStats(new TTaskStatsSnapshot); spTask->GetStatsSnapshot(spStats); - spStats->SetTaskID(rEntry.GetTaskID()); + spStats->SetTaskID(rEntry.GetObjectID()); if(spStats->IsTaskRunning() && spStats->GetTaskState()) ++stRunningTasks; @@ -460,6 +460,9 @@ ISerializerContainerPtr spContainer = m_spSerializer->GetContainer(_T("tasks")); m_tTasks.Load(spContainer); + // ensure that we assign nonexistent to new task IDs + m_stNextTaskID = m_tTasks.GetLastTaskID() + 1; + // clear all modifications of freshly loaded tasks (in case serializer does // not reset the modification state) m_tTasks.ClearModifications(); Index: src/libchcore/libchcore.vc90.vcproj =================================================================== diff -u -N -rd32a79f0e9220bad2c6eeb5e8a986228b6e832fb -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 --- src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision d32a79f0e9220bad2c6eeb5e8a986228b6e832fb) +++ src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) @@ -1324,6 +1324,14 @@ > + + + + @@ -1398,34 +1406,34 @@ RelativePath=".\TSQLiteSerializerRowWriter.h" > - - - - - - - - - - - - - - + + + + + + + + + + + + +