drop custom hashtable implementation in idl

Change-Id: I2cdb79022e77cdcc03962d392d0d87626a090ac5
Reviewed-on: https://gerrit.libreoffice.org/32043
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 2016-12-15 13:44:21 +02:00
parent f9fd6390cd
commit f9a97a5d5a
6 changed files with 83 additions and 238 deletions

View File

@ -122,7 +122,7 @@ public:
void Push( SvMetaObject * pObj ); void Push( SvMetaObject * pObj );
sal_uInt32 GetUniqueId() { return ++nUniqueId; } sal_uInt32 GetUniqueId() { return ++nUniqueId; }
bool FindId( const OString& rIdName, sal_uLong * pVal ); bool FindId( const OString& rIdName, sal_uLong * pVal );
bool InsertId( const OString& rIdName, sal_uLong nVal ); void InsertId( const OString& rIdName, sal_uLong nVal );
bool ReadIdFile( const OString& rFileName ); bool ReadIdFile( const OString& rFileName );
SvMetaType * FindType( const OString& rName ); SvMetaType * FindType( const OString& rName );

View File

@ -22,51 +22,49 @@
#include <hash.hxx> #include <hash.hxx>
typedef tools::SvRef<SvStringHashEntry> SvStringHashEntryRef;
class SvClassManager; class SvClassManager;
struct SvGlobalHashNames struct SvGlobalHashNames
{ {
SvStringHashEntryRef MM_module; SvStringHashEntry* MM_module;
SvStringHashEntryRef MM_interface; SvStringHashEntry* MM_interface;
SvStringHashEntryRef MM_shell; SvStringHashEntry* MM_shell;
SvStringHashEntryRef MM_Toggle; SvStringHashEntry* MM_Toggle;
SvStringHashEntryRef MM_AutoUpdate; SvStringHashEntry* MM_AutoUpdate;
SvStringHashEntryRef MM_Asynchron; SvStringHashEntry* MM_Asynchron;
SvStringHashEntryRef MM_RecordPerSet; SvStringHashEntry* MM_RecordPerSet;
SvStringHashEntryRef MM_RecordPerItem; SvStringHashEntry* MM_RecordPerItem;
SvStringHashEntryRef MM_NoRecord; SvStringHashEntry* MM_NoRecord;
SvStringHashEntryRef MM_RecordAbsolute; SvStringHashEntry* MM_RecordAbsolute;
SvStringHashEntryRef MM_enum; SvStringHashEntry* MM_enum;
SvStringHashEntryRef MM_UINT16; SvStringHashEntry* MM_UINT16;
SvStringHashEntryRef MM_INT16; SvStringHashEntry* MM_INT16;
SvStringHashEntryRef MM_UINT32; SvStringHashEntry* MM_UINT32;
SvStringHashEntryRef MM_INT32; SvStringHashEntry* MM_INT32;
SvStringHashEntryRef MM_BOOL; SvStringHashEntry* MM_BOOL;
SvStringHashEntryRef MM_BYTE; SvStringHashEntry* MM_BYTE;
SvStringHashEntryRef MM_float; SvStringHashEntry* MM_float;
SvStringHashEntryRef MM_double; SvStringHashEntry* MM_double;
SvStringHashEntryRef MM_item; SvStringHashEntry* MM_item;
SvStringHashEntryRef MM_PseudoSlots; SvStringHashEntry* MM_PseudoSlots;
SvStringHashEntryRef MM_import; SvStringHashEntry* MM_import;
SvStringHashEntryRef MM_SlotIdFile; SvStringHashEntry* MM_SlotIdFile;
SvStringHashEntryRef MM_include; SvStringHashEntry* MM_include;
SvStringHashEntryRef MM_ExecMethod; SvStringHashEntry* MM_ExecMethod;
SvStringHashEntryRef MM_StateMethod; SvStringHashEntry* MM_StateMethod;
SvStringHashEntryRef MM_GroupId; SvStringHashEntry* MM_GroupId;
SvStringHashEntryRef MM_Export; SvStringHashEntry* MM_Export;
SvStringHashEntryRef MM_PseudoPrefix; SvStringHashEntry* MM_PseudoPrefix;
SvStringHashEntryRef MM_define; SvStringHashEntry* MM_define;
SvStringHashEntryRef MM_MenuConfig; SvStringHashEntry* MM_MenuConfig;
SvStringHashEntryRef MM_ToolBoxConfig; SvStringHashEntry* MM_ToolBoxConfig;
SvStringHashEntryRef MM_AccelConfig; SvStringHashEntry* MM_AccelConfig;
SvStringHashEntryRef MM_FastCall; SvStringHashEntry* MM_FastCall;
SvStringHashEntryRef MM_SbxObject; SvStringHashEntry* MM_SbxObject;
SvStringHashEntryRef MM_Container; SvStringHashEntry* MM_Container;
SvStringHashEntryRef MM_ReadOnlyDoc; SvStringHashEntry* MM_ReadOnlyDoc;
SvStringHashEntryRef MM_struct; SvStringHashEntry* MM_struct;
SvStringHashEntryRef MM_SlotType; SvStringHashEntry* MM_SlotType;
SvStringHashEntryRef MM_DisableFlags; SvStringHashEntry* MM_DisableFlags;
SvGlobalHashNames(); SvGlobalHashNames();
}; };
@ -88,7 +86,7 @@ inline SvStringHashEntry * SvHash_##Name() \
{ \ { \
if( !GetIdlApp().pGlobalNames ) \ if( !GetIdlApp().pGlobalNames ) \
GetIdlApp().pGlobalNames = new SvGlobalHashNames(); \ GetIdlApp().pGlobalNames = new SvGlobalHashNames(); \
return GetIdlApp().pGlobalNames->MM_##Name.get(); \ return GetIdlApp().pGlobalNames->MM_##Name; \
} }
HASH_INLINE(module) HASH_INLINE(module)

