xref: /aoo4110/main/idl/source/cmptools/hash.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_idl.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski /****************** I N C L U D E S **************************************/
28*b1cdbd2cSJim Jagielski // C and C++ Includes.
29*b1cdbd2cSJim Jagielski #include <stdlib.h>
30*b1cdbd2cSJim Jagielski #include <stdio.h>
31*b1cdbd2cSJim Jagielski #include <ctype.h>
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski // Programmabh�ngige Includes.
34*b1cdbd2cSJim Jagielski #include <hash.hxx>
35*b1cdbd2cSJim Jagielski #include <tools/debug.hxx>
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski /****************** C O D E **********************************************/
38*b1cdbd2cSJim Jagielski /*************************************************************************
39*b1cdbd2cSJim Jagielski |*
40*b1cdbd2cSJim Jagielski |*    SvStringHashEntry::~SvStringHashEntry()
41*b1cdbd2cSJim Jagielski |*
42*b1cdbd2cSJim Jagielski |*    Beschreibung
43*b1cdbd2cSJim Jagielski |*
44*b1cdbd2cSJim Jagielski *************************************************************************/
~SvStringHashEntry()45*b1cdbd2cSJim Jagielski SvStringHashEntry::~SvStringHashEntry() { };
46*b1cdbd2cSJim Jagielski 
47*b1cdbd2cSJim Jagielski /*************************************************************************
48*b1cdbd2cSJim Jagielski |*
49*b1cdbd2cSJim Jagielski |*    SvHashTable::SvHashTable()
50*b1cdbd2cSJim Jagielski |*
51*b1cdbd2cSJim Jagielski |*    Beschreibung
52*b1cdbd2cSJim Jagielski |*
53*b1cdbd2cSJim Jagielski *************************************************************************/
SvHashTable(sal_uInt32 nMaxEntries)54*b1cdbd2cSJim Jagielski SvHashTable::SvHashTable( sal_uInt32 nMaxEntries )
55*b1cdbd2cSJim Jagielski {
56*b1cdbd2cSJim Jagielski     nMax = nMaxEntries;     // set max entries
57*b1cdbd2cSJim Jagielski     nFill = 0;              // no entries
58*b1cdbd2cSJim Jagielski     lTry = 0;
59*b1cdbd2cSJim Jagielski     lAsk = 0;
60*b1cdbd2cSJim Jagielski }
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski /*************************************************************************
63*b1cdbd2cSJim Jagielski |*
64*b1cdbd2cSJim Jagielski |*    SvHashTable::~SvHashTable()
65*b1cdbd2cSJim Jagielski |*
66*b1cdbd2cSJim Jagielski |*    Beschreibung
67*b1cdbd2cSJim Jagielski |*
68*b1cdbd2cSJim Jagielski *************************************************************************/
~SvHashTable()69*b1cdbd2cSJim Jagielski SvHashTable::~SvHashTable()
70*b1cdbd2cSJim Jagielski {
71*b1cdbd2cSJim Jagielski #ifdef DOS_NIE
72*b1cdbd2cSJim Jagielski     printf( "Maximum: %ld, F�llung: %ld\n", (sal_uLong)nMax, (sal_uLong)nFill );
73*b1cdbd2cSJim Jagielski     printf( "Anfragen: %ld, Versuche: %ld", (sal_uLong)lAsk, (sal_uLong)lTry );
74*b1cdbd2cSJim Jagielski     if( lTry != 0 )
75*b1cdbd2cSJim Jagielski         printf( ", V/E = %ld\n", lTry / lAsk );
76*b1cdbd2cSJim Jagielski #endif
77*b1cdbd2cSJim Jagielski }
78*b1cdbd2cSJim Jagielski 
79*b1cdbd2cSJim Jagielski /*************************************************************************
80*b1cdbd2cSJim Jagielski |*
81*b1cdbd2cSJim Jagielski |*    SvHashTable::Test_Insert()
82*b1cdbd2cSJim Jagielski |*
83*b1cdbd2cSJim Jagielski |*    Beschreibung
84*b1cdbd2cSJim Jagielski |*
85*b1cdbd2cSJim Jagielski *************************************************************************/
Test_Insert(const void * pElement,sal_Bool bInsert,sal_uInt32 * pInsertPos)86*b1cdbd2cSJim Jagielski sal_Bool SvHashTable::Test_Insert( const void * pElement, sal_Bool bInsert,
87*b1cdbd2cSJim Jagielski                                sal_uInt32 * pInsertPos )
88*b1cdbd2cSJim Jagielski {
89*b1cdbd2cSJim Jagielski     sal_uInt32    nHash;
90*b1cdbd2cSJim Jagielski     sal_uInt32    nIndex;
91*b1cdbd2cSJim Jagielski     sal_uInt32    nLoop;
92*b1cdbd2cSJim Jagielski 
93*b1cdbd2cSJim Jagielski     lAsk++;
94*b1cdbd2cSJim Jagielski     lTry++;
95*b1cdbd2cSJim Jagielski 
96*b1cdbd2cSJim Jagielski     nHash =  HashFunc( pElement );
97*b1cdbd2cSJim Jagielski     nIndex = nHash % nMax;
98*b1cdbd2cSJim Jagielski 
99*b1cdbd2cSJim Jagielski //  const char* s = ((ByteString*) pElement)->GetStr();
100*b1cdbd2cSJim Jagielski //  fprintf(stderr,"### Hash: %lu , Name: %s\n",nIndex,s );
101*b1cdbd2cSJim Jagielski 
102*b1cdbd2cSJim Jagielski     nLoop = 0;                                      // divide to range
103*b1cdbd2cSJim Jagielski     while( (nMax != nLoop) && IsEntry( nIndex ) )
104*b1cdbd2cSJim Jagielski     {                     // is place occupied
105*b1cdbd2cSJim Jagielski         if( COMPARE_EQUAL == Compare( pElement, nIndex ) )
106*b1cdbd2cSJim Jagielski         {
107*b1cdbd2cSJim Jagielski             if( pInsertPos )
108*b1cdbd2cSJim Jagielski                 *pInsertPos = nIndex;               // place of Element
109*b1cdbd2cSJim Jagielski             return sal_True;
110*b1cdbd2cSJim Jagielski         }
111*b1cdbd2cSJim Jagielski         nLoop++;
112*b1cdbd2cSJim Jagielski         lTry++;
113*b1cdbd2cSJim Jagielski         nIndex = (sal_uInt16)(nIndex + nHash + 7) % nMax;
114*b1cdbd2cSJim Jagielski     }
115*b1cdbd2cSJim Jagielski 
116*b1cdbd2cSJim Jagielski     if( bInsert )
117*b1cdbd2cSJim Jagielski     {
118*b1cdbd2cSJim Jagielski         DBG_ASSERT( nMax != nLoop, "Hash table full" );
119*b1cdbd2cSJim Jagielski 		if( nMax != nLoop )
120*b1cdbd2cSJim Jagielski 		{
121*b1cdbd2cSJim Jagielski 	        nFill++;
122*b1cdbd2cSJim Jagielski 	        *pInsertPos = nIndex;                       // return free place
123*b1cdbd2cSJim Jagielski 	        return sal_True;
124*b1cdbd2cSJim Jagielski 		}
125*b1cdbd2cSJim Jagielski     }
126*b1cdbd2cSJim Jagielski     return( sal_False );
127*b1cdbd2cSJim Jagielski }
128*b1cdbd2cSJim Jagielski 
129*b1cdbd2cSJim Jagielski /************************************************************************/
130*b1cdbd2cSJim Jagielski /*************************************************************************
131*b1cdbd2cSJim Jagielski |*
132*b1cdbd2cSJim Jagielski |*    SvStringHashTable::SvStringHashTable()
133*b1cdbd2cSJim Jagielski |*
134*b1cdbd2cSJim Jagielski |*    Beschreibung
135*b1cdbd2cSJim Jagielski |*
136*b1cdbd2cSJim Jagielski *************************************************************************/
SvStringHashTable(sal_uInt32 nMaxEntries)137*b1cdbd2cSJim Jagielski SvStringHashTable::SvStringHashTable( sal_uInt32 nMaxEntries )
138*b1cdbd2cSJim Jagielski         : SvHashTable( nMaxEntries )
139*b1cdbd2cSJim Jagielski {
140*b1cdbd2cSJim Jagielski     pEntries = new SvStringHashEntry[ nMaxEntries ];
141*b1cdbd2cSJim Jagielski 
142*b1cdbd2cSJim Jagielski     // RefCount auf eins setzen
143*b1cdbd2cSJim Jagielski     SvStringHashEntry * pPos, *pEnd;
144*b1cdbd2cSJim Jagielski     pPos    = pEntries;
145*b1cdbd2cSJim Jagielski     pEnd    = pEntries + nMaxEntries;
146*b1cdbd2cSJim Jagielski     while( pPos != pEnd )
147*b1cdbd2cSJim Jagielski     {
148*b1cdbd2cSJim Jagielski         pPos->AddRef();
149*b1cdbd2cSJim Jagielski         pPos++;
150*b1cdbd2cSJim Jagielski     }
151*b1cdbd2cSJim Jagielski }
152*b1cdbd2cSJim Jagielski 
153*b1cdbd2cSJim Jagielski /*************************************************************************
154*b1cdbd2cSJim Jagielski |*
155*b1cdbd2cSJim Jagielski |*    ~SvStringHashTable::SvStringHashTable()
156*b1cdbd2cSJim Jagielski |*
157*b1cdbd2cSJim Jagielski |*    Beschreibung
158*b1cdbd2cSJim Jagielski |*
159*b1cdbd2cSJim Jagielski *************************************************************************/
~SvStringHashTable()160*b1cdbd2cSJim Jagielski SvStringHashTable::~SvStringHashTable()
161*b1cdbd2cSJim Jagielski {
162*b1cdbd2cSJim Jagielski     // RefCount auf eins setzen
163*b1cdbd2cSJim Jagielski     SvStringHashEntry * pPos, *pEnd;
164*b1cdbd2cSJim Jagielski     pPos    = pEntries;
165*b1cdbd2cSJim Jagielski     pEnd    = pEntries + GetMax();
166*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
167*b1cdbd2cSJim Jagielski     while( pPos != pEnd )
168*b1cdbd2cSJim Jagielski     {
169*b1cdbd2cSJim Jagielski         DBG_ASSERT( pPos->GetRefCount() == 1, "Reference count != 1" );
170*b1cdbd2cSJim Jagielski         pPos++;
171*b1cdbd2cSJim Jagielski     }
172*b1cdbd2cSJim Jagielski #endif
173*b1cdbd2cSJim Jagielski 
174*b1cdbd2cSJim Jagielski #ifdef MPW
175*b1cdbd2cSJim Jagielski     // der MPW-Compiler ruft sonst keine Dtoren!
176*b1cdbd2cSJim Jagielski     for ( sal_uInt16 n = 0; n < GetMax(); ++n )
177*b1cdbd2cSJim Jagielski         (pEntries+n)->SvStringHashEntry::~SvStringHashEntry();
178*b1cdbd2cSJim Jagielski     delete (void*) pEntries;
179*b1cdbd2cSJim Jagielski #else
180*b1cdbd2cSJim Jagielski     delete [] pEntries;
181*b1cdbd2cSJim Jagielski #endif
182*b1cdbd2cSJim Jagielski }
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski /*************************************************************************
185*b1cdbd2cSJim Jagielski |*
186*b1cdbd2cSJim Jagielski |*    SvStringHashTable::HashFunc()
187*b1cdbd2cSJim Jagielski |*
188*b1cdbd2cSJim Jagielski |*    Beschreibung
189*b1cdbd2cSJim Jagielski |*
190*b1cdbd2cSJim Jagielski *************************************************************************/
HashFunc(const void * pElement) const191*b1cdbd2cSJim Jagielski sal_uInt32 SvStringHashTable::HashFunc( const void * pElement ) const
192*b1cdbd2cSJim Jagielski {
193*b1cdbd2cSJim Jagielski     sal_uInt32          nHash = 0;  // hash value
194*b1cdbd2cSJim Jagielski     const char *    pStr = ((const ByteString * )pElement)->GetBuffer();
195*b1cdbd2cSJim Jagielski 
196*b1cdbd2cSJim Jagielski     int nShift = 0;
197*b1cdbd2cSJim Jagielski     while( *pStr )
198*b1cdbd2cSJim Jagielski     {
199*b1cdbd2cSJim Jagielski         if( isupper( *pStr ) )
200*b1cdbd2cSJim Jagielski             nHash ^= sal_uInt32(*pStr - 'A' + 26) << nShift;
201*b1cdbd2cSJim Jagielski         else
202*b1cdbd2cSJim Jagielski             nHash ^= sal_uInt32(*pStr - 'a') << nShift;
203*b1cdbd2cSJim Jagielski         if( nShift == 28 )
204*b1cdbd2cSJim Jagielski             nShift = 0;
205*b1cdbd2cSJim Jagielski         else
206*b1cdbd2cSJim Jagielski             nShift += 4;
207*b1cdbd2cSJim Jagielski         pStr++;
208*b1cdbd2cSJim Jagielski     }
209*b1cdbd2cSJim Jagielski     return( nHash );
210*b1cdbd2cSJim Jagielski }
211*b1cdbd2cSJim Jagielski 
212*b1cdbd2cSJim Jagielski /*************************************************************************
213*b1cdbd2cSJim Jagielski |*
214*b1cdbd2cSJim Jagielski |*    SvStringHashTable::GetNearString()
215*b1cdbd2cSJim Jagielski |*
216*b1cdbd2cSJim Jagielski |*    Beschreibung
217*b1cdbd2cSJim Jagielski |*
218*b1cdbd2cSJim Jagielski *************************************************************************/
GetNearString(const ByteString & rName) const219*b1cdbd2cSJim Jagielski ByteString SvStringHashTable::GetNearString( const ByteString & rName ) const
220*b1cdbd2cSJim Jagielski {
221*b1cdbd2cSJim Jagielski     for( sal_uInt32 i = 0; i < GetMax(); i++ )
222*b1cdbd2cSJim Jagielski     {
223*b1cdbd2cSJim Jagielski         SvStringHashEntry * pE = Get( i );
224*b1cdbd2cSJim Jagielski         if( pE )
225*b1cdbd2cSJim Jagielski         {
226*b1cdbd2cSJim Jagielski             if( pE->GetName().EqualsIgnoreCaseAscii( rName ) && !pE->GetName().Equals( rName ) )
227*b1cdbd2cSJim Jagielski                 return pE->GetName();
228*b1cdbd2cSJim Jagielski         }
229*b1cdbd2cSJim Jagielski     }
230*b1cdbd2cSJim Jagielski     return ByteString();
231*b1cdbd2cSJim Jagielski }
232*b1cdbd2cSJim Jagielski 
233*b1cdbd2cSJim Jagielski /*************************************************************************
234*b1cdbd2cSJim Jagielski |*
235*b1cdbd2cSJim Jagielski |*    SvStringHashTable::IsEntry()
236*b1cdbd2cSJim Jagielski |*
237*b1cdbd2cSJim Jagielski |*    Beschreibung
238*b1cdbd2cSJim Jagielski |*
239*b1cdbd2cSJim Jagielski *************************************************************************/
IsEntry(sal_uInt32 nIndex) const240*b1cdbd2cSJim Jagielski sal_Bool SvStringHashTable::IsEntry( sal_uInt32 nIndex ) const
241*b1cdbd2cSJim Jagielski {
242*b1cdbd2cSJim Jagielski     if( nIndex >= GetMax() )
243*b1cdbd2cSJim Jagielski         return sal_False;
244*b1cdbd2cSJim Jagielski     return pEntries[ nIndex ].HasId();
245*b1cdbd2cSJim Jagielski }
246*b1cdbd2cSJim Jagielski 
247*b1cdbd2cSJim Jagielski /*************************************************************************
248*b1cdbd2cSJim Jagielski |*
249*b1cdbd2cSJim Jagielski |*    SvStringHashTable::Insert()
250*b1cdbd2cSJim Jagielski |*
251*b1cdbd2cSJim Jagielski |*    Beschreibung
252*b1cdbd2cSJim Jagielski |*
253*b1cdbd2cSJim Jagielski *************************************************************************/
Insert(const ByteString & rName,sal_uInt32 * pIndex)254*b1cdbd2cSJim Jagielski sal_Bool SvStringHashTable::Insert( const ByteString & rName, sal_uInt32 * pIndex )
255*b1cdbd2cSJim Jagielski {
256*b1cdbd2cSJim Jagielski     sal_uInt32 nIndex;
257*b1cdbd2cSJim Jagielski 
258*b1cdbd2cSJim Jagielski     if( !pIndex ) pIndex = &nIndex;
259*b1cdbd2cSJim Jagielski 
260*b1cdbd2cSJim Jagielski     if( !SvHashTable::Test_Insert( &rName, sal_True, pIndex ) )
261*b1cdbd2cSJim Jagielski         return sal_False;
262*b1cdbd2cSJim Jagielski 
263*b1cdbd2cSJim Jagielski     if( !IsEntry( *pIndex ) )
264*b1cdbd2cSJim Jagielski         pEntries[ *pIndex ] = SvStringHashEntry( rName, *pIndex );
265*b1cdbd2cSJim Jagielski     return sal_True;
266*b1cdbd2cSJim Jagielski }
267*b1cdbd2cSJim Jagielski 
268*b1cdbd2cSJim Jagielski /*************************************************************************
269*b1cdbd2cSJim Jagielski |*
270*b1cdbd2cSJim Jagielski |*    SvStringHashTable::Test()
271*b1cdbd2cSJim Jagielski |*
272*b1cdbd2cSJim Jagielski |*    Beschreibung
273*b1cdbd2cSJim Jagielski |*
274*b1cdbd2cSJim Jagielski *************************************************************************/
Test(const ByteString & rName,sal_uInt32 * pPos) const275*b1cdbd2cSJim Jagielski sal_Bool SvStringHashTable::Test( const ByteString & rName, sal_uInt32 * pPos ) const
276*b1cdbd2cSJim Jagielski {
277*b1cdbd2cSJim Jagielski     return ((SvStringHashTable *)this)->SvHashTable::
278*b1cdbd2cSJim Jagielski                 Test_Insert( &rName, sal_False, pPos );
279*b1cdbd2cSJim Jagielski }
280*b1cdbd2cSJim Jagielski 
281*b1cdbd2cSJim Jagielski /*************************************************************************
282*b1cdbd2cSJim Jagielski |*
283*b1cdbd2cSJim Jagielski |*    SvStringHashTable::Get()
284*b1cdbd2cSJim Jagielski |*
285*b1cdbd2cSJim Jagielski |*    Beschreibung
286*b1cdbd2cSJim Jagielski |*
287*b1cdbd2cSJim Jagielski *************************************************************************/
Get(sal_uInt32 nIndex) const288*b1cdbd2cSJim Jagielski SvStringHashEntry * SvStringHashTable::Get( sal_uInt32 nIndex ) const
289*b1cdbd2cSJim Jagielski {
290*b1cdbd2cSJim Jagielski     if( IsEntry( nIndex ) )
291*b1cdbd2cSJim Jagielski         return pEntries + nIndex;
292*b1cdbd2cSJim Jagielski     return( NULL );
293*b1cdbd2cSJim Jagielski }
294*b1cdbd2cSJim Jagielski 
295*b1cdbd2cSJim Jagielski /*************************************************************************
296*b1cdbd2cSJim Jagielski |*
297*b1cdbd2cSJim Jagielski |*    SvStringHashTable::Get()
298*b1cdbd2cSJim Jagielski |*
299*b1cdbd2cSJim Jagielski |*    Beschreibung
300*b1cdbd2cSJim Jagielski |*
301*b1cdbd2cSJim Jagielski *************************************************************************/
Compare(const void * pElement,sal_uInt32 nIndex) const302*b1cdbd2cSJim Jagielski StringCompare SvStringHashTable::Compare( const void * pElement,
303*b1cdbd2cSJim Jagielski                                           sal_uInt32 nIndex ) const
304*b1cdbd2cSJim Jagielski {
305*b1cdbd2cSJim Jagielski     return ((const ByteString *)pElement)->CompareTo( pEntries[ nIndex ].GetName() );
306*b1cdbd2cSJim Jagielski }
307*b1cdbd2cSJim Jagielski 
308*b1cdbd2cSJim Jagielski /*************************************************************************
309*b1cdbd2cSJim Jagielski |*
310*b1cdbd2cSJim Jagielski |*    SvStringHashTable::FillHashList()
311*b1cdbd2cSJim Jagielski |*
312*b1cdbd2cSJim Jagielski |*    Beschreibung
313*b1cdbd2cSJim Jagielski |*
314*b1cdbd2cSJim Jagielski *************************************************************************/
FillHashList(SvStringHashList * pList) const315*b1cdbd2cSJim Jagielski void SvStringHashTable::FillHashList( SvStringHashList * pList ) const
316*b1cdbd2cSJim Jagielski {
317*b1cdbd2cSJim Jagielski     for( sal_uInt32 n = 0; n < GetMax(); n++ )
318*b1cdbd2cSJim Jagielski     {
319*b1cdbd2cSJim Jagielski         if( IsEntry( n ) )
320*b1cdbd2cSJim Jagielski             pList->Insert( Get( n ), LIST_APPEND );
321*b1cdbd2cSJim Jagielski     }
322*b1cdbd2cSJim Jagielski     // Hash Reihenfolge, jetzt sortieren
323*b1cdbd2cSJim Jagielski }
324