00001
00002
00003 #include <string.h>
00004 #include "ghash.h"
00005
00006
00007
00008
00009
00010 gKey::gKey (eKeyKind aKeyKind)
00011 : keyKind( aKeyKind ),
00012 pvalUInt( nil ),
00013 pvalDouble( nil )
00014 {
00015 }
00016
00017 gKey::gKey (int v)
00018 : gInt( v ),
00019 pvalUInt( nil ),
00020 pvalDouble( nil )
00021 {
00022 keyKind = gKey::e_Int;
00023 }
00024
00025 gKey::gKey (gInt& v)
00026 : gInt( v.GetInt() ),
00027 pvalUInt( nil ),
00028 pvalDouble( nil )
00029 {
00030 keyKind = gKey::e_Int;
00031 }
00032
00033 gKey::gKey (gString& s)
00034 : gInt( -1 ),
00035 pvalUInt( nil ),
00036 pvalDouble( nil ),
00037 pvalStr( s )
00038 {
00039 keyKind = gKey::e_String;
00040 }
00041
00042 gKey::gKey (char* s)
00043 : gInt( -1 ),
00044 pvalUInt( nil ),
00045 pvalDouble( nil )
00046 {
00047 pvalStr.Set( s );
00048 keyKind = gKey::e_String;
00049 }
00050
00051 gKey::~gKey ()
00052 {
00053 delete pvalUInt;
00054 delete pvalDouble;
00055 }
00056
00057 bool gKey::IsOk ()
00058 {
00059 return true;
00060 }
00061
00062 t_uint64 gKey::GetUInt64 ()
00063 {
00064 ASSERTION(pvalUInt!=nil,"pvalUInt!=nil");
00065 return *pvalUInt;
00066 }
00067
00068 double gKey::GetReal ()
00069 {
00070 ASSERTION(pvalDouble!=nil,"pvalDouble!=nil");
00071 return *pvalDouble;
00072 }
00073
00074 gString& gKey::GetString ()
00075 {
00076 ASSERTION(pvalUInt==nil,"pvalUInt==nil");
00077 ASSERTION(pvalDouble==nil,"pvalDouble==nil");
00078 ASSERTION(GetInt()<=0,"GetInt()<=0");
00079 ASSERTION(keyKind==gKey::e_String,"keyKind=e_String");
00080 return pvalStr;
00081 }
00082
00083 unsigned gKey::HashPos (unsigned hashSize)
00084 {
00085 #ifdef DEBUG_HASH
00086 return 1;
00087 #else
00088 unsigned uTemp;
00089 double dTemp;
00090
00091 switch ( keyKind ) {
00092 case gKey::e_Int:
00093 return (unsigned)GetInt()%hashSize;
00094 case gKey::e_UInt64:
00095 return (unsigned)(*pvalUInt)%hashSize;
00096 case gKey::e_Real:
00097 dTemp = *pvalDouble;
00098 uTemp = dTemp > (double)MAX_LONG_L ? (unsigned)(dTemp/214748364.0) : (unsigned)(dTemp*101.0);
00099 return uTemp%hashSize;
00100 case gKey::e_String:
00101 return HashStrPos( hashSize, pvalStr );
00102 default:
00103 ASSERTION_FALSE("HashPos(1)");
00104 }
00105 return 0;
00106 #endif //DEBUG_HASH
00107 }
00108
00109 bool gKey::MatchKey (gKey& hKey)
00110 {
00111 ;
00112 if ( keyKind!=hKey.GetKeyKind() ) return false;
00113 if ( hKey.IsOk()==false ) return false;
00114 switch ( keyKind ) {
00115 case gKey::e_Int:
00116 return GetInt()==hKey.GetInt();
00117 case gKey::e_UInt64:
00118 return GetUInt64()==hKey.GetUInt64();
00119 case gKey::e_Real:
00120 return GetReal()==hKey.GetReal();
00121 case gKey::e_String:
00122 return GetString().Match( hKey.GetString() );
00123 default:
00124 ASSERTION_FALSE("MatchKey(1)");
00125 }
00126 return false;
00127 }
00128
00129 bool gKey::MatchStorage (gStorage* aObj)
00130 {
00131 gHashElemGeneric* pHashElem;
00132 ASSERTION(aObj!=nil,"aObj!=nil");
00133 ASSERTION(aObj->Kind()==e_Control,"aObj->Kind()==e_Control");
00134 pHashElem = (gHashElemGeneric*)aObj;
00135 return MatchKey( pHashElem->hKey );
00136 }
00137
00138 void gKey::Reset ()
00139 {
00140 gInt::Reset();
00141 if ( pvalUInt!=nil ) *pvalUInt = 0;
00142 if ( pvalDouble!=nil ) *pvalDouble = 0.0;
00143 pvalStr.SetEmpty();
00144 }
00145
00146 void gKey::Set (int v)
00147 {
00148 thisNewKind( gKey::e_Int );
00149 SetInt( v );
00150 }
00151
00152 void gKey::Set (t_uint64 v)
00153 {
00154 thisNewKind( gKey::e_UInt64 );
00155 ASSERTION(pvalUInt!=nil,"pvalUInt!=nil");
00156 *pvalUInt = v;
00157 }
00158
00159 void gKey::Set (double v)
00160 {
00161 thisNewKind( gKey::e_Real );
00162 ASSERTION(pvalDouble!=nil,"pvalDouble!=nil");
00163 *pvalDouble = v;
00164 }
00165
00166 void gKey::Set (gString& s)
00167 {
00168 thisNewKind( gKey::e_String );
00169 pvalStr = s;
00170 }
00171
00172 void gKey::Copy (gKey& copy)
00173 {
00174 eKeyKind newKind = copy.GetKeyKind();
00175 switch ( newKind ) {
00176 case gKey::e_Int:
00177 Set( copy.GetInt() );
00178 break;
00179 case gKey::e_UInt64:
00180 Set( copy.GetUInt64() );
00181 break;
00182 case gKey::e_Real:
00183 Set( copy.GetReal() );
00184 break;
00185 case gKey::e_String:
00186 Set( copy.GetString() );
00187 break;
00188 default:
00189 ASSERTION_FALSE("gKey::Copy(1)");
00190 }
00191 ASSERTION(keyKind==newKind,"gKey::Copy(2)");
00192 }
00193
00194 unsigned gKey::HashStrPos (unsigned hashSize, gString& s)
00195 {
00196 unsigned i, n, uTemp=0, uMark;
00197 t_uchar uChr;
00198
00199
00200 if ( hashSize==7591 && s.Match("FORM") ) return 1519;
00201 for (i=1, n=s.Length(); i<=n; i++) {
00202 uChr = s[i];
00203 uMark = uChr>='a' && uChr<='z' ? (unsigned)uChr-32 : (unsigned)uChr;
00204 uMark -= 65;
00205 if ( i==1 ) uMark *= hashSize / 26;
00206 uTemp += uMark+i*2+(uChr>='Y');
00207 }
00208
00209 return uTemp%hashSize;
00210 }
00211
00212 gStorage* gKey::NewObject ()
00213 {
00214 ASSERTION_FALSE("gKey::NewObject");
00215 return nil;
00216 }
00217
00218 t_uchar* gKey::ToString (t_uchar* uBuf)
00219 {
00220 char* sBuf;
00221 if ( uBuf==nil ) return nil;
00222 sBuf = (char*)uBuf;
00223 switch ( keyKind ) {
00224 case gKey::e_Int:
00225 sprintf(sBuf,"%d",GetInt());
00226 break;
00227 case gKey::e_UInt64:
00228 sprintf(sBuf,"%lx",(long)GetUInt64());
00229 break;
00230 case gKey::e_Real:
00231 sprintf(sBuf,"%f",(float)GetReal());
00232 break;
00233 case gKey::e_String:
00234 sprintf(sBuf,"%s",GetString().Str());
00235 break;
00236 default:
00237 ASSERTION_FALSE("gKey::ToString");
00238 }
00239 return (t_uchar*)sBuf;
00240 }
00241
00242 void gKey::Show (bool doShowAll)
00243 {
00244 t_uchar uBuf[50];
00245 printf("%s",ToString(uBuf));
00246 }
00247
00248 void gKey::thisNewKind (eKeyKind newKind)
00249 {
00250 Reset();
00251 delete pvalUInt;
00252 pvalUInt = nil;
00253 delete pvalDouble;
00254 pvalDouble = nil;
00255 switch ( keyKind = newKind ) {
00256 case gKey::e_Int:
00257 break;
00258 case gKey::e_UInt64:
00259 pvalUInt = new t_uint64;
00260 break;
00261 case gKey::e_Real:
00262 pvalDouble = new double;
00263 break;
00264 case gKey::e_String:
00265 break;
00266 default:
00267 ASSERTION_FALSE("thisNewKind");
00268 };
00269 }
00270
00271 gHashElemGeneric::gHashElemGeneric (gStorage* aObj)
00272 : myObj( aObj )
00273 {
00274 }
00275
00276 gHashElemGeneric::~gHashElemGeneric ()
00277 {
00278
00279 }
00280
00281 gHashElemTriple::gHashElemTriple (gKey& aKey, gString& s, gStorage* aObj)
00282 : gHashElemGeneric( aObj ),
00283 sDesc( s ),
00284 iVal( 0 )
00285 {
00286 hKey.Copy( aKey );
00287 }
00288
00289 gHashElemTriple::gHashElemTriple (gKey& aKey, int aVal, gStorage* aObj)
00290 : gHashElemGeneric( aObj ),
00291 iVal( aVal )
00292 {
00293 hKey.Copy( aKey );
00294 }
00295
00296 gHashElemTriple::~gHashElemTriple ()
00297 {
00298 }
00299
00300 void gHashElemTriple::Show (bool doShowAll)
00301 {
00302 hKey.Show( doShowAll );
00303 if ( doShowAll ) {
00304 printf("{%s",sDesc.Str());
00305
00306
00307
00308
00309
00310
00311
00312 printf("}");
00313 }
00314 }
00315
00316
00317
00318 gHashGeneric::gHashGeneric (eStorage aKind, unsigned hashSize)
00319 : gStorage( aKind, e_StgDefault ),
00320 size( 0 ),
00321 pLst( nil ),
00322 usageCounter( 0 )
00323 {
00324 thisPreAllocate( hashSize );
00325 }
00326
00327 gHashGeneric::~gHashGeneric ()
00328 {
00329 thisDelete();
00330 }
00331
00332 bool gHashGeneric::IsValidIndex (unsigned idx)
00333 {
00334 return idx<size;
00335 }
00336
00337 gList* gHashGeneric::GetHash (unsigned idx)
00338 {
00339 ASSERTION(pLst!=nil,"pLst!=nil");
00340 ASSERTION(IsValidIndex(idx),"GetHash(1)");
00341 return &pLst[idx];
00342 }
00343
00344 unsigned gHashGeneric::Delete ()
00345 {
00346 thisDelete();
00347 thisPreAllocate( size );
00348 return size;
00349 }
00350
00351 gStorage* gHashGeneric::NewObject ()
00352 {
00353 ASSERTION_FALSE("gHashGeneric::NewObject: Not used");
00354 return nil;
00355 }
00356
00357 t_uchar* gHashGeneric::ToString (t_uchar* uBuf)
00358 {
00359 ;
00360
00361
00362
00363
00364
00365
00366 ;
00367 return nil;
00368 }
00369
00370 bool gHashGeneric::SaveGuts (FILE* f)
00371 {
00372 return CanSave( f );
00373 }
00374
00375 bool gHashGeneric::RestoreGuts (FILE* f)
00376 {
00377 return CanRestore( f );
00378 }
00379
00380 void gHashGeneric::thisPreAllocate (unsigned toSize)
00381 {
00382 ASSERTION(toSize>=LST_HASH_SIZE_MIN,"toSize>=101");
00383 ASSERTION(pLst==nil,"pLst==nil");
00384 pLst = new gList[ size = toSize ];
00385 ASSERTION(pLst!=nil,"pLst!=nil");
00386 }
00387
00388 unsigned gHashGeneric::thisDelete ()
00389 {
00390 ASSERTION(pLst!=nil,"pLst!=nil");
00391 delete[] pLst;
00392 pLst = nil;
00393 return size;
00394 }
00395
00396 gHash::gHash (unsigned hashSize)
00397 : gHashGeneric( e_List, hashSize ),
00398 doFindBeforeInsert( false )
00399 {
00400 }
00401
00402 gHash::~gHash ()
00403 {
00404 }
00405
00406 bool gHash::FindKey (gKey& hKey)
00407 {
00408 int x;
00409 int hashPos = thisFindKey( hKey, x );
00410 return hashPos>=0;
00411 }
00412
00413 unsigned gHash::Add (int v)
00414 {
00415 gInt aVal( v );
00416 return Add( aVal );
00417 }
00418
00419 unsigned gHash::Add (gInt& v)
00420 {
00421 gString sEmpty;
00422 return Add( v, sEmpty );
00423 }
00424
00425 unsigned gHash::Add (gInt& v, gString& s)
00426 {
00427 gKey hKey( v );
00428 return Add( hKey, s );
00429 }
00430
00431 unsigned gHash::Add (gKey& hKey, gString& s)
00432 {
00433 if ( doFindBeforeInsert ) {
00434 if ( FindKey( hKey ) ) return 0;
00435 }
00436 gHashElemTriple* pElem = new gHashElemTriple( hKey, s, nil );
00437 ASSERTION(pElem!=nil,"pElem!=nil");
00438 thisAddElem( hKey.HashPos(size), pElem );
00439 return 0;
00440 }
00441
00442 t_uchar* gHash::ToString (t_uchar* uBuf)
00443 {
00444 return gHashGeneric::ToString( uBuf );
00445 }
00446
00447 bool gHash::SaveGuts (FILE* f)
00448 {
00449 return gHashGeneric::SaveGuts( f );
00450 }
00451
00452 bool gHash::RestoreGuts (FILE* f)
00453 {
00454 return gHashGeneric::RestoreGuts( f );
00455 }
00456
00457 void gHash::Show (bool doShowAll)
00458 {
00459 unsigned idx, k, n;
00460 unsigned count=0;
00461 gList* pRow;
00462 for (idx=0; idx<size; idx++) {
00463 pRow = GetHash( idx );
00464 n = pRow->N();
00465 if ( n==0 ) {
00466 ;
00467 }
00468 else {
00469 printf("%s%u:",count==0?"\0":" ",idx);
00470 count++;
00471 for (k=1; k<=n; k++) {
00472 gStorage* aObj = pRow->GetObjectPtr(k);
00473 ASSERTION(aObj!=nil,"aObj!=nil");
00474 aObj->Show( doShowAll );
00475 }
00476 }
00477 }
00478 if ( doShowAll ) printf("\n");
00479 }
00480
00481 int gHash::thisAddElem (unsigned idx, gHashElemGeneric* pElem)
00482 {
00483 gList* pRow = GetHash( idx );
00484 bool mustBeOk = pRow->AppendObject( pElem );
00485 ASSERTION(mustBeOk,"thisAddElem(1)");
00486 thisInsertElement();
00487 return 0;
00488 }
00489
00490 int gHash::thisFindKey (gKey& hKey, int& x)
00491 {
00492 unsigned idx = hKey.HashPos( size );
00493 gList* pRow = GetHash( idx );
00494 int n = (int)pRow->N();
00495 for (x=1; x<=n; x++) {
00496 if ( thisKeyMatch( hKey, pRow->GetObjectPtr(x) )==1 )
00497 return (int)idx;
00498 }
00499
00500 x = 0;
00501 return -1;
00502 }
00503
00504 int gHash::thisKeyMatch (gKey& hKey, gStorage* hashElem)
00505 {
00506
00507 return (int)hKey.MatchStorage( hashElem );
00508 }
00509
00510 #ifdef DEBUG_HASH
00511 bool gHash::AddTriplePos_dbg (unsigned idx, gKey& hKey, char* str)
00512 {
00513 gString s( str );
00514 gHashElemTriple* pElem = new gHashElemTriple( hKey, s, nil );
00515 thisAddElem( idx, pElem );
00516 return pElem!=nil;
00517 }
00518 #endif //DEBUG_HASH
00519
00520 gHashTriple::gHashTriple (unsigned hashSize)
00521 : gHash( hashSize )
00522 {
00523 }
00524
00525 gHashTriple::~gHashTriple ()
00526 {
00527 }
00528
00529 bool gHashTriple::FindKey (gKey& hKey)
00530 {
00531
00532
00533 return gHash::FindKey( hKey );
00534 }
00535
00536 gHashElemTriple* gHashTriple::GetTriple (unsigned idx, int x)
00537 {
00538 gHashElemTriple* aObj;
00539 ASSERTION(x>=1,"x>=1");
00540 aObj = (gHashElemTriple*)GetHash( idx )->GetObjectPtr( (unsigned)x );
00541
00542 return aObj;
00543 }
00544
00545 gHashElemTriple* gHashTriple::Find (gKey& hKey, unsigned& idx, int& x)
00546 {
00547 gHashElemTriple* pElem;
00548 idx = hKey.HashPos( size );
00549 gList* pRow = GetHash( idx );
00550 int n = (int)pRow->N();
00551 for (x=1; x<=n; x++) {
00552 pElem = (gHashElemTriple*)pRow->GetObjectPtr(x);
00553 if ( thisKeyMatch( hKey, pElem )==1 )
00554 return pElem;
00555 }
00556 x = 0;
00557 return nil;
00558 }
00559
00560 bool gHashTriple::AddTriple (gKey& hKey, char* str, gStorage* aObj)
00561 {
00562 gString s( str );
00563 return AddTriple( hKey, s, aObj );
00564 }
00565
00566 bool gHashTriple::AddTriple (gKey& hKey, gString& s, gStorage* aObj)
00567 {
00568 if ( doFindBeforeInsert ) {
00569 if ( FindKey( hKey ) ) return false;
00570 }
00571 gHashElemTriple* pElem = new gHashElemTriple( hKey, s, aObj );
00572 ASSERTION(pElem!=nil,"pElem!=nil");
00573 thisAddElem( hKey.HashPos(size), pElem );
00574 return true;
00575 }
00576
00577 bool gHashTriple::AddTriple (gKey& hKey, int iVal, gStorage* aObj)
00578 {
00579 if ( doFindBeforeInsert ) {
00580 if ( FindKey( hKey ) ) return false;
00581 }
00582 gHashElemTriple* pElem = new gHashElemTriple( hKey, iVal, aObj );
00583 ASSERTION(pElem!=nil,"pElem!=nil");
00584 thisAddElem( hKey.HashPos(size), pElem );
00585 return true;
00586 }
00587
00588