Index: src/libchcore/ISerializerContainer.h =================================================================== diff -u -N -r31c4b1fc46687ed2cf35dd9fa0acec2543ae1886 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/ISerializerContainer.h (.../ISerializerContainer.h) (revision 31c4b1fc46687ed2cf35dd9fa0acec2543ae1886) +++ src/libchcore/ISerializerContainer.h (.../ISerializerContainer.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -27,6 +27,7 @@ class ISerializerRowData; typedef boost::shared_ptr ISerializerRowDataPtr; +class TRemovedObjects; class LIBCHCORE_API ISerializerContainer { @@ -40,6 +41,7 @@ virtual ISerializerRowDataPtr AddRow(size_t stRowID) = 0; virtual ISerializerRowDataPtr GetRow(size_t stRowID) = 0; virtual void DeleteRow(size_t stRowID) = 0; + virtual void DeleteRows(const TRemovedObjects& setObjects) = 0; // getting data from the serialized archive virtual ISerializerRowReaderPtr GetRowReader() = 0; Index: src/libchcore/TBasePathData.cpp =================================================================== diff -u -N -r2efd22688b8d12be34c87bf2b024d8db6e317d60 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TBasePathData.cpp (.../TBasePathData.cpp) (revision 2efd22688b8d12be34c87bf2b024d8db6e317d60) +++ src/libchcore/TBasePathData.cpp (.../TBasePathData.cpp) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -26,19 +26,25 @@ #include "SerializationHelpers.h" #include "TCoreException.h" #include "ErrorCodes.h" +#include "TRowData.h" +#include "ISerializerRowData.h" BEGIN_CHCORE_NAMESPACE ////////////////////////////////////////////////////////////////////////////// // TBasePathData TBasePathData::TBasePathData() : - m_bSkipFurtherProcessing(false) + m_bSkipFurtherProcessing(m_setModifications, false), + m_pathDst(m_setModifications) { + m_setModifications[eMod_Added] = true; } TBasePathData::TBasePathData(const TBasePathData& rEntry) : - m_pathDst(rEntry.m_pathDst) + m_pathDst(rEntry.m_pathDst), + m_bSkipFurtherProcessing(rEntry.m_bSkipFurtherProcessing), + m_setModifications(rEntry.m_setModifications) { } @@ -52,22 +58,58 @@ return m_pathDst; } -void TBasePathData::Serialize(TReadBinarySerializer& rSerializer, bool bData) +bool TBasePathData::GetSkipFurtherProcessing() const { - if(bData) - Serializers::Serialize(rSerializer, m_bSkipFurtherProcessing); - else - Serializers::Serialize(rSerializer, m_pathDst); + return m_bSkipFurtherProcessing; } -void TBasePathData::Serialize(TWriteBinarySerializer& rSerializer, bool bData) +void TBasePathData::SetSkipFurtherProcessing(bool bSkipFurtherProcessing) { - if(bData) - Serializers::Serialize(rSerializer, m_bSkipFurtherProcessing); - else - Serializers::Serialize(rSerializer, m_pathDst); + m_bSkipFurtherProcessing = bSkipFurtherProcessing; } +bool TBasePathData::IsDestinationPathSet() const +{ + return !m_pathDst.Get().IsEmpty(); +} + +void TBasePathData::Store(const ISerializerContainerPtr& spContainer, size_t stObjectID) const +{ + if(!spContainer) + THROW_CORE_EXCEPTION(eErr_InvalidPointer); + + ISerializerRowDataPtr spRow; + + bool bAdded = m_setModifications.at(eMod_Added); + if(bAdded) + spRow = spContainer->AddRow(stObjectID); + else if(m_setModifications.any()) + spRow = spContainer->GetRow(stObjectID); + + if(bAdded || m_setModifications.at(eMod_SkipProcessing)) + *spRow % TRowData(_T("skip_processing"), m_bSkipFurtherProcessing); + if(bAdded || m_setModifications.at(eMod_DstPath)) + *spRow % TRowData(_T("dst_path"), m_pathDst); + + m_setModifications.reset(); +} + +void TBasePathData::InitLoader(const IColumnsDefinitionPtr& spColumnDefs) +{ + if(!spColumnDefs) + THROW_CORE_EXCEPTION(eErr_InvalidPointer); + + *spColumnDefs % _T("id") % _T("skip_processing") % _T("dst_path"); +} + +void TBasePathData::Load(const ISerializerRowReaderPtr& spRowReader, size_t& stObjectID) +{ + spRowReader->GetValue(_T("id"), stObjectID); + spRowReader->GetValue(_T("skip_processing"), m_bSkipFurtherProcessing.Modify()); + spRowReader->GetValue(_T("dst_path"), m_pathDst.Modify()); + m_setModifications.reset(); +} + ////////////////////////////////////////////////////////////////////////////// // TBasePathDataContainer @@ -118,11 +160,18 @@ { boost::unique_lock lock(m_lock); m_mapEntries.erase(stObjectID); + m_setRemovedObjects.Add(stObjectID); } void TBasePathDataContainer::Clear() { boost::unique_lock lock(m_lock); + + BOOST_FOREACH(const MapEntries::value_type& rItem, m_mapEntries) + { + m_setRemovedObjects.Add(rItem.first); + } + m_mapEntries.clear(); } @@ -159,4 +208,45 @@ return iter->second->IsDestinationPathSet(); } +void TBasePathDataContainer::Store(const ISerializerContainerPtr& spContainer) const +{ + if(!spContainer) + THROW_CORE_EXCEPTION(eErr_InvalidPointer); + + boost::shared_lock lock(m_lock); + + spContainer->DeleteRows(m_setRemovedObjects); + m_setRemovedObjects.Clear(); + + BOOST_FOREACH(const MapEntries::value_type& rPair, m_mapEntries) + { + rPair.second->Store(spContainer, rPair.first); + } +} + +void TBasePathDataContainer::Load(const ISerializerContainerPtr& spContainer) +{ + if(!spContainer) + THROW_CORE_EXCEPTION(eErr_InvalidPointer); + + boost::unique_lock lock(m_lock); + m_setRemovedObjects.Clear(); + m_mapEntries.clear(); + + ISerializerRowReaderPtr spRowReader = spContainer->GetRowReader(); + IColumnsDefinitionPtr spColumns = spRowReader->GetColumnsDefinitions(); + if(spColumns->IsEmpty()) + TBasePathData::InitLoader(spRowReader->GetColumnsDefinitions()); + + while(spRowReader->Next()) + { + TBasePathDataPtr spPathData(new TBasePathData); + size_t stObjectID = 0; + + spPathData->Load(spRowReader, stObjectID); + + m_mapEntries.insert(std::make_pair(stObjectID, spPathData)); + } +} + END_CHCORE_NAMESPACE Index: src/libchcore/TBasePathData.h =================================================================== diff -u -N -r2efd22688b8d12be34c87bf2b024d8db6e317d60 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TBasePathData.h (.../TBasePathData.h) (revision 2efd22688b8d12be34c87bf2b024d8db6e317d60) +++ src/libchcore/TBasePathData.h (.../TBasePathData.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -26,30 +26,50 @@ #include "libchcore.h" #include "TPath.h" #include "TModPathContainer.h" +#include +#include "TSharedModificationTracker.h" +#include "TRemovedObjects.h" BEGIN_CHCORE_NAMESPACE ///////////////////////////////////////////////////////////////////////////// // TBasePathData class LIBCHCORE_API TBasePathData { +private: + enum EModifications + { + eMod_Added, + eMod_SkipProcessing, + eMod_DstPath, + + eMod_Last + }; + public: TBasePathData(); TBasePathData(const TBasePathData& rEntry); - bool GetSkipFurtherProcessing() const { return m_bSkipFurtherProcessing; } - void SetSkipFurtherProcessing(bool bSkipFurtherProcessing) { m_bSkipFurtherProcessing = bSkipFurtherProcessing; } + bool GetSkipFurtherProcessing() const; + void SetSkipFurtherProcessing(bool bSkipFurtherProcessing); void SetDestinationPath(const TSmartPath& strPath); TSmartPath GetDestinationPath() const; - bool IsDestinationPathSet() const { return !m_pathDst.IsEmpty(); } + bool IsDestinationPathSet() const; - void Serialize(TReadBinarySerializer& rSerializer, bool bData); - void Serialize(TWriteBinarySerializer& rSerializer, bool bData); + void Store(const ISerializerContainerPtr& spContainer, size_t stObjectID) const; + static void InitLoader(const IColumnsDefinitionPtr& spColumnDefs); + void Load(const ISerializerRowReaderPtr& spRowReader, size_t& stObjectID); private: - bool m_bSkipFurtherProcessing; // specifies if the path should be (or not) processed further - TSmartPath m_pathDst; // dest path +#pragma warning(push) +#pragma warning(disable: 4251) + typedef std::bitset BitSet; + mutable BitSet m_setModifications; + + TSharedModificationTracker m_bSkipFurtherProcessing; // specifies if the path should be (or not) processed further + TSharedModificationTracker m_pathDst; +#pragma warning(pop) }; typedef boost::shared_ptr TBasePathDataPtr; @@ -77,6 +97,9 @@ TSmartPath GetDestinationPath(size_t stObjectID) const; bool IsDestinationPathSet(size_t stObjectID) const; + void Store(const ISerializerContainerPtr& spContainer) const; + void Load(const ISerializerContainerPtr& spContainer); + private: TBasePathDataContainer(const TBasePathDataContainer& rSrc); TBasePathDataContainer& operator=(const TBasePathDataContainer& rSrc); @@ -86,6 +109,8 @@ #pragma warning(disable: 4251) typedef std::map MapEntries; MapEntries m_mapEntries; + mutable TRemovedObjects m_setRemovedObjects; + mutable boost::shared_mutex m_lock; #pragma warning(pop) }; Index: src/libchcore/TIntrusiveSerializableItem.cpp =================================================================== diff -u -N --- src/libchcore/TIntrusiveSerializableItem.cpp (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) +++ src/libchcore/TIntrusiveSerializableItem.cpp (revision 0) @@ -1,76 +0,0 @@ -// ============================================================================ -// 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/TModPathContainer.cpp =================================================================== diff -u -N -r2efd22688b8d12be34c87bf2b024d8db6e317d60 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TModPathContainer.cpp (.../TModPathContainer.cpp) (revision 2efd22688b8d12be34c87bf2b024d8db6e317d60) +++ src/libchcore/TModPathContainer.cpp (.../TModPathContainer.cpp) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -135,7 +135,7 @@ THROW_CORE_EXCEPTION(eErr_BoundsExceeded); DataMap::iterator iter = m_vPaths.begin() + stIndex; - return iter->second.Value(); + return iter->second.Modify(); } size_t TModPathContainer::GetOidAt(size_t stIndex) const @@ -177,7 +177,7 @@ THROW_CORE_EXCEPTION(eErr_BoundsExceeded); DataMap::iterator iterDel = m_vPaths.begin() + stIndex; - m_setRemovedItems.insert(iterDel->first); + m_setRemovedItems.Add(iterDel->first); m_vPaths.erase(iterDel); } @@ -193,12 +193,12 @@ { for(DataMap::iterator iterDel = m_vPaths.begin(); iterDel != m_vPaths.end(); ++iterDel) { - m_setRemovedItems.insert(iterDel->first); + m_setRemovedItems.Add(iterDel->first); } } else { - m_setRemovedItems.clear(); + m_setRemovedItems.Clear(); m_stNextObjectID = 1; } @@ -236,7 +236,7 @@ TSmartPath& TModPathContainer::GetAtOid(size_t stObjectID) { - return m_vPaths.at(stObjectID).Value(); + return m_vPaths.at(stObjectID).Modify(); } void TModPathContainer::SetByOid(size_t stObjectID, const TSmartPath& spPath) @@ -251,12 +251,12 @@ void TModPathContainer::DeleteOid(size_t stObjectID) { m_vPaths.erase(stObjectID); - m_setRemovedItems.insert(stObjectID); + m_setRemovedItems.Add(stObjectID); } bool TModPathContainer::HasModifications() const { - if(!m_setRemovedItems.empty()) + if(!m_setRemovedItems.IsEmpty()) return true; for(DataMap::const_iterator iterDel = m_vPaths.begin(); iterDel != m_vPaths.end(); ++iterDel) @@ -270,27 +270,24 @@ void TModPathContainer::ClearModifications() { - m_setRemovedItems.clear(); + m_setRemovedItems.Clear(); for(DataMap::iterator iterDel = m_vPaths.begin(); iterDel != m_vPaths.end(); ++iterDel) { iterDel->second.ClearModifications(); } } -void TModPathContainer::Store(const ISerializerContainerPtr& spContainer) +void TModPathContainer::Store(const ISerializerContainerPtr& spContainer) const { // delete items first - BOOST_FOREACH(size_t stObjectID, m_setRemovedItems) - { - spContainer->DeleteRow(stObjectID); - } - m_setRemovedItems.clear(); + spContainer->DeleteRows(m_setRemovedItems); + m_setRemovedItems.Clear(); // add/modify - for(DataMap::iterator iterPath = m_vPaths.begin(); iterPath != m_vPaths.end(); ++iterPath) + for(DataMap::const_iterator iterPath = m_vPaths.begin(); iterPath != m_vPaths.end(); ++iterPath) { - TModificationTracker& rItem = iterPath->second; + const TModificationTracker& rItem = iterPath->second; ISerializerRowDataPtr spRow; if(rItem.IsAdded()) @@ -308,7 +305,7 @@ void TModPathContainer::Load(const ISerializerContainerPtr& spContainer) { - m_setRemovedItems.clear(); + m_setRemovedItems.Clear(); m_vPaths.clear(); m_stNextObjectID = 1; Index: src/libchcore/TModPathContainer.h =================================================================== diff -u -N -r2efd22688b8d12be34c87bf2b024d8db6e317d60 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TModPathContainer.h (.../TModPathContainer.h) (revision 2efd22688b8d12be34c87bf2b024d8db6e317d60) +++ src/libchcore/TModPathContainer.h (.../TModPathContainer.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -24,6 +24,7 @@ #include "TModificationTracker.h" #include "TPath.h" #include "ISerializerContainer.h" +#include "TRemovedObjects.h" BEGIN_CHCORE_NAMESPACE @@ -70,14 +71,14 @@ #pragma endregion #pragma region Serialization - void Store(const ISerializerContainerPtr& spContainer); + void Store(const ISerializerContainerPtr& spContainer) const; void Load(const ISerializerContainerPtr& spContainer); #pragma endregion private: #pragma warning(push) #pragma warning(disable: 4251) - std::set m_setRemovedItems; + mutable TRemovedObjects m_setRemovedItems; typedef boost::container::flat_map > DataMap; DataMap m_vPaths; #pragma warning(pop) Index: src/libchcore/TModificationTracker.h =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TModificationTracker.h (.../TModificationTracker.h) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/TModificationTracker.h (.../TModificationTracker.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -57,8 +57,11 @@ template TModificationTracker& operator=(const V& rValue) { - m_tValue = rValue; - m_chModified |= eMod_Modified; + if(m_tValue != rValue) + { + m_tValue = rValue; + m_chModified |= eMod_Modified; + } return *this; } @@ -68,25 +71,20 @@ return m_tValue; } - T& Value() + T& Modify() { m_chModified |= eMod_Modified; return m_tValue; } - const T* operator->() const + void ClearModifications() const { - return &m_tValue; - } - - void ClearModifications() - { m_chModified = eMod_None; } bool IsModified() const { - return (m_chModified & eMod_Modified) != 0; + return m_chModified != 0; } bool IsAdded() const @@ -103,7 +101,7 @@ }; T m_tValue; - char m_chModified; + mutable char m_chModified; }; END_CHCORE_NAMESPACE Index: src/libchcore/TPath.cpp =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TPath.cpp (.../TPath.cpp) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/TPath.cpp (.../TPath.cpp) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -257,6 +257,12 @@ return Compare(rPath) == 0; } + +bool TSmartPath::operator!=(const TSmartPath& rPath) const +{ + return Compare(rPath) != 0; +} + // ============================================================================ /// TSmartPath::operator< /// @date 2009/11/29 Index: src/libchcore/TPath.h =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TPath.h (.../TPath.h) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/TPath.h (.../TPath.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -72,6 +72,7 @@ TSmartPath& operator=(const TSmartPath& spPath); bool operator==(const TSmartPath& rPath) const; + bool operator!=(const TSmartPath& rPath) const; bool operator<(const TSmartPath& rPath) const; bool operator>(const TSmartPath& rPath) const; Index: src/libchcore/TRemovedObjects.cpp =================================================================== diff -u -N --- src/libchcore/TRemovedObjects.cpp (revision 0) +++ src/libchcore/TRemovedObjects.cpp (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -0,0 +1,65 @@ +// ============================================================================ +// 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 "TRemovedObjects.h" +#include "TCoreException.h" +#include "ErrorCodes.h" + +BEGIN_CHCORE_NAMESPACE + +TRemovedObjects::TRemovedObjects() +{ +} + +TRemovedObjects::~TRemovedObjects() +{ + +} + +void TRemovedObjects::Add(size_t stObjectID) +{ + m_setObjects.insert(stObjectID); +} + +size_t TRemovedObjects::GetCount() const +{ + return m_setObjects.size(); +} + +size_t TRemovedObjects::GetAt(size_t stIndex) const +{ + if(stIndex >= m_setObjects.size()) + THROW_CORE_EXCEPTION(eErr_InvalidArgument); + + std::set::const_iterator iter = m_setObjects.begin(); + std::advance(iter, stIndex); + return *iter; +} + +void TRemovedObjects::Clear() +{ + m_setObjects.clear(); +} + +bool TRemovedObjects::IsEmpty() const +{ + return m_setObjects.empty(); +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TRemovedObjects.h =================================================================== diff -u -N --- src/libchcore/TRemovedObjects.h (revision 0) +++ src/libchcore/TRemovedObjects.h (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -0,0 +1,48 @@ +// ============================================================================ +// 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 __TREMOVEDOBJECTS_H__ +#define __TREMOVEDOBJECTS_H__ + +#include "libchcore.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TRemovedObjects +{ +public: + TRemovedObjects(); + ~TRemovedObjects(); + + void Add(size_t stObjectID); + size_t GetCount() const; + size_t GetAt(size_t stIndex) const; + void Clear(); + + bool IsEmpty() const; + +private: +#pragma warning(push) +#pragma warning(disable: 4251) + std::set m_setObjects; +#pragma warning(pop) +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TSQLiteSerializerContainer.cpp =================================================================== diff -u -N -r11053b920c95ec8d138323e32465f59c8dd5ccea -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TSQLiteSerializerContainer.cpp (.../TSQLiteSerializerContainer.cpp) (revision 11053b920c95ec8d138323e32465f59c8dd5ccea) +++ src/libchcore/TSQLiteSerializerContainer.cpp (.../TSQLiteSerializerContainer.cpp) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -25,6 +25,7 @@ #include "TSQLiteStatement.h" #include "TSQLiteSerializerRowReader.h" #include +#include "TRemovedObjects.h" BEGIN_CHCORE_NAMESPACE @@ -75,6 +76,15 @@ m_setDeleteItems.insert(stRowID); } +void TSQLiteSerializerContainer::DeleteRows(const TRemovedObjects& setObjects) +{ + size_t stCount = setObjects.GetCount(); + while(stCount-- != 0) + { + DeleteRow(setObjects.GetAt(stCount)); + } +} + ISerializerRowReaderPtr TSQLiteSerializerContainer::GetRowReader() { TSQLiteSerializerRowReaderPtr spRowReader(new TSQLiteSerializerRowReader(m_spDB, m_spColumns, m_strName)); Index: src/libchcore/TSQLiteSerializerContainer.h =================================================================== diff -u -N -r31c4b1fc46687ed2cf35dd9fa0acec2543ae1886 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TSQLiteSerializerContainer.h (.../TSQLiteSerializerContainer.h) (revision 31c4b1fc46687ed2cf35dd9fa0acec2543ae1886) +++ src/libchcore/TSQLiteSerializerContainer.h (.../TSQLiteSerializerContainer.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -43,6 +43,7 @@ virtual ISerializerRowDataPtr AddRow(size_t stRowID); virtual ISerializerRowDataPtr GetRow(size_t stRowID); virtual void DeleteRow(size_t stRowID); + virtual void DeleteRows(const TRemovedObjects& setObjects); virtual ISerializerRowReaderPtr GetRowReader(); Index: src/libchcore/TSQLiteTaskSchema.cpp =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -49,6 +49,9 @@ tStatement.Prepare(_T("CREATE TABLE base_paths(id BIGINT UNIQUE, path varchar(32768) NOT NULL)")); tStatement.Step(); + tStatement.Prepare(_T("CREATE TABLE base_paths_data(id BIGINT UNIQUE REFERENCES base_paths(id), skip_processing boolean NOT NULL, dst_path varchar(32768) NOT NULL)")); + tStatement.Step(); + // and finally set the database version to current one tVersion.SetVersion(1); } Index: src/libchcore/TSharedModificationTracker.h =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TSharedModificationTracker.h (.../TSharedModificationTracker.h) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/TSharedModificationTracker.h (.../TSharedModificationTracker.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -23,35 +23,35 @@ BEGIN_CHCORE_NAMESPACE -template +template class TSharedModificationTracker { public: - TSharedModificationTracker(bool& rbSharedFlag) : + TSharedModificationTracker(Bitset& rBitset) : m_tValue(), - m_rbModified(rbSharedFlag) + m_rBitset(rBitset) { } - TSharedModificationTracker(const TSharedModificationTracker& rSrc) : + TSharedModificationTracker(const TSharedModificationTracker& rSrc) : m_tValue(rSrc.m_tValue), - m_rbModified(rSrc.m_rbModified) + m_rBitset(rSrc.m_rBitset) { } template - TSharedModificationTracker(const V& rValue, bool& rbSharedFlag) : + TSharedModificationTracker(Bitset& rBitset, const V& rValue) : m_tValue(rValue), - m_rbModified(rbSharedFlag) + m_rBitset(rBitset) { } - TSharedModificationTracker& operator=(const TSharedModificationTracker& rValue) + TSharedModificationTracker& operator=(const TSharedModificationTracker& rValue) { if(this != &rValue) { - m_rbModified = rValue.m_rbModified; m_tValue = rValue.m_tValue; + m_rBitset = rValue.m_rBitset; } return *this; @@ -60,8 +60,11 @@ template TSharedModificationTracker& operator=(const V& rValue) { - m_tValue = rValue; - m_rbModified = true; + if(m_tValue != rValue) + { + m_tValue = rValue; + m_rBitset[ChangeBit] = true; + } return *this; } @@ -71,25 +74,25 @@ return m_tValue; } - T& Value() + const T& Get() const { - m_rbModified = true; return m_tValue; } - const T* operator->() const + T& Modify() { - return &m_tValue; + m_rBitset[ChangeBit] = true; + return m_tValue; } bool IsModified() const { - return m_rbModified; + return m_rBitset[ChangeBit]; } private: T m_tValue; - bool& m_rbModified; + Bitset& m_rBitset; }; END_CHCORE_NAMESPACE Index: src/libchcore/TTask.cpp =================================================================== diff -u -N -r2efd22688b8d12be34c87bf2b024d8db6e317d60 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision 2efd22688b8d12be34c87bf2b024d8db6e317d60) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -43,10 +43,6 @@ // TTask members TTask::TTask(const ISerializerPtr& spSerializer, const IFeedbackHandlerPtr& spFeedbackHandler) : - m_strTaskName(m_bBaseDataChanged), - m_eCurrentState(eTaskState_None, m_bBaseDataChanged), - m_pathLog(m_bBaseDataChanged), - m_pathDestinationPath(m_bBaseDataChanged), m_log(), m_spFeedbackHandler(spFeedbackHandler), m_arrSourcePathsInfo(), @@ -55,8 +51,7 @@ m_bContinue(false), m_tSubTaskContext(m_tConfiguration, m_vSourcePaths, m_arrSourcePathsInfo, m_files, m_cfgTracker, m_log, spFeedbackHandler, m_workerThread, m_fsLocal), m_tSubTasksArray(), - m_spSerializer(spSerializer), - m_bWasSerialized(false) + m_spSerializer(spSerializer) { if(!spFeedbackHandler || !spSerializer) THROW_CORE_EXCEPTION(eErr_InvalidPointer); @@ -69,15 +64,15 @@ void TTask::SetTaskDefinition(const TTaskDefinition& rTaskDefinition) { - m_pathDestinationPath = rTaskDefinition.GetDestinationPath(); + m_tBaseData.SetDestinationPath(rTaskDefinition.GetDestinationPath()); m_tConfiguration = rTaskDefinition.GetConfiguration(); m_vSourcePaths = rTaskDefinition.GetSourcePaths(); - m_strTaskName = rTaskDefinition.GetTaskName(); + m_tBaseData.SetTaskName(rTaskDefinition.GetTaskName()); m_tSubTasksArray.Init(rTaskDefinition.GetOperationPlan(), m_tSubTaskContext); m_files.Clear(); m_tSubTaskContext.SetOperationType(m_tSubTasksArray.GetOperationType()); - m_tSubTaskContext.SetDestinationPath(m_pathDestinationPath); + m_tSubTaskContext.SetDestinationPath(m_tBaseData.GetDestinationPath()); } void TTask::OnRegisterTask() @@ -92,13 +87,13 @@ { // NOTE: we could check some transition rules here boost::unique_lock lock(m_lock); - m_eCurrentState = eTaskState; + m_tBaseData.SetCurrentState(eTaskState); } ETaskCurrentState TTask::GetTaskState() const { boost::shared_lock lock(m_lock); - return m_eCurrentState; + return m_tBaseData.GetCurrentState(); } void TTask::SetBufferSizes(const TBufferSizes& bsSizes) @@ -137,29 +132,14 @@ boost::unique_lock lock(m_lock); ISerializerContainerPtr spContainer = m_spSerializer->GetContainer(_T("task")); - ISerializerRowReaderPtr spRowReader = spContainer->GetRowReader(); + m_tBaseData.Load(spContainer); - IColumnsDefinitionPtr spColumns = spRowReader->GetColumnsDefinitions(); - if(spColumns->IsEmpty()) - *spColumns % _T("name") % _T("log_path") % _T("current_state") % _T("destination_path"); - - bool bResult = spRowReader->Next(); - if(bResult) - { - spRowReader->GetValue(_T("name"), m_strTaskName.Value()); - spRowReader->GetValue(_T("log_path"), m_pathLog.Value()); - spRowReader->GetValue(_T("current_state"), *(int*)(ETaskCurrentState*)&m_eCurrentState.Value()); - spRowReader->GetValue(_T("destination_path"), m_pathDestinationPath.Value()); - } - else - THROW_CORE_EXCEPTION(eErr_SerializeLoadError); - spContainer = m_spSerializer->GetContainer(_T("base_paths")); m_vSourcePaths.Load(spContainer); - } - m_bBaseDataChanged = false; - m_bWasSerialized = true; + spContainer = m_spSerializer->GetContainer(_T("base_paths_data")); + m_arrSourcePathsInfo.Load(spContainer); + } } void TTask::Store() @@ -170,29 +150,14 @@ boost::shared_lock lock(m_lock); ISerializerContainerPtr spContainer = m_spSerializer->GetContainer(_T("task")); - ISerializerRowDataPtr spRow; + m_tBaseData.Store(spContainer); - // base data - if(!m_bWasSerialized || m_bBaseDataChanged) - { - if(m_bWasSerialized) - spRow = spContainer->GetRow(0); - else - spRow = spContainer->AddRow(0); - - *spRow - % TRowData(_T("name"), m_strTaskName) - % TRowData(_T("log_path"), m_pathLog) - % TRowData(_T("current_state"), m_eCurrentState) - % TRowData(_T("destination_path"), m_pathDestinationPath); - - m_bBaseDataChanged = false; - m_bWasSerialized = true; - } - // base paths spContainer = m_spSerializer->GetContainer(_T("base_paths")); m_vSourcePaths.Store(spContainer); + + spContainer = m_spSerializer->GetContainer(_T("base_paths_data")); + m_arrSourcePathsInfo.Store(spContainer); } m_spSerializer->Flush(); @@ -273,11 +238,11 @@ m_tLocalStats.GetSnapshot(spSnapshot); - spSnapshot->SetTaskName(m_strTaskName); + spSnapshot->SetTaskName(m_tBaseData.GetTaskName()); spSnapshot->SetThreadPriority(GetTaskPropValue(m_tConfiguration)); - spSnapshot->SetDestinationPath(m_pathDestinationPath->ToString()); + spSnapshot->SetDestinationPath(m_tBaseData.GetDestinationPath().ToString()); spSnapshot->SetFilters(m_afFilters); - spSnapshot->SetTaskState(m_eCurrentState); + spSnapshot->SetTaskState(m_tBaseData.GetCurrentState()); spSnapshot->SetOperationType(m_tSubTasksArray.GetOperationType()); spSnapshot->SetIgnoreDirectories(GetTaskPropValue(m_tConfiguration)); @@ -422,7 +387,7 @@ TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; // initialize log file - m_log.init(m_pathLog->ToString(), 262144, icpf::log_file::level_debug, false, false); + m_log.init(m_tBaseData.GetLogPath().ToString(), 262144, icpf::log_file::level_debug, false, false); // start operation OnBeginOperation(); @@ -586,12 +551,12 @@ chcore::TSmartPath TTask::GetLogPath() const { - return m_pathLog; + return m_tBaseData.GetLogPath(); } void TTask::SetLogPath(const TSmartPath& pathLog) { - m_pathLog = pathLog; + m_tBaseData.SetLogPath(pathLog); } chcore::ISerializerPtr TTask::GetSerializer() const Index: src/libchcore/TTask.h =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TTask.h (.../TTask.h) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/TTask.h (.../TTask.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -35,7 +35,7 @@ #include "TTaskStatsSnapshot.h" #include "ISerializer.h" #include "TModPathContainer.h" -#include "TSharedModificationTracker.h" +#include "TTaskBaseData.h" BEGIN_CHCORE_NAMESPACE @@ -135,21 +135,9 @@ IFeedbackHandlerPtr m_spFeedbackHandler; #pragma warning(pop) - bool m_bWasSerialized; - // base data -#pragma region Base data - bool m_bBaseDataChanged; + TTaskBaseData m_tBaseData; -#pragma warning(push) -#pragma warning(disable: 4251) - TSharedModificationTracker m_strTaskName; - TSharedModificationTracker m_eCurrentState; // current state of processing this task represents - TSharedModificationTracker m_pathLog; - TSharedModificationTracker m_pathDestinationPath; -#pragma warning(pop) -#pragma endregion - // basic information TModPathContainer m_vSourcePaths; TBasePathDataContainer m_arrSourcePathsInfo; Index: src/libchcore/TTaskBaseData.cpp =================================================================== diff -u -N --- src/libchcore/TTaskBaseData.cpp (revision 0) +++ src/libchcore/TTaskBaseData.cpp (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -0,0 +1,133 @@ +// ============================================================================ +// 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 "TTaskBaseData.h" +#include "ISerializerRowData.h" +#include "ISerializerContainer.h" +#include "TCoreException.h" +#include "ErrorCodes.h" + +BEGIN_CHCORE_NAMESPACE + +TTaskBaseData::TTaskBaseData() : + m_strTaskName(m_setChanges), + m_eCurrentState(m_setChanges), + m_pathLog(m_setChanges), + m_pathDestinationPath(m_setChanges) +{ + m_setChanges[eMod_Added] = true; +} + +TTaskBaseData::~TTaskBaseData() +{ +} + +chcore::TString TTaskBaseData::GetTaskName() const +{ + return m_strTaskName; +} + +void TTaskBaseData::SetTaskName(const TString& strTaskName) +{ + m_strTaskName = strTaskName; +} + +chcore::ETaskCurrentState TTaskBaseData::GetCurrentState() const +{ + return m_eCurrentState; +} + +void TTaskBaseData::SetCurrentState(ETaskCurrentState eCurrentState) +{ + m_eCurrentState = eCurrentState; +} + +chcore::TSmartPath TTaskBaseData::GetLogPath() const +{ + return m_pathLog; +} + +void TTaskBaseData::SetLogPath(const TSmartPath& pathLog) +{ + m_pathLog = pathLog; +} + +chcore::TSmartPath TTaskBaseData::GetDestinationPath() const +{ + return m_pathDestinationPath; +} + +void TTaskBaseData::SetDestinationPath(const TSmartPath& pathDst) +{ + m_pathDestinationPath = pathDst; +} + +void TTaskBaseData::Store(const ISerializerContainerPtr& spContainer) const +{ + ISerializerRowDataPtr spRow; + + // base data + if(m_setChanges.any()) + { + bool bAdded = m_setChanges[eMod_Added]; + + if(bAdded) + spRow = spContainer->AddRow(0); + else + spRow = spContainer->GetRow(0); + + if(bAdded || m_setChanges[eMod_TaskName]) + *spRow % TRowData(_T("name"), m_strTaskName); + + if(bAdded || m_setChanges[eMod_LogPath]) + *spRow % TRowData(_T("log_path"), m_pathLog); + + if(bAdded || m_setChanges[eMod_CurrentState]) + *spRow % TRowData(_T("current_state"), m_eCurrentState); + + if(bAdded || m_setChanges[eMod_DstPath]) + *spRow % TRowData(_T("destination_path"), m_pathDestinationPath); + + m_setChanges.reset(); + } +} + +void TTaskBaseData::Load(const ISerializerContainerPtr& spContainer) +{ + ISerializerRowReaderPtr spRowReader = spContainer->GetRowReader(); + + IColumnsDefinitionPtr spColumns = spRowReader->GetColumnsDefinitions(); + if(spColumns->IsEmpty()) + *spColumns % _T("name") % _T("log_path") % _T("current_state") % _T("destination_path"); + + bool bResult = spRowReader->Next(); + if(bResult) + { + spRowReader->GetValue(_T("name"), m_strTaskName.Modify()); + spRowReader->GetValue(_T("log_path"), m_pathLog.Modify()); + spRowReader->GetValue(_T("current_state"), *(int*)(ETaskCurrentState*)&m_eCurrentState.Modify()); + spRowReader->GetValue(_T("destination_path"), m_pathDestinationPath.Modify()); + } + else + THROW_CORE_EXCEPTION(eErr_SerializeLoadError); + + m_setChanges.reset(); +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TTaskBaseData.h =================================================================== diff -u -N --- src/libchcore/TTaskBaseData.h (revision 0) +++ src/libchcore/TTaskBaseData.h (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -0,0 +1,81 @@ +// ============================================================================ +// 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 __TTASKBASEDATA_H__ +#define __TTASKBASEDATA_H__ + +#include "libchcore.h" +#include "ISerializerRowData.h" +#include +#include "TSharedModificationTracker.h" +#include "ETaskCurrentState.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TTaskBaseData +{ +private: + TTaskBaseData(const TTaskBaseData&); + TTaskBaseData& operator=(const TTaskBaseData&); + +public: + TTaskBaseData(); + ~TTaskBaseData(); + + TString GetTaskName() const; + void SetTaskName(const TString& strTaskName); + + ETaskCurrentState GetCurrentState() const; + void SetCurrentState(ETaskCurrentState eCurrentState); + + TSmartPath GetLogPath() const; + void SetLogPath(const TSmartPath& pathLog); + + TSmartPath GetDestinationPath() const; + void SetDestinationPath(const TSmartPath& pathDst); + + void Store(const ISerializerContainerPtr& spContainer) const; + void Load(const ISerializerContainerPtr& spContainer); + +private: + enum EModifications + { + eMod_Added, + eMod_TaskName, + eMod_CurrentState, + eMod_LogPath, + eMod_DstPath, + + eMod_Last + }; + +#pragma warning(push) +#pragma warning(disable: 4251) + typedef std::bitset ModBitSet; + mutable ModBitSet m_setChanges; + + TSharedModificationTracker m_strTaskName; + TSharedModificationTracker m_eCurrentState; // current state of processing this task represents + TSharedModificationTracker m_pathLog; + TSharedModificationTracker m_pathDestinationPath; +#pragma warning(pop) +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TTaskInfo.cpp =================================================================== diff -u -N -r31c4b1fc46687ed2cf35dd9fa0acec2543ae1886 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TTaskInfo.cpp (.../TTaskInfo.cpp) (revision 31c4b1fc46687ed2cf35dd9fa0acec2543ae1886) +++ src/libchcore/TTaskInfo.cpp (.../TTaskInfo.cpp) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -26,17 +26,20 @@ BEGIN_CHCORE_NAMESPACE TTaskInfoEntry::TTaskInfoEntry() : - TIntrusiveSerializableItem(), - m_iOrder(0) + m_iOrder(m_setModifications, 0), + m_pathSerializeLocation(m_setModifications), + m_stObjectID(0) { + m_setModifications[eMod_Added] = true; } -TTaskInfoEntry::TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask, int iModification) : - TIntrusiveSerializableItem(tTaskID, iModification), - m_pathSerializeLocation(pathTask), - m_iOrder(iOrder), +TTaskInfoEntry::TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask) : + m_stObjectID(tTaskID), + m_pathSerializeLocation(m_setModifications, pathTask), + m_iOrder(m_setModifications, iOrder), m_spTask(spTask) { + m_setModifications[eMod_Added] = true; } TSmartPath TTaskInfoEntry::GetTaskSerializeLocation() const @@ -46,7 +49,6 @@ void TTaskInfoEntry::SetTaskSerializeLocation(const TSmartPath& strTaskPath) { - SetModification(eMod_TaskPath, eMod_TaskPath); m_pathSerializeLocation = strTaskPath; } @@ -67,59 +69,66 @@ void TTaskInfoEntry::SetOrder(int iOrder) { - SetModification(eMod_Order, eMod_Order); m_iOrder = iOrder; } -void TTaskInfoEntry::Store(const ISerializerContainerPtr& spContainer) +void TTaskInfoEntry::Store(const ISerializerContainerPtr& spContainer) const { - if(!IsModified()) + if(!m_setModifications.any()) return; - if(IsAdded()) - { - ISerializerRowDataPtr spRow = spContainer->AddRow(GetObjectID()); + ISerializerRowDataPtr spRow; - *spRow % TRowData(_T("path"), m_pathSerializeLocation) - % TRowData(_T("task_order"), m_iOrder); - } + bool bAdded = m_setModifications[eMod_Added]; + if(bAdded) + spRow = spContainer->AddRow(m_stObjectID); else - { - ISerializerRowDataPtr spRow = spContainer->GetRow(GetObjectID()); - if(GetModifications() & eMod_TaskPath) - *spRow % TRowData(_T("path"), m_pathSerializeLocation); - else if(GetModifications() & eMod_Order) - *spRow % TRowData(_T("task_order"), m_iOrder); - } + spRow = spContainer->GetRow(m_stObjectID); - ResetModifications(); + if(bAdded || m_setModifications[eMod_TaskPath]) + *spRow % TRowData(_T("path"), m_pathSerializeLocation); + if(bAdded || m_setModifications[eMod_Order]) + *spRow % TRowData(_T("task_order"), m_iOrder); + + m_setModifications.reset(); } -bool TTaskInfoEntry::Load(const ISerializerRowReaderPtr& spRowReader) +void TTaskInfoEntry::Load(const ISerializerRowReaderPtr& spRowReader) { - IColumnsDefinitionPtr spColumns = spRowReader->GetColumnsDefinitions(); - if(spColumns->IsEmpty()) - *spColumns % _T("id") % _T("path") % _T("task_order"); + spRowReader->GetValue(_T("id"), m_stObjectID); + spRowReader->GetValue(_T("path"), m_pathSerializeLocation.Modify()); + spRowReader->GetValue(_T("task_order"), m_iOrder.Modify()); - bool bResult = spRowReader->Next(); - if(bResult) - { - spRowReader->GetValue(_T("id"), m_stObjectID); - spRowReader->GetValue(_T("path"), m_pathSerializeLocation); - spRowReader->GetValue(_T("task_order"), m_iOrder); - } + m_setModifications.reset(); +} - return bResult; +void TTaskInfoEntry::InitLoader(const IColumnsDefinitionPtr& spColumnDefs) +{ + if(!spColumnDefs) + THROW_CORE_EXCEPTION(eErr_InvalidPointer); + + *spColumnDefs % _T("id") % _T("path") % _T("task_order"); } +size_t TTaskInfoEntry::GetObjectID() const +{ + return m_stObjectID; +} + +void TTaskInfoEntry::ResetModifications() +{ + m_setModifications.reset(); +} + /////////////////////////////////////////////////////////////////////////// -TTaskInfoContainer::TTaskInfoContainer() +TTaskInfoContainer::TTaskInfoContainer() : + m_stLastObjectID(0) { } -void TTaskInfoContainer::Add(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask) +void TTaskInfoContainer::Add(const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask) { - m_vTaskInfos.push_back(TTaskInfoEntry(tTaskID, pathTask, iOrder, spTask, TTaskInfoEntry::eMod_Added)); + m_vTaskInfos.push_back(TTaskInfoEntry(++m_stLastObjectID, pathTask, iOrder, spTask)); } void TTaskInfoContainer::RemoveAt(size_t stIndex) @@ -130,14 +139,14 @@ std::vector::iterator iter = m_vTaskInfos.begin() + stIndex; taskid_t tTaskID = (*iter).GetObjectID(); m_vTaskInfos.erase(m_vTaskInfos.begin() + stIndex); - m_setRemovedTasks.insert(tTaskID); + m_setRemovedTasks.Add(tTaskID); } void TTaskInfoContainer::Clear() { BOOST_FOREACH(TTaskInfoEntry& rEntry, m_vTaskInfos) { - m_setRemovedTasks.insert(rEntry.GetObjectID()); + m_setRemovedTasks.Add(rEntry.GetObjectID()); } m_vTaskInfos.clear(); } @@ -182,53 +191,9 @@ return m_vTaskInfos.empty(); } -bool TTaskInfoContainer::HasDeletions() const -{ - return !m_setRemovedTasks.empty(); -} - -bool TTaskInfoContainer::HasAdditions() const -{ - BOOST_FOREACH(const TTaskInfoEntry& rEntry, m_vTaskInfos) - { - if(rEntry.IsAdded()) - return true; - } - - return false; -} - -bool TTaskInfoContainer::HasModifications() const -{ - BOOST_FOREACH(const TTaskInfoEntry& rEntry, m_vTaskInfos) - { - // if marked as added, we don't consider it modified anymore - if(rEntry.IsModified()) - return true; - } - - return false; -} - -size_t TTaskInfoContainer::GetDeletedCount() const -{ - return m_setRemovedTasks.size(); -} - -chcore::taskid_t TTaskInfoContainer::GetDeletedAt(size_t stIndex) const -{ - if(stIndex >= m_setRemovedTasks.size()) - THROW_CORE_EXCEPTION(eErr_BoundsExceeded); - - std::set::const_iterator iter = m_setRemovedTasks.begin(); - std::advance(iter, stIndex); - - return *iter; -} - void TTaskInfoContainer::ClearModifications() { - m_setRemovedTasks.clear(); + m_setRemovedTasks.Clear(); BOOST_FOREACH(TTaskInfoEntry& rEntry, m_vTaskInfos) { @@ -237,46 +202,43 @@ } } -void TTaskInfoContainer::Store(const ISerializerContainerPtr& spContainer) +void TTaskInfoContainer::Store(const ISerializerContainerPtr& spContainer) const { - BOOST_FOREACH(taskid_t stObjectID, m_setRemovedTasks) - { - spContainer->DeleteRow(stObjectID); - } + spContainer->DeleteRows(m_setRemovedTasks); + m_setRemovedTasks.Clear(); - BOOST_FOREACH(TTaskInfoEntry& rEntry, m_vTaskInfos) + BOOST_FOREACH(const TTaskInfoEntry& rEntry, m_vTaskInfos) { - if(rEntry.GetModifications() != TTaskInfoEntry::eMod_None) - rEntry.Store(spContainer); + rEntry.Store(spContainer); } - - ClearModifications(); } void TTaskInfoContainer::Load(const ISerializerContainerPtr& spContainer) { ISerializerRowReaderPtr spRowReader = spContainer->GetRowReader(); + IColumnsDefinitionPtr spColumns = spRowReader->GetColumnsDefinitions(); + if(spColumns->IsEmpty()) + TTaskInfoEntry::InitLoader(spColumns); TTaskInfoEntry tEntry; - while(tEntry.Load(spRowReader)) + while(spRowReader->Next()) { + tEntry.Load(spRowReader); + m_vTaskInfos.push_back(tEntry); + m_stLastObjectID = std::max(m_stLastObjectID, tEntry.GetObjectID()); } } -taskid_t TTaskInfoContainer::GetLastTaskID() const +TTaskInfoEntry& TTaskInfoContainer::GetAtOid(size_t stObjectID) { - taskid_t tLastTaskID = NoTaskID; - - BOOST_FOREACH(const TTaskInfoEntry& rEntry, m_vTaskInfos) + for(std::vector::iterator iter = m_vTaskInfos.begin(); iter != m_vTaskInfos.end(); ++iter) { - tLastTaskID = std::max(rEntry.GetObjectID(), tLastTaskID); + if((*iter).GetObjectID() == stObjectID) + return *iter; } - if(!m_setRemovedTasks.empty()) - tLastTaskID = std::max(*m_setRemovedTasks.rbegin(), tLastTaskID); - - return tLastTaskID; + THROW_CORE_EXCEPTION(eErr_InvalidArgument); } END_CHCORE_NAMESPACE Index: src/libchcore/TTaskInfo.h =================================================================== diff -u -N -r0c5027d5173ab0daeba6aa6b735a2b11d4cd2164 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TTaskInfo.h (.../TTaskInfo.h) (revision 0c5027d5173ab0daeba6aa6b735a2b11d4cd2164) +++ src/libchcore/TTaskInfo.h (.../TTaskInfo.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -25,26 +25,34 @@ #include "TPath.h" #include "TaskID.h" #include "ISerializerContainer.h" -#include "TIntrusiveSerializableItem.h" +#include "TRemovedObjects.h" +#include +#include "TSharedModificationTracker.h" BEGIN_CHCORE_NAMESPACE class TTask; typedef boost::shared_ptr TTaskPtr; -class LIBCHCORE_API TTaskInfoEntry : public TIntrusiveSerializableItem +class LIBCHCORE_API TTaskInfoEntry { public: - enum ETIEntryInfo + enum EModifications { - eMod_TaskPath = TIntrusiveSerializableItem::eMod_Modified, - eMod_Order = TIntrusiveSerializableItem::eMod_Modified << 1, + eMod_None = 0, + eMod_Added, + eMod_TaskPath, + eMod_Order, + + eMod_Last }; public: TTaskInfoEntry(); - TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask, int iModification = eMod_None); + TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask); + size_t GetObjectID() const; + TSmartPath GetTaskSerializeLocation() const; void SetTaskSerializeLocation(const TSmartPath& pathTask); @@ -54,30 +62,37 @@ int GetOrder() const; void SetOrder(int iOrder); - void Store(const ISerializerContainerPtr& spContainer); - bool Load(const ISerializerRowReaderPtr& spRowReader); + void Store(const ISerializerContainerPtr& spContainer) const; + static void InitLoader(const IColumnsDefinitionPtr& spColumnDefs); + void Load(const ISerializerRowReaderPtr& spRowReader); + void ResetModifications(); + private: - TSmartPath m_pathSerializeLocation; #pragma warning(push) #pragma warning(disable:4251) + size_t m_stObjectID; + typedef std::bitset Bitset; + mutable std::bitset m_setModifications; + TSharedModificationTracker m_pathSerializeLocation; + TSharedModificationTracker m_iOrder; + TTaskPtr m_spTask; #pragma warning(pop) - int m_iOrder; }; class LIBCHCORE_API TTaskInfoContainer { public: TTaskInfoContainer(); - void Add(taskid_t tTaskID, const TSmartPath& strPath, int iOrder, const TTaskPtr& spTask); + void Add(const TSmartPath& strPath, int iOrder, const TTaskPtr& spTask); void RemoveAt(size_t stIndex); TTaskInfoEntry& GetAt(size_t stIndex); const TTaskInfoEntry& GetAt(size_t stIndex) const; - taskid_t GetLastTaskID() const; + TTaskInfoEntry& GetAtOid(size_t stObjectID); bool GetByTaskID(taskid_t tTaskID, TTaskInfoEntry& rInfo) const; @@ -86,25 +101,19 @@ void Clear(); - size_t GetDeletedCount() const; - taskid_t GetDeletedAt(size_t stIndex) const; - // modifications management - void Store(const ISerializerContainerPtr& spContainer); + void Store(const ISerializerContainerPtr& spContainer) const; void Load(const ISerializerContainerPtr& spContainer); void ClearModifications(); - bool HasDeletions() const; - bool HasAdditions() const; - bool HasModifications() const; - private: #pragma warning(push) #pragma warning(disable:4251) std::vector m_vTaskInfos; - std::set m_setRemovedTasks; + mutable TRemovedObjects m_setRemovedTasks; #pragma warning(pop) + size_t m_stLastObjectID; }; END_CHCORE_NAMESPACE Index: src/libchcore/TTaskManager.cpp =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -33,7 +33,6 @@ TTaskManager::TTaskManager(const ISerializerFactoryPtr& spSerializerFactory, const IFeedbackHandlerFactoryPtr& spFeedbackHandlerFactory, bool bForceRecreateSerializer) : - m_stNextTaskID(NoTaskID + 1), m_spSerializerFactory(spSerializerFactory), m_spFeedbackFactory(spFeedbackHandlerFactory) { @@ -114,7 +113,7 @@ iOrder = rEntry.GetOrder() + 1; } - m_tTasks.Add(m_stNextTaskID++, spNewTask->GetSerializer()->GetLocation(), iOrder, spNewTask); + m_tTasks.Add(spNewTask->GetSerializer()->GetLocation(), iOrder, spNewTask); spNewTask->OnRegisterTask(); } @@ -449,36 +448,45 @@ void TTaskManager::Load() { - boost::unique_lock lock(m_lock); + // load list of tasks (without loading tasks themselves) + { + boost::unique_lock lock(m_lock); - if(!m_tTasks.IsEmpty()) - THROW_CORE_EXCEPTION(eErr_InternalProblem); + if(!m_tTasks.IsEmpty()) + THROW_CORE_EXCEPTION(eErr_InternalProblem); - ISerializerContainerPtr spContainer = m_spSerializer->GetContainer(_T("tasks")); - m_tTasks.Load(spContainer); + 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; + // retrieve information about tasks to load + std::vector > vObjects; + { + boost::shared_lock lock(m_lock); - // clear all modifications of freshly loaded tasks (in case serializer does - // not reset the modification state) - m_tTasks.ClearModifications(); + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) + { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + if(!rEntry.GetTask()) + vObjects.push_back(std::make_pair(rEntry.GetObjectID(), rEntry.GetTaskSerializeLocation())); + } + } - for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) + typedef std::pair PairInfo; + BOOST_FOREACH(const PairInfo& rInfo, vObjects) { - TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + IFeedbackHandlerPtr spHandler = m_spFeedbackFactory->Create(); + ISerializerPtr spSerializer(m_spSerializerFactory->CreateSerializer(ISerializerFactory::eObj_Task, rInfo.second.ToWString())); - if(!rEntry.GetTask()) - { - IFeedbackHandlerPtr spHandler = m_spFeedbackFactory->Create(); - ISerializerPtr spSerializer(m_spSerializerFactory->CreateSerializer(ISerializerFactory::eObj_Task, rEntry.GetTaskSerializeLocation().ToWString())); + TTaskPtr spTask(new TTask(spSerializer, spHandler)); + spTask->Load(); - TTaskPtr spTask(new TTask(spSerializer, spHandler)); - spTask->Load(); + boost::unique_lock lock(m_lock); - rEntry.SetTask(spTask); - } + TTaskInfoEntry& rInfoEntry = m_tTasks.GetAtOid(rInfo.first); + rInfoEntry.SetTask(spTask); } + } TSmartPath TTaskManager::CreateTaskLogPath(const TString& strTaskUuid) const Index: src/libchcore/TTaskManager.h =================================================================== diff -u -N -r458af7bf8c35950fdeb4b906950437596324aea1 -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/TTaskManager.h (.../TTaskManager.h) (revision 458af7bf8c35950fdeb4b906950437596324aea1) +++ src/libchcore/TTaskManager.h (.../TTaskManager.h) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -91,7 +91,6 @@ TTaskInfoContainer m_tTasks; // serializable TSmartPath m_pathLogDir; // config-based, not serializable - taskid_t m_stNextTaskID; // serializable #pragma warning(push) #pragma warning(disable: 4251) Index: src/libchcore/libchcore.vc90.vcproj =================================================================== diff -u -N -r73583f2ca01fa1b2eae49bbc63bce46b9ecff5db -r293e52b38d46653068006262172018a0f0d0a31c --- src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision 73583f2ca01fa1b2eae49bbc63bce46b9ecff5db) +++ src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision 293e52b38d46653068006262172018a0f0d0a31c) @@ -936,6 +936,14 @@ > + + + + @@ -1108,10 +1116,6 @@ > - - @@ -1144,10 +1148,6 @@ > - - @@ -1263,6 +1263,18 @@ > + + + + + +