const CQueryHashTable* CLibraryDictionary::GetHashTable() { ASSUME_LOCK( Library.m_pSection ); BuildHashTable(); return m_pTable; }
// //########################################################################### // Hash //########################################################################### // Hash::Hash( CollectionSize size, Node *node, bool has_unique_entries ): SortedSocket(node, has_unique_entries) { hashTableSize = size; // // If the size is not prime, warn and select new size // Warn(!CheckForPrimeSize()); if (!CheckForPrimeSize()) { while (!CheckForPrimeSize()) { hashTableSize++; } STOP(("Correct hashTableSize=%d", hashTableSize)); } BuildHashTable(); }
CFileList* CLibraryDictionary::Search(const CQuerySearch* pSearch, const int nMaximum, const bool bLocal, const bool bAvailableOnly) { ASSUME_LOCK( Library.m_pSection ); if ( ! m_bValid ) { BuildHashTable(); if ( ! m_bValid ) return NULL; } // Only check the hash when a search comes from other client. if ( ! bLocal && ! m_pTable->Check( pSearch ) ) return NULL; ++m_nSearchCookie; CLibraryFile* pHit = NULL; CQuerySearch::const_iterator pWordEntry = pSearch->begin(); const CQuerySearch::const_iterator pLastWordEntry = pSearch->end(); for ( ; pWordEntry != pLastWordEntry; ++pWordEntry ) { if ( pWordEntry->first[ 0 ] == L'-' ) continue; CString strWord( pWordEntry->first, static_cast< int >( pWordEntry->second ) ); CFileList* pList = NULL; if ( m_oWordMap.Lookup( strWord, pList ) ) { for ( POSITION pos = pList->GetHeadPosition(); pos; ) { CLibraryFile* pFile = pList->GetNext( pos ); if ( bAvailableOnly && ! pFile->IsAvailable() ) continue; if ( ! bLocal && ! pFile->IsShared() ) continue; if ( pFile->m_nSearchCookie == m_nSearchCookie ) { ++pFile->m_nSearchWords; } else { pFile->m_nSearchCookie = m_nSearchCookie; pFile->m_nSearchWords = 1; pFile->m_pNextHit = pHit; pHit = pFile; } } } } size_t nLowerBound = ( pSearch->tableSize() >= 3 ) ? ( pSearch->tableSize() * 2 / 3 ) : pSearch->tableSize(); CFileList* pHits = NULL; for ( ; pHit; pHit = pHit->m_pNextHit ) { ASSERT( pHit->m_nSearchCookie == m_nSearchCookie ); if ( pHit->m_nSearchWords < nLowerBound ) continue; if ( pSearch->Match( pHit->GetSearchName(), pHit->m_pSchema ? (LPCTSTR)pHit->m_pSchema->GetURI() : NULL, pHit->m_pMetadata, pHit ) ) { if ( ! pHits ) pHits = new CFileList; pHits->AddTail( pHit ); if ( ! bLocal ) { pHit->m_nHitsToday ++; pHit->m_nHitsTotal ++; } if ( pHit->m_nCollIndex ) { CLibraryFile* pCollection = LibraryMaps.LookupFile( pHit->m_nCollIndex, ! bLocal, bAvailableOnly ); if ( pCollection ) { if ( pCollection->m_nSearchCookie != m_nSearchCookie ) { pCollection->m_nSearchCookie = m_nSearchCookie; pHits->AddHead( pCollection ); } } else { // Collection removed without deleting indexes pHit->m_nCollIndex = 0ul; } } if ( nMaximum > 0 && pHits->GetCount() >= nMaximum ) break; } } return pHits; }