| 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 | | |