remove some "optimisation" insanity in ScriptEventContainer

I can only imagine the weird bugs that must have periodically resulted
when we had a hash value collision.
In the process, fix hasElements() to return a useful value

Change-Id: I1d9a052e73332b4b2bbc9c1fd8142c13eb22f1be
Reviewed-on: https://gerrit.libreoffice.org/40226
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin
2017-07-20 12:41:28 +02:00
parent b1601f7333
commit 85f08e3e34
3 changed files with 20 additions and 54 deletions

View File

@@ -686,8 +686,6 @@ include/test/sheet/xdatapilottable.hxx:32
apitest::XDataPilotTable xCellForCheck css::uno::Reference<css::table::XCell> apitest::XDataPilotTable xCellForCheck css::uno::Reference<css::table::XCell>
include/test/sheet/xnamedranges.hxx:38 include/test/sheet/xnamedranges.hxx:38
apitest::XNamedRanges xSheet css::uno::Reference<css::sheet::XSpreadsheet> apitest::XNamedRanges xSheet css::uno::Reference<css::sheet::XSpreadsheet>
include/toolkit/controls/eventcontainer.hxx:52
toolkit::ScriptEventContainer mnElementCount sal_Int32
include/tools/inetmime.hxx:66 include/tools/inetmime.hxx:66
INetContentTypeParameter m_bConverted _Bool INetContentTypeParameter m_bConverted _Bool
include/tools/multisel.hxx:43 include/tools/multisel.hxx:43

View File