View File

@ -23,34 +23,11 @@
#include <rtl/ustring.hxx> #include <rtl/ustring.hxx>
#include <tools/ref.hxx> #include <tools/ref.hxx>
#include <tools/solar.h> #include <tools/solar.h>
#include <vector> #include <unordered_map>
#include <memory>
class SvHashTable class SvStringHashEntry
{ {
sal_uInt32 nMax; // size of hash-tabel
sal_uInt32 nFill; // elements in hash-tabel
sal_uInt32 lAsk; // number of requests
sal_uInt32 lTry; // number of tries
protected:
bool Test_Insert( const OString&, bool bInsert, sal_uInt32 * pInsertPos );
// compare element with entry
virtual bool equals( const OString& , sal_uInt32 ) const = 0;
// get hash value from subclass
virtual sal_uInt32 HashFunc( const OString& ) const = 0;
public:
SvHashTable( sal_uInt32 nMaxEntries );
virtual ~SvHashTable();
sal_uInt32 GetMax() const { return nMax; }
virtual bool IsEntry( sal_uInt32 ) const = 0;
};
class SvStringHashTable;
class SvStringHashEntry : public SvRefBase
{
friend class SvStringHashTable;
OString aName; OString aName;
sal_uLong nValue; sal_uLong nValue;
bool bHasId; bool bHasId;
@ -75,22 +52,17 @@ public:
sal_uLong GetValue() const { return nValue; } sal_uLong GetValue() const { return nValue; }
}; };
class SvStringHashTable : public SvHashTable class SvStringHashTable
{ {
SvStringHashEntry* pEntries; std::unordered_map<sal_uInt32, std::unique_ptr<SvStringHashEntry>> maInt2EntryMap;
protected: std::unordered_map<OString, sal_uInt32, OStringHash> maString2IntMap;
virtual sal_uInt32 HashFunc( const OString& rElement ) const override; sal_uInt32 mnNextId = 0;
virtual bool equals( const OString &rElement, sal_uInt32 nIndex ) const override;
public: public:
SvStringHashTable( sal_uInt32 nMaxEntries ); // max size of hash-tabel SvStringHashEntry * Insert( OString const & rElement, sal_uInt32 * pInsertPos );
virtual ~SvStringHashTable() override; bool Test( OString const & rElement, sal_uInt32 * pInsertPos );
SvStringHashEntry * Get( sal_uInt32 nInsertPos ) const;
OString GetNearString( const OString& rName ) const; OString GetNearString( const OString& rName ) const;
virtual bool IsEntry( sal_uInt32 nIndex ) const override;
bool Insert( const OString& rStr, sal_uInt32 * pHash ); // insert string
bool Test( const OString& rStr, sal_uInt32 * pHash ) const; // test of insert string
SvStringHashEntry * Get ( sal_uInt32 nIndex ) const; // return pointer to string
}; };
#endif // INCLUDED_IDL_INC_HASH_HXX #endif // INCLUDED_IDL_INC_HASH_HXX

