[Libreoffice-commits] core.git: idl/inc idl/source

Noel Grandin noel.grandin at collabora.co.uk
Mon Dec 19 06:06:38 UTC 2016


 idl/inc/database.hxx         |    2 
 idl/inc/globals.hxx          |   84 ++++++++++-----------
 idl/inc/hash.hxx             |   50 ++-----------
 idl/source/cmptools/hash.cxx |  165 ++++++-------------------------------------
 idl/source/prj/command.cxx   |    2 
 idl/source/prj/database.cxx  |   16 +---
 6 files changed, 82 insertions(+), 237 deletions(-)

New commits:
commit f9a97a5d5aca8473845bca2e17c5826b772b8f3c
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Thu Dec 15 13:44:21 2016 +0200

    drop custom hashtable implementation in idl
    
    Change-Id: I2cdb79022e77cdcc03962d392d0d87626a090ac5
    Reviewed-on: https://gerrit.libreoffice.org/32043
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
    Tested-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/idl/inc/database.hxx b/idl/inc/database.hxx
index 0ed28a6..25381c3 100644
--- a/idl/inc/database.hxx
+++ b/idl/inc/database.hxx
@@ -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 );
diff --git a/idl/inc/globals.hxx b/idl/inc/globals.hxx
index ad8aee0..ccd413c 100644
--- a/idl/inc/globals.hxx
+++ b/idl/inc/globals.hxx
@@ -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)
diff --git a/idl/inc/hash.hxx b/idl/inc/hash.hxx
index a510fbd..11edb80 100644
--- a/idl/inc/hash.hxx
+++ b/idl/inc/hash.hxx
@@ -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
diff --git a/idl/source/cmptools/hash.cxx b/idl/source/cmptools/hash.cxx
index 76976b4..17a5f25 100644
--- a/idl/source/cmptools/hash.cxx
+++ b/idl/source/cmptools/hash.cxx
@@ -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: */
diff --git a/idl/source/prj/command.cxx b/idl/source/prj/command.cxx
index 54e23ab..057c495 100644
--- a/idl/source/prj/command.cxx
+++ b/idl/source/prj/command.cxx
@@ -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();
 }
diff --git a/idl/source/prj/database.cxx b/idl/source/prj/database.cxx
index 2b45e6e..15c21a3 100644
--- a/idl/source/prj/database.cxx
+++ b/idl/source/prj/database.cxx
@@ -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() ) )


More information about the Libreoffice-commits mailing list