Show
Ignore:
Timestamp:
07/01/08 02:41:30 (5 months ago)
Author:
flynd
Message:

Replaced CUserHashTable with std::map. A custom hash map shouldn't make any significant improvement with the number of items in a normal contact list so better and easier to use a std class instead. Also added some missing mutex locks on the user list.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/licq/src/user.cpp

    r6362 r6363  
    487487//=====CUserManager============================================================= 
    488488CUserManager::CUserManager() 
    489   : m_hUsers(USER_HASH_SIZE), 
    490     m_szDefaultEncoding(NULL) 
     489  : m_szDefaultEncoding(NULL) 
    491490{ 
    492491  // Set up the basic all users and new users group 
     
    657656  ICQUser *u; 
    658657  usersConf.SetFlags(INI_FxWARN); 
     658  LockUserList(LOCK_W); 
    659659  for (unsigned short i = 1; i<= nUsers; i++) 
    660660  { 
     
    680680    u = new ICQUser(szId, nPPID, filename); 
    681681    u->AddToContactList(); 
    682     m_hUsers.Store(u, szId, nPPID); 
     682    myUsers[UserMapKey(szId, nPPID)] = u; 
    683683    m_vpcUsers.push_back(u); 
    684684  } 
     685  UnlockUserList(); 
    685686 
    686687  return true; 
     
    689690void CUserManager::AddUser(ICQUser *pUser, const char *_szId, unsigned long _nPPID) 
    690691{ 
     692  LockUserList(LOCK_W); 
     693 
    691694  pUser->Lock(LOCK_W); 
    692695 
     
    710713  } 
    711714 
    712   // Store the user in the hash table 
    713   m_hUsers.Store(pUser, _szId, _nPPID); 
     715  // Store the user in the lookup map 
     716  myUsers[UserMapKey(_szId, _nPPID)] = pUser; 
    714717  // Reorder the user to the correct place 
    715718  m_vpcUsers.push_back(pUser); 
     719 
     720  UnlockUserList(); 
    716721} 
    717722 
     
    732737    m_vpcUsers.erase(iter); 
    733738  DropUser(u); 
    734   m_hUsers.Remove(_szId, _nPPID); 
     739  myUsers.erase(UserMapKey(_szId, _nPPID)); 
    735740  UnlockUserList(); 
    736741  delete u; 
     
    768773 
    769774  if (u == NULL) 
    770     u = m_hUsers.Retrieve(_szId, _nPPID); 
     775  { 
     776    LockUserList(LOCK_R); 
     777    UserMap::iterator iter = myUsers.find(UserMapKey(_szId, _nPPID)); 
     778    if (iter != myUsers.end()) 
     779      u = iter->second; 
     780    UnlockUserList(); 
     781  } 
    771782 
    772783  if (u != NULL) 
     
    788799bool CUserManager::IsOnList(const char *_szId, unsigned long _nPPID) 
    789800{ 
    790   if (FindOwner(_szId, _nPPID)) return true; 
    791   return m_hUsers.Retrieve(_szId, _nPPID) != NULL; 
     801  if (FindOwner(_szId, _nPPID)) 
     802    return true; 
     803 
     804  LockUserList(LOCK_R); 
     805  UserMap::iterator iter = myUsers.find(UserMapKey(_szId, _nPPID)); 
     806  bool found = (iter != myUsers.end()); 
     807  UnlockUserList(); 
     808 
     809  return found; 
    792810} 
    793811 
     
    16461664  SetString(&m_szDefaultEncoding, defaultEncoding); 
    16471665} 
    1648  
    1649  
    1650 //=====CUserHashTable=========================================================== 
    1651 CUserHashTable::CUserHashTable(unsigned short _nSize) : m_vlTable(_nSize) 
    1652 { 
    1653   pthread_rdwr_init_np(&mutex_rw, NULL); 
    1654   pthread_rdwr_set_name(&mutex_rw, __func__); 
    1655   m_nLockType = LOCK_R; 
    1656 } 
    1657  
    1658 CUserHashTable::~CUserHashTable() 
    1659 { 
    1660   pthread_rdwr_destroy_np(&mutex_rw); 
    1661 } 
    1662  
    1663 ICQUser *CUserHashTable::Retrieve(const char *_szId, unsigned long _nPPID) 
    1664 { 
    1665   Lock(LOCK_R); 
    1666  
    1667   ICQUser *u = NULL; 
    1668   char *szRealId; 
    1669   ICQUser::MakeRealId(_szId, _nPPID, szRealId); 
    1670   UserList &l = m_vlTable[HashValue(szRealId)]; 
    1671   char *szTempId = 0; 
    1672   unsigned long nPPID; 
    1673   UserList::iterator iter; 
    1674   for (iter = l.begin(); iter != l.end(); ++iter) 
    1675   { 
    1676     nPPID = (*iter)->PPID(); 
    1677     ICQUser::MakeRealId((*iter)->IdString(), nPPID, szTempId); 
    1678     if (_nPPID == nPPID && strcasecmp(szTempId, szRealId) == 0) 
    1679     { 
    1680       u = (*iter); 
    1681       break; 
    1682     } 
    1683     delete [] szTempId; szTempId = 0; 
    1684   } 
    1685   if (iter == l.end()) u = NULL; 
    1686  
    1687   delete [] szRealId; 
    1688   if (szTempId) delete [] szTempId; 
    1689  
    1690   Unlock(); 
    1691   return u; 
    1692 } 
    1693  
    1694 void CUserHashTable::Store(ICQUser *u, const char *_szId, unsigned long _nPPID) 
    1695 { 
    1696   Lock(LOCK_W); 
    1697   char *szRealId; 
    1698   ICQUser::MakeRealId(_szId, _nPPID, szRealId); 
    1699   UserList &l = m_vlTable[HashValue(szRealId)]; 
    1700   delete [] szRealId; 
    1701   l.push_front(u); 
    1702   Unlock(); 
    1703 } 
    1704  
    1705 void CUserHashTable::Remove(const char *_szId, unsigned long _nPPID) 
    1706 { 
    1707   Lock(LOCK_W); 
    1708  
    1709   char *szRealId; 
    1710   ICQUser::MakeRealId(_szId, _nPPID, szRealId); 
    1711   UserList &l = m_vlTable[HashValue(szRealId)]; 
    1712   delete [] szRealId; 
    1713   char *szId; 
    1714   unsigned long nPPID; 
    1715   UserList::iterator iter; 
    1716   for (iter = l.begin(); iter != l.end(); ++iter) 
    1717   { 
    1718     (*iter)->Lock(LOCK_R); 
    1719     szId = (*iter)->IdString(); 
    1720     nPPID = (*iter)->PPID(); 
    1721     (*iter)->Unlock(); 
    1722     if (_nPPID == nPPID && strcmp(szId, _szId) == 0) 
    1723     { 
    1724       l.erase(iter); 
    1725       break; 
    1726     } 
    1727   } 
    1728  
    1729   Unlock(); 
    1730 } 
    1731  
    1732 unsigned short CUserHashTable::HashValue(const char *_szId) 
    1733 { 
    1734   int j = strlen(_szId); 
    1735   unsigned short nRet = 0; 
    1736   for (int i = 0; i < j; i++) 
    1737     nRet += (unsigned short)_szId[i]; 
    1738  
    1739   return (nRet % (USER_HASH_SIZE - 1)); 
    1740 } 
    1741  
    1742 void CUserHashTable::Lock(unsigned short _nLockType) 
    1743 { 
    1744   switch (_nLockType) 
    1745   { 
    1746   case LOCK_R: 
    1747     pthread_rdwr_rlock_np (&mutex_rw); 
    1748     break; 
    1749   case LOCK_W: 
    1750     pthread_rdwr_wlock_np(&mutex_rw); 
    1751     break; 
    1752   default: 
    1753     assert(false); 
    1754     return; 
    1755   } 
    1756   m_nLockType = _nLockType; 
    1757 } 
    1758  
    1759 void CUserHashTable::Unlock() 
    1760 { 
    1761   unsigned short nLockType = m_nLockType; 
    1762   m_nLockType = LOCK_R; 
    1763   switch (nLockType) 
    1764   { 
    1765   case LOCK_R: 
    1766     pthread_rdwr_runlock_np(&mutex_rw); 
    1767     break; 
    1768   case LOCK_W: 
    1769     pthread_rdwr_wunlock_np(&mutex_rw); 
    1770     break; 
    1771   default: 
    1772     assert(false); 
    1773     break; 
    1774   } 
    1775 } 
    1776  
    17771666 
    17781667