Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

RouteCache.cpp

Go to the documentation of this file.
00001 //
00002 // RouteCache.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "RouteCache.h"
00026 #include "Packet.h"
00027 
00028 #ifdef _DEBUG
00029 #undef THIS_FILE
00030 static char THIS_FILE[]=__FILE__;
00031 #define new DEBUG_NEW
00032 #endif
00033 
00034 #define HASH_SIZE                       1024
00035 #define HASH_MASK                       0x3FF
00036 
00037 #define MIN_BUFFER_SIZE         1024
00038 #define MAX_BUFFER_SIZE         40960
00039 #define BUFFER_BLOCK_SIZE       1024
00040 
00041 
00043 // CRouteCache construction
00044 
00045 CRouteCache::CRouteCache()
00046 {
00047         m_nSeconds      = 60 * 20;
00048         m_pRecent       = &m_pTable[0];
00049         m_pHistory      = &m_pTable[1];
00050 }
00051 
00052 CRouteCache::~CRouteCache()
00053 {
00054 }
00055 
00057 // CRouteCache operations
00058 
00059 void CRouteCache::SetDuration(DWORD nSeconds)
00060 {
00061         m_nSeconds = nSeconds;
00062         Clear();
00063 }
00064 
00065 BOOL CRouteCache::Add(const GGUID* pGUID, const CNeighbour* pNeighbour)
00066 {
00067         if ( CRouteCacheItem* pItem = Lookup( pGUID ) )
00068         {
00069                 pItem->m_pNeighbour = pNeighbour;
00070                 return FALSE;
00071         }
00072 
00073         if ( m_pRecent->IsFull() )
00074         {
00075                 CRouteCacheTable* pTemp = m_pRecent;
00076                 m_pRecent = m_pHistory;
00077                 m_pHistory = pTemp;
00078 
00079                 m_pRecent->Resize( m_pHistory->GetNextSize( m_nSeconds ) );
00080         }
00081 
00082         m_pRecent->Add( pGUID, pNeighbour, NULL );
00083 
00084         return TRUE;
00085 }
00086 
00087 BOOL CRouteCache::Add(const GGUID* pGUID, const SOCKADDR_IN* pEndpoint)
00088 {
00089         if ( CRouteCacheItem* pItem = Lookup( pGUID ) )
00090         {
00091                 pItem->m_pNeighbour     = NULL;
00092                 pItem->m_pEndpoint      = *pEndpoint;
00093                 return FALSE;
00094         }
00095 
00096         if ( m_pRecent->IsFull() )
00097         {
00098                 CRouteCacheTable* pTemp = m_pRecent;
00099                 m_pRecent = m_pHistory;
00100                 m_pHistory = pTemp;
00101 
00102                 m_pRecent->Resize( m_pHistory->GetNextSize( m_nSeconds ) );
00103         }
00104 
00105         m_pRecent->Add( pGUID, NULL, pEndpoint );
00106 
00107         return TRUE;
00108 }
00109 
00110 CRouteCacheItem* CRouteCache::Add(const GGUID* pGUID, const CNeighbour* pNeighbour, const SOCKADDR_IN* pEndpoint, DWORD tAdded)
00111 {
00112         GGUID cGUID = *pGUID;
00113         SOCKADDR_IN cEndpoint;
00114         if ( pEndpoint != NULL ) cEndpoint = *pEndpoint;
00115 
00116         if ( m_pRecent->IsFull() )
00117         {
00118                 CRouteCacheTable* pTemp = m_pRecent;
00119                 m_pRecent = m_pHistory;
00120                 m_pHistory = pTemp;
00121 
00122                 m_pRecent->Resize( m_pHistory->GetNextSize( m_nSeconds ) );
00123         }
00124 
00125         return m_pRecent->Add( &cGUID, pNeighbour, pEndpoint != NULL ? &cEndpoint : NULL, tAdded );
00126 }
00127 
00128 CRouteCacheItem* CRouteCache::Lookup(const GGUID* pGUID, CNeighbour** ppNeighbour, SOCKADDR_IN* pEndpoint)
00129 {
00130         CRouteCacheItem* pItem = m_pRecent->Find( pGUID );
00131 
00132         if ( pItem == NULL )
00133         {
00134                 pItem = m_pHistory->Find( pGUID );
00135 
00136                 if ( pItem == NULL )
00137                 {
00138                         if ( ppNeighbour ) *ppNeighbour = NULL;
00139                         if ( pEndpoint ) ZeroMemory( pEndpoint, sizeof(*pEndpoint) );
00140 
00141                         return NULL;
00142                 }
00143 
00144                 pItem = Add( &pItem->m_pGUID, pItem->m_pNeighbour,
00145                         pItem->m_pNeighbour ? NULL : &pItem->m_pEndpoint, pItem->m_tAdded );
00146         }
00147 
00148         if ( ppNeighbour ) *ppNeighbour = (CNeighbour*)pItem->m_pNeighbour;
00149         if ( pEndpoint ) *pEndpoint = pItem->m_pEndpoint;
00150 
00151         return pItem;
00152 }
00153 
00154 void CRouteCache::Remove(CNeighbour* pNeighbour)
00155 {
00156         m_pTable[0].Remove( pNeighbour );
00157         m_pTable[1].Remove( pNeighbour );
00158 }
00159 
00160 void CRouteCache::Clear()
00161 {
00162         m_pTable[0].Clear();
00163         m_pTable[1].Clear();
00164 }
00165 
00166 
00168 // CRouteCacheTable construction
00169 
00170 CRouteCacheTable::CRouteCacheTable()
00171 {
00172         m_pBuffer       = NULL;
00173         m_nBuffer       = 0;
00174         m_nUsed         = 0;
00175         Clear();
00176 }
00177 
00178 CRouteCacheTable::~CRouteCacheTable()
00179 {
00180         if ( m_pBuffer && m_nBuffer ) delete [] m_pBuffer;
00181 }
00182 
00184 // CRouteCacheTable operations
00185 
00186 CRouteCacheItem* CRouteCacheTable::Find(const GGUID* pGUID)
00187 {
00188         WORD nGUID = 0, *ppGUID = (WORD*)pGUID;
00189         for ( int nIt = 8 ; nIt ; nIt-- ) nGUID += *ppGUID++;
00190 
00191         CRouteCacheItem* pItem = *( m_pHash + ( nGUID & HASH_MASK ) );
00192 
00193         for ( ; pItem ; pItem = pItem->m_pNext )
00194         {
00195                 if ( *pGUID == pItem->m_pGUID ) return pItem;
00196         }
00197 
00198         return NULL;
00199 }
00200 
00201 CRouteCacheItem* CRouteCacheTable::Add(const GGUID* pGUID, const CNeighbour* pNeighbour, const SOCKADDR_IN* pEndpoint, DWORD nTime)
00202 {
00203         if ( m_nUsed == m_nBuffer || ! m_pFree ) return NULL;
00204 
00205         WORD nGUID = 0, *ppGUID = (WORD*)pGUID;
00206         for ( int nIt = 8 ; nIt ; nIt-- ) nGUID += *ppGUID++;
00207 
00208         CRouteCacheItem** pHash = m_pHash + ( nGUID & HASH_MASK );
00209 
00210         CRouteCacheItem* pItem = m_pFree;
00211         m_pFree = m_pFree->m_pNext;
00212 
00213         pItem->m_pNext = *pHash;
00214         *pHash = pItem;
00215 
00216         pItem->m_pGUID                  = *pGUID;
00217         pItem->m_tAdded                 = nTime ? nTime : GetTickCount();
00218         pItem->m_pNeighbour             = pNeighbour;
00219         if ( pEndpoint ) pItem->m_pEndpoint = *pEndpoint;
00220 
00221         if ( ! m_nUsed++ )
00222         {
00223                 m_tFirst = GetTickCount();
00224         }
00225         else if ( m_nUsed == m_nBuffer )
00226         {
00227                 m_tLast = GetTickCount();
00228         }
00229 
00230         return pItem;
00231 }
00232 
00233 void CRouteCacheTable::Remove(CNeighbour* pNeighbour)
00234 {
00235         CRouteCacheItem** pHash = m_pHash;
00236 
00237         for ( int nHash = 0 ; nHash < HASH_SIZE ; nHash++, pHash++ )
00238         {
00239                 CRouteCacheItem** pLast = pHash;
00240 
00241                 for ( CRouteCacheItem* pItem = *pLast ; pItem ; )
00242                 {
00243                         CRouteCacheItem* pNext = pItem->m_pNext;
00244 
00245                         if ( pItem->m_pNeighbour == pNeighbour )
00246                         {
00247                                 *pLast = pNext;
00248                                 pItem->m_pNext = m_pFree;
00249                                 m_pFree = pItem;
00250                                 m_nUsed--;
00251                         }
00252                         else
00253                         {
00254                                 pLast = &pItem->m_pNext;
00255                         }
00256 
00257                         pItem = pNext;
00258                 }
00259         }
00260 }
00261 
00262 void CRouteCacheTable::Resize(DWORD nSize)
00263 {
00264         nSize = min( max( nSize, DWORD(MIN_BUFFER_SIZE) ), DWORD(MAX_BUFFER_SIZE) );
00265         nSize = ( ( nSize + BUFFER_BLOCK_SIZE - 1 ) / BUFFER_BLOCK_SIZE * BUFFER_BLOCK_SIZE );
00266 
00267         if ( nSize != m_nBuffer )
00268         {
00269                 if ( m_pBuffer && m_nBuffer ) delete [] m_pBuffer;
00270 
00271                 m_nBuffer = nSize;
00272                 m_pBuffer = nSize ? ( new CRouteCacheItem[ m_nBuffer ] ) : NULL;
00273         }
00274 
00275         ZeroMemory( m_pHash, sizeof(CRouteCacheItem*) * HASH_SIZE );
00276 
00277         m_pFree         = m_pBuffer;
00278         m_nUsed         = 0;
00279         m_tFirst        = 0;
00280         m_tLast         = 0;
00281 
00282         CRouteCacheItem* pItem = m_pBuffer;
00283 
00284         for ( DWORD nPos = m_nBuffer ; nPos ; nPos--, pItem++ )
00285         {
00286                 if ( nPos == 1 )
00287                 {
00288                         pItem->m_pNext = NULL;
00289                 }
00290                 else
00291                 {
00292                         pItem->m_pNext = pItem + 1;
00293                 }
00294         }
00295 }
00296 
00297 DWORD CRouteCacheTable::GetNextSize(DWORD nDesired)
00298 {
00299         DWORD nSeconds = ( m_tLast - m_tFirst ) / 1000;
00300         if ( ! nSeconds ) nSeconds = 1;
00301 
00302         return m_nBuffer * nDesired / nSeconds;
00303 }
00304 
00305 void CRouteCacheTable::Clear()
00306 {
00307         Resize( 0 );
00308 }

Generated on Thu Dec 15 10:39:47 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2