@@ -32,24 +32,12 @@
namespace toolkit namespace toolkit
{ {
// Hashtable to optimize
typedef std::unordered_map
<
OUString,
sal_Int32,
OUStringHash
>
NameContainerNameMap;
class ScriptEventContainer : public ::cppu::WeakImplHelper< class ScriptEventContainer : public ::cppu::WeakImplHelper<
css::container::XNameContainer, css::container::XNameContainer,
css::container::XContainer > css::container::XContainer >
{ {
NameContainerNameMap mHashMap; std::unordered_map< OUString, css::uno::Any, OUStringHash>
css::uno::Sequence< OUString > mNames; mHashMap;
std::vector< css::uno::Any > mValues;
sal_Int32 mnElementCount;
css::uno::Type mType; css::uno::Type mType;
ContainerListenerMultiplexer maContainerListeners; ContainerListenerMultiplexer maContainerListeners;

View File

@@ -46,33 +46,33 @@ Type ScriptEventContainer::getElementType()
sal_Bool ScriptEventContainer::hasElements() sal_Bool ScriptEventContainer::hasElements()
{ {
bool bRet = (mnElementCount > 0); return !mHashMap.empty();
return bRet;
} }
// Methods XNameAccess // Methods XNameAccess
Any ScriptEventContainer::getByName( const OUString& aName ) Any ScriptEventContainer::getByName( const OUString& aName )
{ {
NameContainerNameMap::iterator aIt = mHashMap.find( aName ); auto aIt = mHashMap.find( aName );
if( aIt == mHashMap.end() ) if( aIt == mHashMap.end() )
{ {
throw NoSuchElementException(); throw NoSuchElementException();
} }
sal_Int32 iHashResult = (*aIt).second; return aIt->second;
Any aRetAny = mValues[ iHashResult ];
return aRetAny;
} }
Sequence< OUString > ScriptEventContainer::getElementNames() Sequence< OUString > ScriptEventContainer::getElementNames()
{ {
return mNames; Sequence<OUString> aRet(mHashMap.size());
int i = 0;
for (auto const & pair : mHashMap)
aRet[i++] = pair.first;
return aRet;
} }
sal_Bool ScriptEventContainer::hasByName( const OUString& aName ) sal_Bool ScriptEventContainer::hasByName( const OUString& aName )
{ {
NameContainerNameMap::iterator aIt = mHashMap.find( aName ); auto aIt = mHashMap.find( aName );
bool bRet = ( aIt != mHashMap.end() ); return aIt != mHashMap.end();
return bRet;
} }
@@ -83,14 +83,13 @@ void ScriptEventContainer::replaceByName( const OUString& aName, const Any& aEle
if( mType != aAnyType ) if( mType != aAnyType )
throw IllegalArgumentException(); throw IllegalArgumentException();
NameContainerNameMap::iterator aIt = mHashMap.find( aName ); auto aIt = mHashMap.find( aName );
if( aIt == mHashMap.end() ) if( aIt == mHashMap.end() )
{ {
throw NoSuchElementException(); throw NoSuchElementException();
} }
sal_Int32 iHashResult = (*aIt).second; Any aOldElement = aIt->second;
Any aOldElement = mValues[ iHashResult ]; aIt->second = aElement;
mValues[ iHashResult ] = aElement;
// Fire event // Fire event
ContainerEvent aEvent; ContainerEvent aEvent;
@@ -109,18 +108,13 @@ void ScriptEventContainer::insertByName( const OUString& aName, const Any& aElem
if( mType != aAnyType ) if( mType != aAnyType )
throw IllegalArgumentException(); throw IllegalArgumentException();
NameContainerNameMap::iterator aIt = mHashMap.find( aName ); auto aIt = mHashMap.find( aName );
if( aIt != mHashMap.end() ) if( aIt != mHashMap.end() )
{ {
throw ElementExistException(); throw ElementExistException();
} }
sal_Int32 nCount = mNames.getLength(); mHashMap[ aName ] = aElement;
mNames.realloc( nCount + 1 );
mValues.resize( nCount + 1 );
mNames.getArray()[ nCount ] = aName;
mValues[ nCount ] = aElement;
mHashMap[ aName ] = nCount;
// Fire event // Fire event
ContainerEvent aEvent; ContainerEvent aEvent;
@@ -132,33 +126,20 @@ void ScriptEventContainer::insertByName( const OUString& aName, const Any& aElem
void ScriptEventContainer::removeByName( const OUString& Name ) void ScriptEventContainer::removeByName( const OUString& Name )
{ {
NameContainerNameMap::iterator aIt = mHashMap.find( Name ); auto aIt = mHashMap.find( Name );
if( aIt == mHashMap.end() ) if( aIt == mHashMap.end() )
{ {
throw NoSuchElementException(); throw NoSuchElementException();
} }
sal_Int32 iHashResult = (*aIt).second;
Any aOldElement = mValues[ iHashResult ];
// Fire event // Fire event
ContainerEvent aEvent; ContainerEvent aEvent;
aEvent.Source = *this; aEvent.Source = *this;
aEvent.Element = aOldElement; aEvent.Element = aIt->second;
aEvent.Accessor <<= Name; aEvent.Accessor <<= Name;
maContainerListeners.elementRemoved( aEvent ); maContainerListeners.elementRemoved( aEvent );
mHashMap.erase( aIt ); mHashMap.erase( aIt );
sal_Int32 iLast = mNames.getLength() - 1;
if( iLast != iHashResult )
{
OUString* pNames = mNames.getArray();
pNames[ iHashResult ] = pNames[ iLast ];
mValues[ iHashResult ] = mValues[ iLast ];
mHashMap[ pNames[ iHashResult ] ] = iHashResult;
}
mNames.realloc( iLast );
mValues.resize( iLast );
} }
// Methods XContainer // Methods XContainer
@@ -174,8 +155,7 @@ void ScriptEventContainer::removeContainerListener( const css::uno::Reference< c
ScriptEventContainer::ScriptEventContainer() ScriptEventContainer::ScriptEventContainer()
: mnElementCount( 0 ), : mType( cppu::UnoType<ScriptEventDescriptor>::get() ),
mType( cppu::UnoType<ScriptEventDescriptor>::get() ),
maContainerListeners( *this ) maContainerListeners( *this )
{ {
} }