//----------------------------------------------------------------------------- // Hash the string to the bucket index where it belongs. //----------------------------------------------------------------------------- static inline int EntityBucketForName( const char *pszName ) { if ( !pszName ) return 0; unsigned int nHash = HashStringCaseless( pszName ); return nHash % NUM_HASHED_ENTITY_BUCKETS; }
void CCountedStringPool::DereferenceString( const char* pIntrinsic ) { // If we get a NULL pointer, just return if(!pIntrinsic) return; unsigned short nHashBucketIndex = (HashStringCaseless( pIntrinsic ) % m_HashTable.Count()); unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ]; // If there isn't anything in the bucket, just return. if( nCurrentBucket == INVALID_ELEMENT ) return; for( unsigned short previous = INVALID_ELEMENT; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement ) { if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) ) { // Anyone who hits 65k references is permanant if( m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE ) { m_Elements[nCurrentBucket].nReferenceCount --; } if( m_Elements[nCurrentBucket].nReferenceCount == 0 ) { if( previous == INVALID_ELEMENT ) { m_HashTable[nHashBucketIndex] = m_Elements[nCurrentBucket].nNextElement; } else { m_Elements[previous].nNextElement = m_Elements[nCurrentBucket].nNextElement; } delete [] m_Elements[nCurrentBucket].pString; m_Elements[nCurrentBucket].pString = NULL; m_Elements[nCurrentBucket].nReferenceCount = 0; m_Elements[nCurrentBucket].nNextElement = m_FreeListStart; m_FreeListStart = nCurrentBucket; break; } } previous = nCurrentBucket; } }
unsigned short CCountedStringPool::ReferenceStringHandle( const char* pIntrinsic ) { if( pIntrinsic == NULL ) return INVALID_ELEMENT; unsigned short nHashBucketIndex = (HashStringCaseless( pIntrinsic ) % HASH_TABLE_SIZE); unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ]; // Does the bucket already exist? if( nCurrentBucket != INVALID_ELEMENT ) { for( ; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement ) { if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) ) { // Anyone who hits 65k references is permanant if( m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE ) { m_Elements[nCurrentBucket].nReferenceCount ++ ; } return nCurrentBucket; } } } if( m_FreeListStart != INVALID_ELEMENT ) { nCurrentBucket = m_FreeListStart; m_FreeListStart = m_Elements[nCurrentBucket].nNextElement; } else { nCurrentBucket = m_Elements.AddToTail(); } m_Elements[nCurrentBucket].nReferenceCount = 1; // Insert at the beginning of the bucket: m_Elements[nCurrentBucket].nNextElement = m_HashTable[ nHashBucketIndex ]; m_HashTable[ nHashBucketIndex ] = nCurrentBucket; m_Elements[nCurrentBucket].pString = new char[Q_strlen( pIntrinsic ) + 1]; Q_strcpy( m_Elements[nCurrentBucket].pString, pIntrinsic ); return nCurrentBucket; }
unsigned short CCountedStringPool::FindStringHandle( const char* pIntrinsic ) { if( pIntrinsic == NULL ) return INVALID_ELEMENT; unsigned short nHashBucketIndex = (HashStringCaseless(pIntrinsic ) %HASH_TABLE_SIZE); unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ]; // Does the bucket already exist? if( nCurrentBucket != INVALID_ELEMENT ) { for( ; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement ) { if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) ) { return nCurrentBucket; } } } return 0; }