Kaydet (Commit) 306758ab authored tarafından Noel Grandin's avatar Noel Grandin

tdf#117066 Saving ODT document with ~1500 bookmarks is slow, part 5

Individually, these don't make much difference, but they add up
to a halving the time to save on my machine.

OStorageImpl is spending time iterating over its m_aChildrenVector to
find stuff by name, so just use a std::unordered_map.
Also return iterator from FindElement, so we can avoid searching the map
twice.
This was probably the biggest win.

Change-Id: I30776bad5377d14144fc7a47e86527e2cdb62a83
Reviewed-on: https://gerrit.libreoffice.org/70313
Tested-by: Jenkins
Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst e610999b
...@@ -322,8 +322,9 @@ OStorage_Impl::~OStorage_Impl() ...@@ -322,8 +322,9 @@ OStorage_Impl::~OStorage_Impl()
m_pParent = nullptr; m_pParent = nullptr;
} }
std::for_each(m_aChildrenVector.begin(), m_aChildrenVector.end(), std::default_delete<SotElement_Impl>()); for (auto & pair : m_aChildrenMap)
m_aChildrenVector.clear(); delete pair.second;
m_aChildrenMap.clear();
std::for_each(m_aDeletedVector.begin(), m_aDeletedVector.end(), std::default_delete<SotElement_Impl>()); std::for_each(m_aDeletedVector.begin(), m_aDeletedVector.end(), std::default_delete<SotElement_Impl>());
m_aDeletedVector.clear(); m_aDeletedVector.clear();
...@@ -485,12 +486,12 @@ void OStorage_Impl::OpenOwnPackage() ...@@ -485,12 +486,12 @@ void OStorage_Impl::OpenOwnPackage()
throw embed::InvalidStorageException( THROW_WHERE ); throw embed::InvalidStorageException( THROW_WHERE );
} }
SotElementVector_Impl& OStorage_Impl::GetChildrenVector() bool OStorage_Impl::HasChildren()
{ {
::osl::MutexGuard aGuard( m_xMutex->GetMutex() ); ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
ReadContents(); ReadContents();
return m_aChildrenVector; return !m_aChildrenMap.empty();
} }
void OStorage_Impl::GetStorageProperties() void OStorage_Impl::GetStorageProperties()
...@@ -612,7 +613,8 @@ void OStorage_Impl::ReadContents() ...@@ -612,7 +613,8 @@ void OStorage_Impl::ReadContents()
xNewElement->m_bIsRemoved = true; xNewElement->m_bIsRemoved = true;
} }
m_aChildrenVector.push_back(xNewElement.release()); OUString name = xNewElement->m_aName; // because we're calling release in the next line
m_aChildrenMap.emplace(name, xNewElement.release());
} }
} }
catch( const container::NoSuchElementException& rNoSuchElementException ) catch( const container::NoSuchElementException& rNoSuchElementException )
...@@ -652,8 +654,9 @@ void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDes ...@@ -652,8 +654,9 @@ void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDes
if ( !m_xPackageFolder.is() ) if ( !m_xPackageFolder.is() )
throw embed::InvalidStorageException( THROW_WHERE ); throw embed::InvalidStorageException( THROW_WHERE );
for ( auto& pElement : m_aChildrenVector ) for ( auto& pair : m_aChildrenMap )
{ {
auto & pElement = pair.second;
if ( !pElement->m_bIsRemoved ) if ( !pElement->m_bIsRemoved )
CopyStorageElement( pElement, xDest, pElement->m_aName, bDirect ); CopyStorageElement( pElement, xDest, pElement->m_aName, bDirect );
} }
...@@ -1021,34 +1024,34 @@ void OStorage_Impl::Commit() ...@@ -1021,34 +1024,34 @@ void OStorage_Impl::Commit()
m_aDeletedVector.clear(); m_aDeletedVector.clear();
// remove removed elements // remove removed elements
SotElementVector_Impl::iterator pElementIter = m_aChildrenVector.begin(); auto mapIter = m_aChildrenMap.begin();
while ( pElementIter != m_aChildrenVector.end() ) while ( mapIter != m_aChildrenMap.end() )
{ {
// renamed and inserted elements must be really inserted to package later // renamed and inserted elements must be really inserted to package later
// since thay can conflict with removed elements // since thay can conflict with removed elements
auto & pElement = mapIter->second;
if ( (*pElementIter)->m_bIsRemoved ) if ( pElement->m_bIsRemoved )
{ {
if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage ) if ( m_nStorageType == embed::StorageFormats::OFOPXML && !pElement->m_bIsStorage )
RemoveStreamRelInfo( (*pElementIter)->m_aOriginalName ); RemoveStreamRelInfo( pElement->m_aOriginalName );
// the removed elements are not in new temporary storage // the removed elements are not in new temporary storage
if ( m_bCommited || m_bIsRoot ) if ( m_bCommited || m_bIsRoot )
xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName ); xNewPackageFolder->removeByName( pElement->m_aOriginalName );
delete *pElementIter; delete pElement;
pElementIter = m_aChildrenVector.erase(pElementIter); mapIter = m_aChildrenMap.erase(mapIter);
} }
else else
++pElementIter; ++mapIter;
} }
// there should be no more deleted elements // there should be no more deleted elements
for ( auto& pElement : m_aChildrenVector ) for ( auto& pair : m_aChildrenMap )
{ {
// if it is a 'duplicate commit' inserted elements must be really inserted to package later // if it is a 'duplicate commit' inserted elements must be really inserted to package later
// since thay can conflict with renamed elements // since thay can conflict with renamed elements
auto & pElement = pair.second;
if ( !pElement->m_bIsInserted ) if ( !pElement->m_bIsInserted )
{ {
// for now stream is opened in direct mode that means that in case // for now stream is opened in direct mode that means that in case
...@@ -1117,8 +1120,9 @@ void OStorage_Impl::Commit() ...@@ -1117,8 +1120,9 @@ void OStorage_Impl::Commit()
} }
} }
for ( auto& pElement : m_aChildrenVector ) for ( auto& pair : m_aChildrenMap )
{ {
auto & pElement = pair.second;
// now inserted elements can be inserted to the package // now inserted elements can be inserted to the package
if ( pElement->m_bIsInserted ) if ( pElement->m_bIsInserted )
{ {
...@@ -1212,29 +1216,35 @@ void OStorage_Impl::Revert() ...@@ -1212,29 +1216,35 @@ void OStorage_Impl::Revert()
// all the children must be removed // all the children must be removed
// they will be created later on demand // they will be created later on demand
SotElementVector_Impl::iterator pElementIter = m_aChildrenVector.begin(); // rebuild the map - cannot do it in-place, because we're changing some of the key values
while ( pElementIter != m_aChildrenVector.end() ) std::unordered_map<OUString, SotElement_Impl*> oldMap;
std::swap(oldMap, m_aChildrenMap);
auto pElementIter = oldMap.begin();
while ( pElementIter != oldMap.end() )
{ {
if ( (*pElementIter)->m_bIsInserted ) auto & pElement = pElementIter->second;
if ( pElement->m_bIsInserted )
{ {
delete *pElementIter; delete pElement;
pElementIter = m_aChildrenVector.erase(pElementIter);
} }
else else
{ {
ClearElement( *pElementIter ); ClearElement( pElement );
(*pElementIter)->m_aName = (*pElementIter)->m_aOriginalName; pElement->m_aName = pElement->m_aOriginalName;
(*pElementIter)->m_bIsRemoved = false; pElement->m_bIsRemoved = false;
++pElementIter; m_aChildrenMap.emplace(pElement->m_aName, pElement);
} }
++pElementIter;
} }
// return replaced removed elements // return replaced removed elements
for ( auto& pDeleted : m_aDeletedVector ) for ( auto& pDeleted : m_aDeletedVector )
{ {
m_aChildrenVector.push_back( pDeleted ); // use original name as key, because we're updating m_aName below
m_aChildrenMap.emplace( pDeleted->m_aOriginalName, pDeleted );
ClearElement( pDeleted ); ClearElement( pDeleted );
...@@ -1281,6 +1291,14 @@ void OStorage_Impl::Revert() ...@@ -1281,6 +1291,14 @@ void OStorage_Impl::Revert()
} }
SotElement_Impl* OStorage_Impl::FindElement( const OUString& rName ) SotElement_Impl* OStorage_Impl::FindElement( const OUString& rName )
{
::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
auto it = FindElementIt(rName);
return it == m_aChildrenMap.end() ? nullptr : it->second;
}
std::unordered_map<OUString, SotElement_Impl*>::iterator OStorage_Impl::FindElementIt( const OUString& rName )
{ {
SAL_WARN_IF( rName.isEmpty(), "package.xstor", "Name is empty!" ); SAL_WARN_IF( rName.isEmpty(), "package.xstor", "Name is empty!" );
...@@ -1288,12 +1306,13 @@ SotElement_Impl* OStorage_Impl::FindElement( const OUString& rName ) ...@@ -1288,12 +1306,13 @@ SotElement_Impl* OStorage_Impl::FindElement( const OUString& rName )
ReadContents(); ReadContents();
auto pElementIter = std::find_if(m_aChildrenVector.begin(), m_aChildrenVector.end(), auto pElementIter = m_aChildrenMap.find(rName);
[&rName](const SotElement_Impl* pElement) { return pElement->m_aName == rName && !pElement->m_bIsRemoved; }); if (pElementIter == m_aChildrenMap.end())
if (pElementIter != m_aChildrenVector.end()) return m_aChildrenMap.end();
return *pElementIter; if (pElementIter->second->m_bIsRemoved)
return m_aChildrenMap.end();
return nullptr; return pElementIter;
} }
SotElement_Impl* OStorage_Impl::InsertStream( const OUString& aName, bool bEncr ) SotElement_Impl* OStorage_Impl::InsertStream( const OUString& aName, bool bEncr )
...@@ -1321,7 +1340,7 @@ SotElement_Impl* OStorage_Impl::InsertStream( const OUString& aName, bool bEncr ...@@ -1321,7 +1340,7 @@ SotElement_Impl* OStorage_Impl::InsertStream( const OUString& aName, bool bEncr
SotElement_Impl* pNewElement = InsertElement( aName, false ); SotElement_Impl* pNewElement = InsertElement( aName, false );
pNewElement->m_xStream.reset(new OWriteStream_Impl(this, xPackageSubStream, m_xPackage, m_xContext, bEncr, m_nStorageType, true)); pNewElement->m_xStream.reset(new OWriteStream_Impl(this, xPackageSubStream, m_xPackage, m_xContext, bEncr, m_nStorageType, true));
m_aChildrenVector.push_back( pNewElement ); m_aChildrenMap.emplace( pNewElement->m_aName, pNewElement );
m_bIsModified = true; m_bIsModified = true;
m_bBroadcastModified = true; m_bBroadcastModified = true;
...@@ -1360,7 +1379,7 @@ void OStorage_Impl::InsertRawStream( const OUString& aName, const uno::Reference ...@@ -1360,7 +1379,7 @@ void OStorage_Impl::InsertRawStream( const OUString& aName, const uno::Reference
// the stream is inserted and must be treated as a committed one // the stream is inserted and must be treated as a committed one
pNewElement->m_xStream->SetToBeCommited(); pNewElement->m_xStream->SetToBeCommited();
m_aChildrenVector.push_back( pNewElement ); m_aChildrenMap.emplace( pNewElement->m_aName, pNewElement );
m_bIsModified = true; m_bIsModified = true;
m_bBroadcastModified = true; m_bBroadcastModified = true;
} }
...@@ -1394,30 +1413,26 @@ SotElement_Impl* OStorage_Impl::InsertStorage( const OUString& aName, sal_Int32 ...@@ -1394,30 +1413,26 @@ SotElement_Impl* OStorage_Impl::InsertStorage( const OUString& aName, sal_Int32
pNewElement->m_xStorage = CreateNewStorageImpl(nStorageMode); pNewElement->m_xStorage = CreateNewStorageImpl(nStorageMode);
m_aChildrenVector.push_back( pNewElement ); m_aChildrenMap.emplace( pNewElement->m_aName, pNewElement );
return pNewElement; return pNewElement;
} }
SotElement_Impl* OStorage_Impl::InsertElement( const OUString& aName, bool bIsStorage ) SotElement_Impl* OStorage_Impl::InsertElement( const OUString& aName, bool bIsStorage )
{ {
OSL_ENSURE( FindElement( aName ) == nullptr, "Should not try to insert existing element" );
::osl::MutexGuard aGuard( m_xMutex->GetMutex() ); ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
SotElement_Impl* pDeletedElm = nullptr; SotElement_Impl* pDeletedElm = nullptr;
for ( const auto& pElement : m_aChildrenVector ) auto it = m_aChildrenMap.find(aName);
{ if (it != m_aChildrenMap.end())
if ( pElement->m_aName == aName )
{ {
auto pElement = it->second;
SAL_WARN_IF( !pElement->m_bIsRemoved, "package.xstor", "Try to insert an element instead of existing one!" ); SAL_WARN_IF( !pElement->m_bIsRemoved, "package.xstor", "Try to insert an element instead of existing one!" );
if ( pElement->m_bIsRemoved ) if ( pElement->m_bIsRemoved )
{ {
SAL_WARN_IF( pElement->m_bIsInserted, "package.xstor", "Inserted elements must be deleted immediately!" ); SAL_WARN_IF( pElement->m_bIsInserted, "package.xstor", "Inserted elements must be deleted immediately!" );
pDeletedElm = pElement; pDeletedElm = pElement;
break;
}
} }
} }
...@@ -1428,9 +1443,7 @@ SotElement_Impl* OStorage_Impl::InsertElement( const OUString& aName, bool bIsSt ...@@ -1428,9 +1443,7 @@ SotElement_Impl* OStorage_Impl::InsertElement( const OUString& aName, bool bIsSt
else else
OpenSubStream( pDeletedElm ); OpenSubStream( pDeletedElm );
m_aChildrenVector.erase( m_aChildrenMap.erase(it);
std::remove(m_aChildrenVector.begin(), m_aChildrenVector.end(), pDeletedElm),
m_aChildrenVector.end());
m_aDeletedVector.push_back( pDeletedElm ); m_aDeletedVector.push_back( pDeletedElm );
} }
...@@ -1488,12 +1501,13 @@ uno::Sequence< OUString > OStorage_Impl::GetElementNames() ...@@ -1488,12 +1501,13 @@ uno::Sequence< OUString > OStorage_Impl::GetElementNames()
ReadContents(); ReadContents();
sal_uInt32 nSize = m_aChildrenVector.size(); sal_uInt32 nSize = m_aChildrenMap.size();
uno::Sequence< OUString > aElementNames( nSize ); uno::Sequence< OUString > aElementNames( nSize );
sal_uInt32 nInd = 0; sal_uInt32 nInd = 0;
for ( const auto& pElement : m_aChildrenVector ) for ( const auto& pair : m_aChildrenMap )
{ {
auto pElement = pair.second;
if ( !pElement->m_bIsRemoved ) if ( !pElement->m_bIsRemoved )
aElementNames[nInd++] = pElement->m_aName; aElementNames[nInd++] = pElement->m_aName;
} }
...@@ -1502,12 +1516,9 @@ uno::Sequence< OUString > OStorage_Impl::GetElementNames() ...@@ -1502,12 +1516,9 @@ uno::Sequence< OUString > OStorage_Impl::GetElementNames()
return aElementNames; return aElementNames;
} }
void OStorage_Impl::RemoveElement( SotElement_Impl* pElement ) std::unordered_map<OUString, SotElement_Impl*>::iterator OStorage_Impl::RemoveElement( std::unordered_map<OUString, SotElement_Impl*>::iterator pElementIter )
{ {
SAL_WARN_IF( !pElement, "package.xstor", "Element must be provided!" ); auto pElement = pElementIter->second;
if ( !pElement )
return;
if ( (pElement->m_xStorage && ( pElement->m_xStorage->m_pAntiImpl || !pElement->m_xStorage->m_aReadOnlyWrapVector.empty() )) if ( (pElement->m_xStorage && ( pElement->m_xStorage->m_pAntiImpl || !pElement->m_xStorage->m_aReadOnlyWrapVector.empty() ))
|| (pElement->m_xStream && ( pElement->m_xStream->m_pAntiImpl || !pElement->m_xStream->m_aInputStreamsVector.empty() )) ) || (pElement->m_xStream && ( pElement->m_xStream->m_pAntiImpl || !pElement->m_xStream->m_aInputStreamsVector.empty() )) )
...@@ -1515,13 +1526,15 @@ void OStorage_Impl::RemoveElement( SotElement_Impl* pElement ) ...@@ -1515,13 +1526,15 @@ void OStorage_Impl::RemoveElement( SotElement_Impl* pElement )
if ( pElement->m_bIsInserted ) if ( pElement->m_bIsInserted )
{ {
delete pElement; delete pElementIter->second;
m_aChildrenVector.erase(std::remove(m_aChildrenVector.begin(), m_aChildrenVector.end(), pElement), m_aChildrenVector.end()); return m_aChildrenMap.erase(pElementIter);
} }
else else
{ {
pElement->m_bIsRemoved = true; pElement->m_bIsRemoved = true;
ClearElement( pElement ); ClearElement( pElement );
++pElementIter;
return pElementIter;
} }
// TODO/OFOPXML: the rel stream should be removed as well // TODO/OFOPXML: the rel stream should be removed as well
...@@ -2384,10 +2397,9 @@ uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement( ...@@ -2384,10 +2397,9 @@ uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement(
if ( nStorageMode & embed::ElementModes::TRUNCATE ) if ( nStorageMode & embed::ElementModes::TRUNCATE )
{ {
for ( SotElement_Impl* pElementToDel : pElement->m_xStorage->m_aChildrenVector ) auto pElementToDelIter = pElement->m_xStorage->m_aChildrenMap.begin();
{ while (pElementToDelIter != pElement->m_xStorage->m_aChildrenMap.end())
m_pImpl->RemoveElement( pElementToDel ); pElementToDelIter = m_pImpl->RemoveElement( pElementToDelIter );
}
} }
} }
} }
...@@ -2793,12 +2805,11 @@ void SAL_CALL OStorage::removeElement( const OUString& aElementName ) ...@@ -2793,12 +2805,11 @@ void SAL_CALL OStorage::removeElement( const OUString& aElementName )
try try
{ {
SotElement_Impl* pElement = m_pImpl->FindElement(aElementName); auto pElementIter = m_pImpl->FindElementIt(aElementName);
if ( pElementIter == m_pImpl->m_aChildrenMap.end() )
if (!pElement)
throw container::NoSuchElementException(THROW_WHERE); //??? throw container::NoSuchElementException(THROW_WHERE); //???
m_pImpl->RemoveElement(pElement); m_pImpl->RemoveElement(pElementIter);
m_pImpl->m_bIsModified = true; m_pImpl->m_bIsModified = true;
m_pImpl->m_bBroadcastModified = true; m_pImpl->m_bBroadcastModified = true;
...@@ -2878,11 +2889,14 @@ void SAL_CALL OStorage::renameElement( const OUString& aElementName, const OUStr ...@@ -2878,11 +2889,14 @@ void SAL_CALL OStorage::renameElement( const OUString& aElementName, const OUStr
if (pRefElement) if (pRefElement)
throw container::ElementExistException(THROW_WHERE); //??? throw container::ElementExistException(THROW_WHERE); //???
SotElement_Impl* pElement = m_pImpl->FindElement(aElementName); auto pElementIt = m_pImpl->FindElementIt( aElementName );
if (!pElement) if ( pElementIt == m_pImpl->m_aChildrenMap.end() )
throw container::NoSuchElementException(THROW_WHERE); //??? throw container::NoSuchElementException(THROW_WHERE); //???
auto pElement = pElementIt->second;
pElement->m_aName = aNewName; pElement->m_aName = aNewName;
m_pImpl->m_aChildrenMap.erase( pElementIt );
m_pImpl->m_aChildrenMap.emplace(pElement->m_aName, pElement);
m_pImpl->m_bIsModified = true; m_pImpl->m_bIsModified = true;
m_pImpl->m_bBroadcastModified = true; m_pImpl->m_bBroadcastModified = true;
...@@ -3052,17 +3066,17 @@ void SAL_CALL OStorage::moveElementTo( const OUString& aElementName, ...@@ -3052,17 +3066,17 @@ void SAL_CALL OStorage::moveElementTo( const OUString& aElementName,
try try
{ {
SotElement_Impl* pElement = m_pImpl->FindElement(aElementName); auto pElementIter = m_pImpl->FindElementIt( aElementName );
if (!pElement) if ( pElementIter == m_pImpl->m_aChildrenMap.end() )
throw container::NoSuchElementException(THROW_WHERE); //??? throw container::NoSuchElementException(THROW_WHERE); //???
uno::Reference<XNameAccess> xNameAccess(xDest, uno::UNO_QUERY_THROW); uno::Reference<XNameAccess> xNameAccess(xDest, uno::UNO_QUERY_THROW);
if (xNameAccess->hasByName(aNewName)) if (xNameAccess->hasByName(aNewName))
throw container::ElementExistException(THROW_WHERE); throw container::ElementExistException(THROW_WHERE);
m_pImpl->CopyStorageElement(pElement, xDest, aNewName, false); m_pImpl->CopyStorageElement(pElementIter->second, xDest, aNewName, false);
m_pImpl->RemoveElement(pElement); m_pImpl->RemoveElement(pElementIter);
m_pImpl->m_bIsModified = true; m_pImpl->m_bIsModified = true;
m_pImpl->m_bBroadcastModified = true; m_pImpl->m_bBroadcastModified = true;
...@@ -3612,8 +3626,9 @@ void SAL_CALL OStorage::revert() ...@@ -3612,8 +3626,9 @@ void SAL_CALL OStorage::revert()
} }
bool bThrow = std::any_of( bool bThrow = std::any_of(
m_pImpl->m_aChildrenVector.begin(), m_pImpl->m_aChildrenVector.end(), m_pImpl->m_aChildrenMap.begin(), m_pImpl->m_aChildrenMap.end(),
[](const SotElement_Impl* pElement) { [](decltype(m_pImpl->m_aChildrenMap)::value_type const & pair) {
auto pElement = pair.second;
return (pElement->m_xStorage return (pElement->m_xStorage
&& (pElement->m_xStorage->m_pAntiImpl && (pElement->m_xStorage->m_pAntiImpl
|| !pElement->m_xStorage->m_aReadOnlyWrapVector.empty())) || !pElement->m_xStorage->m_aReadOnlyWrapVector.empty()))
...@@ -3920,7 +3935,7 @@ sal_Bool SAL_CALL OStorage::hasElements() ...@@ -3920,7 +3935,7 @@ sal_Bool SAL_CALL OStorage::hasElements()
try try
{ {
return ( !m_pImpl->GetChildrenVector().empty() ); return m_pImpl->HasChildren();
} }
catch( const uno::RuntimeException& rRuntimeException ) catch( const uno::RuntimeException& rRuntimeException )
{ {
......
...@@ -139,7 +139,7 @@ struct OStorage_Impl ...@@ -139,7 +139,7 @@ struct OStorage_Impl
return m_nModifiedListenerCount > 0 && m_pAntiImpl != nullptr; return m_nModifiedListenerCount > 0 && m_pAntiImpl != nullptr;
} }
SotElementVector_Impl m_aChildrenVector; std::unordered_map<OUString, SotElement_Impl*> m_aChildrenMap;
SotElementVector_Impl m_aDeletedVector; SotElementVector_Impl m_aDeletedVector;
css::uno::Reference< css::container::XNameContainer > m_xPackageFolder; css::uno::Reference< css::container::XNameContainer > m_xPackageFolder;
...@@ -205,7 +205,7 @@ struct OStorage_Impl ...@@ -205,7 +205,7 @@ struct OStorage_Impl
void ReadContents(); void ReadContents();
void ReadRelInfoIfNecessary(); void ReadRelInfoIfNecessary();
SotElementVector_Impl& GetChildrenVector(); bool HasChildren();
void GetStorageProperties(); void GetStorageProperties();
css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > GetAllRelationshipsIfAny(); css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > GetAllRelationshipsIfAny();
...@@ -229,6 +229,7 @@ struct OStorage_Impl ...@@ -229,6 +229,7 @@ struct OStorage_Impl
bool bDirect ); bool bDirect );
SotElement_Impl* FindElement( const OUString& rName ); SotElement_Impl* FindElement( const OUString& rName );
std::unordered_map<OUString, SotElement_Impl*>::iterator FindElementIt( const OUString& rName );
SotElement_Impl* InsertStream( const OUString& aName, bool bEncr ); SotElement_Impl* InsertStream( const OUString& aName, bool bEncr );
void InsertRawStream( const OUString& aName, const css::uno::Reference< css::io::XInputStream >& xInStream ); void InsertRawStream( const OUString& aName, const css::uno::Reference< css::io::XInputStream >& xInStream );
...@@ -242,7 +243,7 @@ struct OStorage_Impl ...@@ -242,7 +243,7 @@ struct OStorage_Impl
css::uno::Sequence< OUString > GetElementNames(); css::uno::Sequence< OUString > GetElementNames();
void RemoveElement( SotElement_Impl* pElement ); std::unordered_map<OUString, SotElement_Impl*>::iterator RemoveElement( std::unordered_map<OUString, SotElement_Impl*>::iterator pElement );
static void ClearElement( SotElement_Impl* pElement ); static void ClearElement( SotElement_Impl* pElement );
/// @throws css::embed::InvalidStorageException /// @throws css::embed::InvalidStorageException
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment