Index: src/libchcore/TSQLiteSerializerContainer.cpp =================================================================== diff -u -N -rd76d3ce6c8c55fa23009dbb03b8bc06f482c5b72 -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 --- src/libchcore/TSQLiteSerializerContainer.cpp (.../TSQLiteSerializerContainer.cpp) (revision d76d3ce6c8c55fa23009dbb03b8bc06f482c5b72) +++ src/libchcore/TSQLiteSerializerContainer.cpp (.../TSQLiteSerializerContainer.cpp) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) @@ -29,169 +29,168 @@ #include #include "TSerializerException.h" -BEGIN_CHCORE_NAMESPACE - -using namespace sqlite; - -TSQLiteSerializerContainer::TSQLiteSerializerContainer(const TString& strName, const sqlite::TSQLiteDatabasePtr& spDB, TPlainStringPool& poolStrings) : - m_strName(strName), - m_spDB(spDB), - m_pPoolRows(NULL), - m_poolStrings(poolStrings) +namespace chcore { -} + using namespace sqlite; -TSQLiteSerializerContainer::~TSQLiteSerializerContainer() -{ - // get rid of all rows first - m_mapRows.clear(); + TSQLiteSerializerContainer::TSQLiteSerializerContainer(const TString& strName, const sqlite::TSQLiteDatabasePtr& spDB, TPlainStringPool& poolStrings) : + m_strName(strName), + m_spDB(spDB), + m_pPoolRows(NULL), + m_poolStrings(poolStrings) + { + } - // now get rid of memory pool - delete m_pPoolRows; -} - -ISerializerRowData& TSQLiteSerializerContainer::GetRow(object_id_t oidRowID, bool bMarkAsAdded) -{ - RowMap::iterator iterFnd = m_mapRows.find(oidRowID); - if(iterFnd == m_mapRows.end()) + TSQLiteSerializerContainer::~TSQLiteSerializerContainer() { - void* pMemoryBlock = GetPool().malloc(); - if(!pMemoryBlock) - THROW_SERIALIZER_EXCEPTION(eErr_InternalProblem, _T("Cannot allocate memory")); + // get rid of all rows first + m_mapRows.clear(); - iterFnd = m_mapRows.insert(std::make_pair(oidRowID, TSQLiteSerializerRowData(oidRowID, m_tColumns, bMarkAsAdded, (unsigned long long*)pMemoryBlock, GetPool().get_requested_size(), m_poolStrings))).first; + // now get rid of memory pool + delete m_pPoolRows; } - else if(bMarkAsAdded) - iterFnd->second.MarkAsAdded(); - return (*iterFnd).second; -} + ISerializerRowData& TSQLiteSerializerContainer::GetRow(object_id_t oidRowID, bool bMarkAsAdded) + { + RowMap::iterator iterFnd = m_mapRows.find(oidRowID); + if (iterFnd == m_mapRows.end()) + { + void* pMemoryBlock = GetPool().malloc(); + if (!pMemoryBlock) + THROW_SERIALIZER_EXCEPTION(eErr_InternalProblem, _T("Cannot allocate memory")); -void TSQLiteSerializerContainer::DeleteRow(object_id_t oidRowID) -{ - RowMap::iterator iterFnd = m_mapRows.find(oidRowID); - if(iterFnd != m_mapRows.end()) - m_mapRows.erase(iterFnd); + iterFnd = m_mapRows.insert(std::make_pair(oidRowID, TSQLiteSerializerRowData(oidRowID, m_tColumns, bMarkAsAdded, (unsigned long long*)pMemoryBlock, GetPool().get_requested_size(), m_poolStrings))).first; + } + else if (bMarkAsAdded) + iterFnd->second.MarkAsAdded(); - m_setDeleteItems.insert(oidRowID); -} + return (*iterFnd).second; + } -void TSQLiteSerializerContainer::DeleteRows(const TRemovedObjects& setObjects) -{ - size_t stCount = setObjects.GetCount(); - while(stCount-- != 0) + void TSQLiteSerializerContainer::DeleteRow(object_id_t oidRowID) { - DeleteRow(setObjects.GetAt(stCount)); + RowMap::iterator iterFnd = m_mapRows.find(oidRowID); + if (iterFnd != m_mapRows.end()) + m_mapRows.erase(iterFnd); + + m_setDeleteItems.insert(oidRowID); } -} -ISerializerRowReaderPtr TSQLiteSerializerContainer::GetRowReader() -{ - TSQLiteSerializerRowReaderPtr spRowReader(new TSQLiteSerializerRowReader(m_spDB, m_tColumns, m_strName)); - return spRowReader; -} + void TSQLiteSerializerContainer::DeleteRows(const TRemovedObjects& setObjects) + { + size_t stCount = setObjects.GetCount(); + while (stCount-- != 0) + { + DeleteRow(setObjects.GetAt(stCount)); + } + } -IColumnsDefinition& TSQLiteSerializerContainer::GetColumnsDefinition() -{ - return m_tColumns; -} - -void TSQLiteSerializerContainer::Flush() -{ - FlushDeletions(); - - // group rows that can be executed with one preparation - std::map> mapGroups; - std::map>::iterator iterMapGroups; - - for(RowMap::iterator iterRows = m_mapRows.begin(); iterRows != m_mapRows.end(); ++iterRows) + ISerializerRowReaderPtr TSQLiteSerializerContainer::GetRowReader() { - unsigned long long rowID = iterRows->second.GetChangeIdentification(); - iterMapGroups = mapGroups.find(rowID); - if(iterMapGroups == mapGroups.end()) - iterMapGroups = mapGroups.insert(std::make_pair(rowID, std::vector())).first; + TSQLiteSerializerRowReaderPtr spRowReader(new TSQLiteSerializerRowReader(m_spDB, m_tColumns, m_strName)); + return spRowReader; + } - iterMapGroups->second.push_back(&iterRows->second); + IColumnsDefinition& TSQLiteSerializerContainer::GetColumnsDefinition() + { + return m_tColumns; } - TSQLiteStatement tStatement(m_spDB); - - for(iterMapGroups = mapGroups.begin(); iterMapGroups != mapGroups.end(); ++iterMapGroups) + void TSQLiteSerializerContainer::Flush() { - if(iterMapGroups->first != 0) + FlushDeletions(); + + // group rows that can be executed with one preparation + std::map> mapGroups; + std::map>::iterator iterMapGroups; + + for (RowMap::iterator iterRows = m_mapRows.begin(); iterRows != m_mapRows.end(); ++iterRows) { - std::vector& rGroupRows = iterMapGroups->second; + unsigned long long rowID = iterRows->second.GetChangeIdentification(); + iterMapGroups = mapGroups.find(rowID); + if (iterMapGroups == mapGroups.end()) + iterMapGroups = mapGroups.insert(std::make_pair(rowID, std::vector())).first; - // query is generated from the first item in a group - TString strQuery = rGroupRows.front()->GetQuery(m_strName); - if(!strQuery.IsEmpty()) - { - DBTRACE2(_T("Preparing query for %lu records: %s\n"), (unsigned long)iterMapGroups->second.size(), strQuery.c_str()); + iterMapGroups->second.push_back(&iterRows->second); + } - tStatement.Prepare(strQuery.c_str()); + TSQLiteStatement tStatement(m_spDB); - for(std::vector::iterator iterRow = iterMapGroups->second.begin(); iterRow != iterMapGroups->second.end(); ++iterRow) + for (iterMapGroups = mapGroups.begin(); iterMapGroups != mapGroups.end(); ++iterMapGroups) + { + if (iterMapGroups->first != 0) + { + std::vector& rGroupRows = iterMapGroups->second; + + // query is generated from the first item in a group + TString strQuery = rGroupRows.front()->GetQuery(m_strName); + if (!strQuery.IsEmpty()) { - (*iterRow)->BindParamsAndExec(tStatement); - tStatement.ClearBindings(); - } + DBTRACE2(_T("Preparing query for %lu records: %s\n"), (unsigned long)iterMapGroups->second.size(), strQuery.c_str()); - tStatement.Close(); + tStatement.Prepare(strQuery.c_str()); + + for (std::vector::iterator iterRow = iterMapGroups->second.begin(); iterRow != iterMapGroups->second.end(); ++iterRow) + { + (*iterRow)->BindParamsAndExec(tStatement); + tStatement.ClearBindings(); + } + + tStatement.Close(); + } } } } -} -void TSQLiteSerializerContainer::FlushDeletions() -{ - // delete from m_strName WHERE id IN (???) - TSQLiteStatement tStatement(m_spDB); + void TSQLiteSerializerContainer::FlushDeletions() + { + // delete from m_strName WHERE id IN (???) + TSQLiteStatement tStatement(m_spDB); - const size_t stMaxToRemoveAtOnce = 10; + const size_t stMaxToRemoveAtOnce = 10; - // delete items in chunks - std::set::const_iterator iterToDelete = m_setDeleteItems.begin(); - while(iterToDelete != m_setDeleteItems.end()) - { - TString strItemsToRemove; - size_t stToRemove = stMaxToRemoveAtOnce; - while(iterToDelete != m_setDeleteItems.end() && (--stToRemove) != 0) + // delete items in chunks + std::set::const_iterator iterToDelete = m_setDeleteItems.begin(); + while (iterToDelete != m_setDeleteItems.end()) { - strItemsToRemove += boost::str(boost::wformat(L"%1%,") % *iterToDelete).c_str(); - ++iterToDelete; - } - strItemsToRemove.TrimRightSelf(_T(",")); + TString strItemsToRemove; + size_t stToRemove = stMaxToRemoveAtOnce; + while (iterToDelete != m_setDeleteItems.end() && (--stToRemove) != 0) + { + strItemsToRemove += boost::str(boost::wformat(L"%1%,") % *iterToDelete).c_str(); + ++iterToDelete; + } + strItemsToRemove.TrimRightSelf(_T(",")); - TString strQuery = boost::str(boost::wformat(L"DELETE FROM %1% WHERE id IN (%2%)") % m_strName % strItemsToRemove).c_str(); - tStatement.Prepare(strQuery.c_str()); + TString strQuery = boost::str(boost::wformat(L"DELETE FROM %1% WHERE id IN (%2%)") % m_strName % strItemsToRemove).c_str(); + tStatement.Prepare(strQuery.c_str()); - DBTRACE1_D(_T("Executing query: %s\n"), strQuery.c_str()); - tStatement.Step(); + DBTRACE1_D(_T("Executing query: %s\n"), strQuery.c_str()); + tStatement.Step(); + } } -} -boost::pool<>& TSQLiteSerializerContainer::GetPool() -{ - if(!m_pPoolRows) - m_pPoolRows = new boost::pool<>(CalculateRowMemorySize()); - else + boost::pool<>& TSQLiteSerializerContainer::GetPool() { - if(m_pPoolRows->get_requested_size() != CalculateRowMemorySize()) - THROW_SERIALIZER_EXCEPTION(eErr_InternalProblem, _T("Column count changed after first use")); + if (!m_pPoolRows) + m_pPoolRows = new boost::pool<>(CalculateRowMemorySize()); + else + { + if (m_pPoolRows->get_requested_size() != CalculateRowMemorySize()) + THROW_SERIALIZER_EXCEPTION(eErr_InternalProblem, _T("Column count changed after first use")); + } + + return *m_pPoolRows; } - return *m_pPoolRows; -} + size_t TSQLiteSerializerContainer::CalculateRowMemorySize() const + { + // assume 64bit column mask (8 bytes) + const size_t stMaskSize = 8; -size_t TSQLiteSerializerContainer::CalculateRowMemorySize() const -{ - // assume 64bit column mask (8 bytes) - const size_t stMaskSize = 8; + // and additionally 64bit for each column (either for storing numbers directly or for allocating string/double) + const size_t stFieldSize = 8; - // and additionally 64bit for each column (either for storing numbers directly or for allocating string/double) - const size_t stFieldSize = 8; - - return stMaskSize + m_tColumns.GetCount() * stFieldSize; + return stMaskSize + m_tColumns.GetCount() * stFieldSize; + } } - -END_CHCORE_NAMESPACE