cache.h

00001 /*****************************************************************************
00002 Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are
00007 met:
00008 
00009 * Redistributions of source code must retain the above
00010   copyright notice, this list of conditions and the
00011   following disclaimer.
00012 
00013 * Redistributions in binary form must reproduce the
00014   above copyright notice, this list of conditions
00015   and the following disclaimer in the documentation
00016   and/or other materials provided with the distribution.
00017 
00018 * Neither the name of the University of Illinois
00019   nor the names of its contributors may be used to
00020   endorse or promote products derived from this
00021   software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00024 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00025 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00026 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00027 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00028 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00029 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00030 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00031 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00032 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 *****************************************************************************/
00035 
00036 /*****************************************************************************
00037 written by
00038    Yunhong Gu, last updated 01/27/2011
00039 *****************************************************************************/
00040 
00041 #ifndef __UDT_CACHE_H__
00042 #define __UDT_CACHE_H__
00043 
00044 #include <list>
00045 #include <vector>
00046 
00047 #include "common.h"
00048 #include "udt.h"
00049 
00050 class CCacheItem
00051 {
00052 public:
00053    virtual ~CCacheItem() {}
00054 
00055 public:
00056    virtual CCacheItem& operator=(const CCacheItem&) = 0;
00057 
00058    // The "==" operator SHOULD only compare key values.
00059    virtual bool operator==(const CCacheItem&) = 0;
00060 
00061       // Functionality:
00062       //    get a deep copy clone of the current item
00063       // Parameters:
00064       //    None.
00065       // Returned value:
00066       //    Pointer to the new item, or NULL if failed.
00067 
00068    virtual CCacheItem* clone() = 0;
00069 
00070       // Functionality:
00071       //    get a random key value between 0 and MAX_INT to be used for the hash in cache
00072       // Parameters:
00073       //    None.
00074       // Returned value:
00075       //    A random hash key.
00076 
00077    virtual int getKey() = 0;
00078 
00079    // If there is any shared resources between the cache item and its clone,
00080    // the shared resource should be released by this function.
00081    virtual void release() {}
00082 };
00083 
00084 template<typename T> class CCache
00085 {
00086 public:
00087    CCache(int size = 1024):
00088    m_iMaxSize(size),
00089    m_iHashSize(size * 3),
00090    m_iCurrSize(0)
00091    {
00092       m_vHashPtr.resize(m_iHashSize);
00093       CGuard::createMutex(m_Lock);
00094    }
00095 
00096    ~CCache()
00097    {
00098       clear();
00099       CGuard::releaseMutex(m_Lock);
00100    }
00101 
00102 public:
00103       // Functionality:
00104       //    find the matching item in the cache.
00105       // Parameters:
00106       //    0) [in/out] data: storage for the retrieved item; initially it must carry the key information
00107       // Returned value:
00108       //    0 if found a match, otherwise -1.
00109 
00110    int lookup(T* data)
00111    {
00112       CGuard cacheguard(m_Lock);
00113 
00114       int key = data->getKey();
00115       if (key < 0)
00116          return -1;
00117       if (key >= m_iMaxSize)
00118          key %= m_iHashSize;
00119 
00120       const ItemPtrList& item_list = m_vHashPtr[key];
00121       for (typename ItemPtrList::const_iterator i = item_list.begin(); i != item_list.end(); ++ i)
00122       {
00123          if (*data == ***i)
00124          {
00125             // copy the cached info
00126             *data = ***i;
00127             return 0;
00128          }
00129       }
00130 
00131       return -1;
00132    }
00133 
00134       // Functionality:
00135       //    update an item in the cache, or insert one if it doesn't exist; oldest item may be removed
00136       // Parameters:
00137       //    0) [in] data: the new item to updated/inserted to the cache
00138       // Returned value:
00139       //    0 if success, otherwise -1.
00140 
00141    int update(T* data)
00142    {
00143       CGuard cacheguard(m_Lock);
00144 
00145       int key = data->getKey();
00146       if (key < 0)
00147          return -1;
00148       if (key >= m_iMaxSize)
00149          key %= m_iHashSize;
00150 
00151       T* curr = NULL;
00152 
00153       ItemPtrList& item_list = m_vHashPtr[key];
00154       for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i)
00155       {
00156          if (*data == ***i)
00157          {
00158             // update the existing entry with the new value
00159             ***i = *data;
00160             curr = **i;
00161 
00162             // remove the current entry
00163             m_StorageList.erase(*i);
00164             item_list.erase(i);
00165 
00166             // re-insert to the front
00167             m_StorageList.push_front(curr);
00168             item_list.push_front(m_StorageList.begin());
00169 
00170             return 0;
00171          }
00172       }
00173 
00174       // create new entry and insert to front
00175       curr = data->clone();
00176       m_StorageList.push_front(curr);
00177       item_list.push_front(m_StorageList.begin());
00178 
00179       ++ m_iCurrSize;
00180       if (m_iCurrSize >= m_iMaxSize)
00181       {
00182          // Cache overflow, remove oldest entry.
00183          T* last_data = m_StorageList.back();
00184          int last_key = last_data->getKey() % m_iHashSize;
00185 
00186          item_list = m_vHashPtr[last_key];
00187          for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i)
00188          {
00189             if (*last_data == ***i)
00190             {
00191                item_list.erase(i);
00192                break;
00193             }
00194          }
00195 
00196          last_data->release();
00197          delete last_data;
00198          m_StorageList.pop_back();
00199          -- m_iCurrSize;
00200       }
00201 
00202       return 0;
00203    }
00204 
00205       // Functionality:
00206       //    Specify the cache size (i.e., max number of items).
00207       // Parameters:
00208       //    0) [in] size: max cache size.
00209       // Returned value:
00210       //    None.
00211 
00212    void setSizeLimit(int size)
00213    {
00214       m_iMaxSize = size;
00215       m_iHashSize = size * 3;
00216       m_vHashPtr.resize(m_iHashSize);
00217    }
00218 
00219       // Functionality:
00220       //    Clear all entries in the cache, restore to initialization state.
00221       // Parameters:
00222       //    None.
00223       // Returned value:
00224       //    None.
00225 
00226    void clear()
00227    {
00228       for (typename std::list<T*>::iterator i = m_StorageList.begin(); i != m_StorageList.end(); ++ i)
00229       {
00230          (*i)->release();
00231          delete *i;
00232       }
00233       m_StorageList.clear();
00234       for (typename std::vector<ItemPtrList>::iterator i = m_vHashPtr.begin(); i != m_vHashPtr.end(); ++ i)
00235          i->clear();
00236       m_iCurrSize = 0;
00237    }
00238 
00239 private:
00240    std::list<T*> m_StorageList;
00241    typedef typename std::list<T*>::iterator ItemPtr;
00242    typedef std::list<ItemPtr> ItemPtrList;
00243    std::vector<ItemPtrList> m_vHashPtr;
00244 
00245    int m_iMaxSize;
00246    int m_iHashSize;
00247    int m_iCurrSize;
00248 
00249    pthread_mutex_t m_Lock;
00250 
00251 private:
00252    CCache(const CCache&);
00253    CCache& operator=(const CCache&);
00254 };
00255 
00256 
00257 class CInfoBlock
00258 {
00259 public:
00260    uint32_t m_piIP[4];          // IP address, machine read only, not human readable format
00261    int m_iIPversion;            // IP version
00262    uint64_t m_ullTimeStamp;     // last update time
00263    int m_iRTT;                  // RTT
00264    int m_iBandwidth;            // estimated bandwidth
00265    int m_iLossRate;             // average loss rate
00266    int m_iReorderDistance;      // packet reordering distance
00267    double m_dInterval;          // inter-packet time, congestion control
00268    double m_dCWnd;              // congestion window size, congestion control
00269 
00270 public:
00271    virtual ~CInfoBlock() {}
00272    virtual CInfoBlock& operator=(const CInfoBlock& obj);
00273    virtual bool operator==(const CInfoBlock& obj);
00274    virtual CInfoBlock* clone();
00275    virtual int getKey();
00276    virtual void release() {}
00277 
00278 public:
00279 
00280       // Functionality:
00281       //    convert sockaddr structure to an integer array
00282       // Parameters:
00283       //    0) [in] addr: network address
00284       //    1) [in] ver: IP version
00285       //    2) [out] ip: the result machine readable IP address in integer array
00286       // Returned value:
00287       //    None.
00288 
00289    static void convert(const sockaddr* addr, int ver, uint32_t ip[]);
00290 };
00291 
00292 
00293 #endif

Generated on 9 Feb 2013 for barchart-udt-core-2.2.2 by  doxygen 1.6.1