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

drop custom hashtable implementation in idl

Change-Id: I2cdb79022e77cdcc03962d392d0d87626a090ac5
Reviewed-on: https://gerrit.libreoffice.org/32043Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
Tested-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst f9fd6390
......@@ -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;
public:
SvStringHashTable( sal_uInt32 nMaxEntries ); // max size of hash-tabel
virtual ~SvStringHashTable() override;
std::unordered_map<sal_uInt32, std::unique_ptr<SvStringHashEntry>> maInt2EntryMap;
std::unordered_map<OString, sal_uInt32, OStringHash> maString2IntMap;
sal_uInt32 mnNextId = 0;
public:
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;
}
if( bInsert )
{
DBG_ASSERT( nMax != nLoop, "Hash table full" );
if( nMax != nLoop )
{
nFill++;
*pInsertPos = nIndex; // return free place
return true;
}
auto it = maString2IntMap.find(rElement);
if (it != maString2IntMap.end()) {
*pInsertPos = it->second;
return maInt2EntryMap[*pInsertPos].get();
}
return false;
maString2IntMap[rElement] = mnNextId;
maInt2EntryMap[mnNextId] = o3tl::make_unique<SvStringHashEntry>(rElement);
*pInsertPos = mnNextId;
mnNextId++;
return maInt2EntryMap[*pInsertPos].get();
}
SvStringHashTable::SvStringHashTable( sal_uInt32 nMaxEntries )
: SvHashTable( nMaxEntries )
bool SvStringHashTable::Test( const OString& rElement, sal_uInt32 * pInsertPos )
{
pEntries = new SvStringHashEntry[ nMaxEntries ];
// set RefCount to one
SvStringHashEntry * pPos, *pEnd;
pPos = pEntries;
pEnd = pEntries + nMaxEntries;
while( pPos != pEnd )
{
pPos->AddFirstRef();
pPos++;
auto it = maString2IntMap.find(rElement);
if (it != maString2IntMap.end()) {
*pInsertPos = it->second;
return true;
}
return false;
}
SvStringHashTable::~SvStringHashTable()
SvStringHashEntry * SvStringHashTable::Get( sal_uInt32 nInsertPos ) const
{
#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() ) )
......
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