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:
parent
f9fd6390cd
commit
f9a97a5d5a
@ -122,7 +122,7 @@ public:
|
||||
void Push( SvMetaObject * pObj );
|
||||
sal_uInt32 GetUniqueId() { return ++nUniqueId; }
|
||||
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 );
|
||||
|
||||
SvMetaType * FindType( const OString& rName );
|
||||
|
@ -22,51 +22,49 @@
|
||||
|
||||
#include <hash.hxx>
|
||||
|
||||
typedef tools::SvRef<SvStringHashEntry> SvStringHashEntryRef;
|
||||
|
||||
class SvClassManager;
|
||||
struct SvGlobalHashNames
|
||||
{
|
||||
SvStringHashEntryRef MM_module;
|
||||
SvStringHashEntryRef MM_interface;
|
||||
SvStringHashEntryRef MM_shell;
|
||||
SvStringHashEntryRef MM_Toggle;
|
||||
SvStringHashEntryRef MM_AutoUpdate;
|
||||
SvStringHashEntryRef MM_Asynchron;
|
||||
SvStringHashEntryRef MM_RecordPerSet;
|
||||
SvStringHashEntryRef MM_RecordPerItem;
|
||||
SvStringHashEntryRef MM_NoRecord;
|
||||
SvStringHashEntryRef MM_RecordAbsolute;
|
||||
SvStringHashEntryRef MM_enum;
|
||||
SvStringHashEntryRef MM_UINT16;
|
||||
SvStringHashEntryRef MM_INT16;
|
||||
SvStringHashEntryRef MM_UINT32;
|
||||
SvStringHashEntryRef MM_INT32;
|
||||
SvStringHashEntryRef MM_BOOL;
|
||||
SvStringHashEntryRef MM_BYTE;
|
||||
SvStringHashEntryRef MM_float;
|
||||
SvStringHashEntryRef MM_double;
|
||||
SvStringHashEntryRef MM_item;
|
||||
SvStringHashEntryRef MM_PseudoSlots;
|
||||
SvStringHashEntryRef MM_import;
|
||||
SvStringHashEntryRef MM_SlotIdFile;
|
||||
SvStringHashEntryRef MM_include;
|
||||
SvStringHashEntryRef MM_ExecMethod;
|
||||
SvStringHashEntryRef MM_StateMethod;
|
||||
SvStringHashEntryRef MM_GroupId;
|
||||
SvStringHashEntryRef MM_Export;
|
||||
SvStringHashEntryRef MM_PseudoPrefix;
|
||||
SvStringHashEntryRef MM_define;
|
||||
SvStringHashEntryRef MM_MenuConfig;
|
||||
SvStringHashEntryRef MM_ToolBoxConfig;
|
||||
SvStringHashEntryRef MM_AccelConfig;
|
||||
SvStringHashEntryRef MM_FastCall;
|
||||
SvStringHashEntryRef MM_SbxObject;
|
||||
SvStringHashEntryRef MM_Container;
|
||||
SvStringHashEntryRef MM_ReadOnlyDoc;
|
||||
SvStringHashEntryRef MM_struct;
|
||||
SvStringHashEntryRef MM_SlotType;
|
||||
SvStringHashEntryRef MM_DisableFlags;
|
||||
SvStringHashEntry* MM_module;
|
||||
SvStringHashEntry* MM_interface;
|
||||
SvStringHashEntry* MM_shell;
|
||||
SvStringHashEntry* MM_Toggle;
|
||||
SvStringHashEntry* MM_AutoUpdate;
|
||||
SvStringHashEntry* MM_Asynchron;
|
||||
SvStringHashEntry* MM_RecordPerSet;
|
||||
SvStringHashEntry* MM_RecordPerItem;
|
||||
SvStringHashEntry* MM_NoRecord;
|
||||
SvStringHashEntry* MM_RecordAbsolute;
|
||||
SvStringHashEntry* MM_enum;
|
||||
SvStringHashEntry* MM_UINT16;
|
||||
SvStringHashEntry* MM_INT16;
|
||||
SvStringHashEntry* MM_UINT32;
|
||||
SvStringHashEntry* MM_INT32;
|
||||
SvStringHashEntry* MM_BOOL;
|
||||
SvStringHashEntry* MM_BYTE;
|
||||
SvStringHashEntry* MM_float;
|
||||
SvStringHashEntry* MM_double;
|
||||
SvStringHashEntry* MM_item;
|
||||
SvStringHashEntry* MM_PseudoSlots;
|
||||
SvStringHashEntry* MM_import;
|
||||
SvStringHashEntry* MM_SlotIdFile;
|
||||
SvStringHashEntry* MM_include;
|
||||
SvStringHashEntry* MM_ExecMethod;
|
||||
SvStringHashEntry* MM_StateMethod;
|
||||
SvStringHashEntry* MM_GroupId;
|
||||
SvStringHashEntry* MM_Export;
|
||||
SvStringHashEntry* MM_PseudoPrefix;
|
||||
SvStringHashEntry* MM_define;
|
||||
SvStringHashEntry* MM_MenuConfig;
|
||||
SvStringHashEntry* MM_ToolBoxConfig;
|
||||
SvStringHashEntry* MM_AccelConfig;
|
||||
SvStringHashEntry* MM_FastCall;
|
||||
SvStringHashEntry* MM_SbxObject;
|
||||
SvStringHashEntry* MM_Container;
|
||||
SvStringHashEntry* MM_ReadOnlyDoc;
|
||||
SvStringHashEntry* MM_struct;
|
||||
SvStringHashEntry* MM_SlotType;
|
||||
SvStringHashEntry* MM_DisableFlags;
|
||||
|
||||
SvGlobalHashNames();
|
||||
};
|
||||
@ -88,7 +86,7 @@ inline SvStringHashEntry * SvHash_##Name() \
|
||||
{ \
|
||||
if( !GetIdlApp().pGlobalNames ) \
|
||||
GetIdlApp().pGlobalNames = new SvGlobalHashNames(); \
|
||||
return GetIdlApp().pGlobalNames->MM_##Name.get(); \
|
||||
return GetIdlApp().pGlobalNames->MM_##Name; \
|
||||
}
|
||||
|
||||
HASH_INLINE(module)
|
||||
|
@ -23,34 +23,11 @@
|
||||
#include <rtl/ustring.hxx>
|
||||
#include <tools/ref.hxx>
|
||||
#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;
|
||||
sal_uLong nValue;
|
||||
bool bHasId;
|
||||
@ -75,22 +52,17 @@ public:
|
||||
sal_uLong GetValue() const { return nValue; }
|
||||
};
|
||||
|
||||
class SvStringHashTable : public SvHashTable
|
||||
class SvStringHashTable
|
||||
{
|
||||
SvStringHashEntry* pEntries;
|
||||
protected:
|
||||
virtual sal_uInt32 HashFunc( const OString& rElement ) const override;
|
||||
virtual bool equals( const OString &rElement, sal_uInt32 nIndex ) const override;
|
||||
std::unordered_map<sal_uInt32, std::unique_ptr<SvStringHashEntry>> maInt2EntryMap;
|
||||
std::unordered_map<OString, sal_uInt32, OStringHash> maString2IntMap;
|
||||
sal_uInt32 mnNextId = 0;
|
||||
|
||||
public:
|
||||
SvStringHashTable( sal_uInt32 nMaxEntries ); // max size of hash-tabel
|
||||
virtual ~SvStringHashTable() override;
|
||||
|
||||
SvStringHashEntry * Insert( OString const & rElement, sal_uInt32 * pInsertPos );
|
||||
bool Test( OString const & rElement, sal_uInt32 * pInsertPos );
|
||||
SvStringHashEntry * Get( sal_uInt32 nInsertPos ) 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
|
||||
|
@ -27,164 +27,47 @@
|
||||
#include <tools/debug.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
|
||||
nFill = 0; // no entries
|
||||
lTry = 0;
|
||||
lAsk = 0;
|
||||
}
|
||||
|
||||
SvHashTable::~SvHashTable()
|
||||
{
|
||||
}
|
||||
|
||||
bool SvHashTable::Test_Insert( const OString& rElement, bool bInsert,
|
||||
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;
|
||||
}
|
||||
nLoop++;
|
||||
lTry++;
|
||||
nIndex = (sal_uInt16)(nIndex + nHash + 7) % nMax;
|
||||
auto it = maString2IntMap.find(rElement);
|
||||
if (it != maString2IntMap.end()) {
|
||||
*pInsertPos = it->second;
|
||||
return maInt2EntryMap[*pInsertPos].get();
|
||||
}
|
||||
maString2IntMap[rElement] = mnNextId;
|
||||
maInt2EntryMap[mnNextId] = o3tl::make_unique<SvStringHashEntry>(rElement);
|
||||
*pInsertPos = mnNextId;
|
||||
mnNextId++;
|
||||
return maInt2EntryMap[*pInsertPos].get();
|
||||
}
|
||||
|
||||
if( bInsert )
|
||||
{
|
||||
DBG_ASSERT( nMax != nLoop, "Hash table full" );
|
||||
if( nMax != nLoop )
|
||||
{
|
||||
nFill++;
|
||||
*pInsertPos = nIndex; // return free place
|
||||
return true;
|
||||
}
|
||||
bool SvStringHashTable::Test( const OString& rElement, sal_uInt32 * pInsertPos )
|
||||
{
|
||||
auto it = maString2IntMap.find(rElement);
|
||||
if (it != maString2IntMap.end()) {
|
||||
*pInsertPos = it->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SvStringHashTable::SvStringHashTable( sal_uInt32 nMaxEntries )
|
||||
: SvHashTable( nMaxEntries )
|
||||
SvStringHashEntry * SvStringHashTable::Get( sal_uInt32 nInsertPos ) const
|
||||
{
|
||||
pEntries = new SvStringHashEntry[ nMaxEntries ];
|
||||
|
||||
// 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;
|
||||
auto it = maInt2EntryMap.find(nInsertPos);
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
if( pE->GetName().equalsIgnoreAsciiCase( rName ) && !pE->GetName().equals( rName ) )
|
||||
return pE->GetName();
|
||||
}
|
||||
SvStringHashEntry * pE = rPair.second.get();
|
||||
if( pE->GetName().equalsIgnoreAsciiCase( rName ) && !pE->GetName().equals( rName ) )
|
||||
return pE->GetName();
|
||||
}
|
||||
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: */
|
||||
|
@ -110,7 +110,7 @@ char CommandLineSyntax[] =
|
||||
void Init()
|
||||
{
|
||||
if( !GetIdlApp().pHashTable )
|
||||
GetIdlApp().pHashTable = new SvStringHashTable( 2801 );
|
||||
GetIdlApp().pHashTable = new SvStringHashTable;
|
||||
if( !GetIdlApp().pGlobalNames )
|
||||
GetIdlApp().pGlobalNames = new SvGlobalHashNames();
|
||||
}
|
||||
|
@ -125,18 +125,13 @@ bool SvIdlDataBase::FindId( const OString& rIdName, sal_uLong * pVal )
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SvIdlDataBase::InsertId( const OString& rIdName, sal_uLong nVal )
|
||||
void SvIdlDataBase::InsertId( const OString& rIdName, sal_uLong nVal )
|
||||
{
|
||||
if( !pIdTable )
|
||||
pIdTable = new SvStringHashTable( 20003 );
|
||||
pIdTable = new SvStringHashTable;
|
||||
|
||||
sal_uInt32 nHash;
|
||||
if( pIdTable->Insert( rIdName, &nHash ) )
|
||||
{
|
||||
pIdTable->Get( nHash )->SetValue( nVal );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
pIdTable->Insert( rIdName, &nHash )->SetValue( nVal );
|
||||
}
|
||||
|
||||
bool SvIdlDataBase::ReadIdFile( const OString& rOFileName )
|
||||
@ -211,10 +206,7 @@ bool SvIdlDataBase::ReadIdFile( const OString& rOFileName )
|
||||
}
|
||||
if( bOk )
|
||||
{
|
||||
if( !InsertId( aDefName, nVal ) )
|
||||
{
|
||||
throw SvParseException( "hash table overflow: ", rTok );
|
||||
}
|
||||
InsertId( aDefName, nVal );
|
||||
}
|
||||
}
|
||||
else if( rTok.Is( SvHash_include() ) )
|
||||
|
Loading…
x
Reference in New Issue
Block a user