View File

@ -27,164 +27,47 @@
#include <tools/debug.hxx> #include <tools/debug.hxx>
#include <rtl/character.hxx> #include <rtl/character.hxx>
#include <o3tl/make_unique.hxx>
SvHashTable::SvHashTable( sal_uInt32 nMaxEntries ) SvStringHashEntry * SvStringHashTable::Insert( const OString& rElement, sal_uInt32 * pInsertPos )
{ {
nMax = nMaxEntries; // set max entries auto it = maString2IntMap.find(rElement);
nFill = 0; // no entries if (it != maString2IntMap.end()) {
lTry = 0; *pInsertPos = it->second;
lAsk = 0; return maInt2EntryMap[*pInsertPos].get();
}
maString2IntMap[rElement] = mnNextId;
maInt2EntryMap[mnNextId] = o3tl::make_unique<SvStringHashEntry>(rElement);
*pInsertPos = mnNextId;
mnNextId++;
return maInt2EntryMap[*pInsertPos].get();
} }
SvHashTable::~SvHashTable() bool SvStringHashTable::Test( const OString& rElement, sal_uInt32 * pInsertPos )
{ {
} auto it = maString2IntMap.find(rElement);
if (it != maString2IntMap.end()) {
bool SvHashTable::Test_Insert( const OString& rElement, bool bInsert, *pInsertPos = it->second;
sal_uInt32 * pInsertPos )
{
sal_uInt32 nHash;
sal_uInt32 nIndex;
sal_uInt32 nLoop;
lAsk++;
lTry++;
nHash = HashFunc( rElement );
nIndex = nHash % nMax;
nLoop = 0; // divide to range
while( (nMax != nLoop) && IsEntry( nIndex ) )
{ // is place occupied
if( equals( rElement, nIndex ) )
{
if( pInsertPos )
*pInsertPos = nIndex; // place of Element
return true; return true;
} }
nLoop++;
lTry++;
nIndex = (sal_uInt16)(nIndex + nHash + 7) % nMax;
}
if( bInsert )
{
DBG_ASSERT( nMax != nLoop, "Hash table full" );
if( nMax != nLoop )
{
nFill++;
*pInsertPos = nIndex; // return free place
return true;
}
}
return false; return false;
} }
SvStringHashTable::SvStringHashTable( sal_uInt32 nMaxEntries ) SvStringHashEntry * SvStringHashTable::Get( sal_uInt32 nInsertPos ) const
: SvHashTable( nMaxEntries )
{ {
pEntries = new SvStringHashEntry[ nMaxEntries ]; auto it = maInt2EntryMap.find(nInsertPos);
return it->second.get();
// set RefCount to one
SvStringHashEntry * pPos, *pEnd;
pPos = pEntries;
pEnd = pEntries + nMaxEntries;
while( pPos != pEnd )
{
pPos->AddFirstRef();
pPos++;
}
}
SvStringHashTable::~SvStringHashTable()
{
#ifdef DBG_UTIL
// set RefCount to one
SvStringHashEntry * pPos, *pEnd;
pPos = pEntries;
pEnd = pEntries + GetMax();
while( pPos != pEnd )
{
DBG_ASSERT( pPos->GetRefCount() == 1, "Reference count != 1" );
pPos++;
}
#endif
delete [] pEntries;
}
sal_uInt32 SvStringHashTable::HashFunc( const OString& rElement ) const
{
sal_uInt32 nHash = 0; // hash value
const char * pStr = rElement.getStr();
int nShift = 0;
while( *pStr )
{
if( rtl::isAsciiUpperCase( *pStr ) )
nHash ^= sal_uInt32(*pStr - 'A' + 26) << nShift;
else
nHash ^= sal_uInt32(*pStr - 'a') << nShift;
if( nShift == 28 )
nShift = 0;
else
nShift += 4;
pStr++;
}
return nHash;
} }
OString SvStringHashTable::GetNearString( const OString& rName ) const OString SvStringHashTable::GetNearString( const OString& rName ) const
{ {
for( sal_uInt32 i = 0; i < GetMax(); i++ ) for( auto const & rPair : maInt2EntryMap )
{
SvStringHashEntry * pE = Get( i );
if( pE )
{ {
SvStringHashEntry * pE = rPair.second.get();
if( pE->GetName().equalsIgnoreAsciiCase( rName ) && !pE->GetName().equals( rName ) ) if( pE->GetName().equalsIgnoreAsciiCase( rName ) && !pE->GetName().equals( rName ) )
return pE->GetName(); return pE->GetName();
} }
}
return OString(); return OString();
} }
bool SvStringHashTable::IsEntry( sal_uInt32 nIndex ) const
{
if( nIndex >= GetMax() )
return false;
return pEntries[ nIndex ].HasId();
}
bool SvStringHashTable::Insert( const OString& rName, sal_uInt32 * pIndex )
{
sal_uInt32 nIndex;
if( !pIndex ) pIndex = &nIndex;
if( !SvHashTable::Test_Insert( rName, true, pIndex ) )
return false;
if( !IsEntry( *pIndex ) )
pEntries[ *pIndex ] = SvStringHashEntry( rName );
return true;
}
bool SvStringHashTable::Test( const OString& rName, sal_uInt32 * pPos ) const
{
return const_cast<SvStringHashTable*>(this)->Test_Insert( rName, false, pPos );
}
SvStringHashEntry * SvStringHashTable::Get( sal_uInt32 nIndex ) const
{
if( IsEntry( nIndex ) )
return pEntries + nIndex;
return nullptr;
}
bool SvStringHashTable::equals( const OString& rElement,
sal_uInt32 nIndex ) const
{
return rElement.equals( pEntries[ nIndex ].GetName() );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -110,7 +110,7 @@ char CommandLineSyntax[] =
void Init() void Init()
{ {
if( !GetIdlApp().pHashTable ) if( !GetIdlApp().pHashTable )
GetIdlApp().pHashTable = new SvStringHashTable( 2801 ); GetIdlApp().pHashTable = new SvStringHashTable;
if( !GetIdlApp().pGlobalNames ) if( !GetIdlApp().pGlobalNames )
GetIdlApp().pGlobalNames = new SvGlobalHashNames(); GetIdlApp().pGlobalNames = new SvGlobalHashNames();
} }

View File

@ -125,18 +125,13 @@ bool SvIdlDataBase::FindId( const OString& rIdName, sal_uLong * pVal )
return false; return false;
} }
bool SvIdlDataBase::InsertId( const OString& rIdName, sal_uLong nVal ) void SvIdlDataBase::InsertId( const OString& rIdName, sal_uLong nVal )
{ {
if( !pIdTable ) if( !pIdTable )
pIdTable = new SvStringHashTable( 20003 ); pIdTable = new SvStringHashTable;
sal_uInt32 nHash; sal_uInt32 nHash;
if( pIdTable->Insert( rIdName, &nHash ) ) pIdTable->Insert( rIdName, &nHash )->SetValue( nVal );
{
pIdTable->Get( nHash )->SetValue( nVal );
return true;
}
return false;
} }
bool SvIdlDataBase::ReadIdFile( const OString& rOFileName ) bool SvIdlDataBase::ReadIdFile( const OString& rOFileName )
@ -211,10 +206,7 @@ bool SvIdlDataBase::ReadIdFile( const OString& rOFileName )
} }
if( bOk ) if( bOk )
{ {
if( !InsertId( aDefName, nVal ) ) InsertId( aDefName, nVal );
{
throw SvParseException( "hash table overflow: ", rTok );
}
} }
} }
else if( rTok.Is( SvHash_include() ) ) else if( rTok.Is( SvHash_include() ) )