123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- /*****************************************************************************
- Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
- * Redistributions in binary form must reproduce the
- above copyright notice, this list of conditions
- and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the University of Illinois
- nor the names of its contributors may be used to
- endorse or promote products derived from this
- software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
- /*****************************************************************************
- written by
- Yunhong Gu, last updated 01/27/2011
- *****************************************************************************/
- #ifndef INC_SRT_CACHE_H
- #define INC_SRT_CACHE_H
- #include <list>
- #include <vector>
- #include "sync.h"
- #include "netinet_any.h"
- #include "udt.h"
- namespace srt
- {
- class CCacheItem
- {
- public:
- virtual ~CCacheItem() {}
- public:
- virtual CCacheItem& operator=(const CCacheItem&) = 0;
- // The "==" operator SHOULD only compare key values.
- virtual bool operator==(const CCacheItem&) = 0;
- /// get a deep copy clone of the current item
- /// @return Pointer to the new item, or NULL if failed.
- virtual CCacheItem* clone() = 0;
- /// get a random key value between 0 and MAX_INT to be used for the hash in cache
- /// @return A random hash key.
- virtual int getKey() = 0;
- // If there is any shared resources between the cache item and its clone,
- // the shared resource should be released by this function.
- virtual void release() {}
- };
- template<typename T> class CCache
- {
- public:
- CCache(int size = 1024):
- m_iMaxSize(size),
- m_iHashSize(size * 3),
- m_iCurrSize(0)
- {
- m_vHashPtr.resize(m_iHashSize);
- // Exception: -> CUDTUnited ctor
- srt::sync::setupMutex(m_Lock, "Cache");
- }
- ~CCache()
- {
- clear();
- }
- public:
- /// find the matching item in the cache.
- /// @param [in,out] data storage for the retrieved item; initially it must carry the key information
- /// @return 0 if found a match, otherwise -1.
- int lookup(T* data)
- {
- srt::sync::ScopedLock cacheguard(m_Lock);
- int key = data->getKey();
- if (key < 0)
- return -1;
- if (key >= m_iMaxSize)
- key %= m_iHashSize;
- const ItemPtrList& item_list = m_vHashPtr[key];
- for (typename ItemPtrList::const_iterator i = item_list.begin(); i != item_list.end(); ++ i)
- {
- if (*data == ***i)
- {
- // copy the cached info
- *data = ***i;
- return 0;
- }
- }
- return -1;
- }
- /// update an item in the cache, or insert one if it doesn't exist; oldest item may be removed
- /// @param [in] data the new item to updated/inserted to the cache
- /// @return 0 if success, otherwise -1.
- int update(T* data)
- {
- srt::sync::ScopedLock cacheguard(m_Lock);
- int key = data->getKey();
- if (key < 0)
- return -1;
- if (key >= m_iMaxSize)
- key %= m_iHashSize;
- T* curr = NULL;
- ItemPtrList& item_list = m_vHashPtr[key];
- for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i)
- {
- if (*data == ***i)
- {
- // update the existing entry with the new value
- ***i = *data;
- curr = **i;
- // remove the current entry
- m_StorageList.erase(*i);
- item_list.erase(i);
- // re-insert to the front
- m_StorageList.push_front(curr);
- item_list.push_front(m_StorageList.begin());
- return 0;
- }
- }
- // create new entry and insert to front
- curr = data->clone();
- m_StorageList.push_front(curr);
- item_list.push_front(m_StorageList.begin());
- ++ m_iCurrSize;
- if (m_iCurrSize >= m_iMaxSize)
- {
- // Cache overflow, remove oldest entry.
- T* last_data = m_StorageList.back();
- int last_key = last_data->getKey() % m_iHashSize;
- ItemPtrList& last_item_list = m_vHashPtr[last_key];
- for (typename ItemPtrList::iterator i = last_item_list.begin(); i != last_item_list.end(); ++ i)
- {
- if (*last_data == ***i)
- {
- last_item_list.erase(i);
- break;
- }
- }
- last_data->release();
- delete last_data;
- m_StorageList.pop_back();
- -- m_iCurrSize;
- }
- return 0;
- }
- /// Specify the cache size (i.e., max number of items).
- /// @param [in] size max cache size.
- void setSizeLimit(int size)
- {
- m_iMaxSize = size;
- m_iHashSize = size * 3;
- m_vHashPtr.resize(m_iHashSize);
- }
- /// Clear all entries in the cache, restore to initialization state.
- void clear()
- {
- for (typename std::list<T*>::iterator i = m_StorageList.begin(); i != m_StorageList.end(); ++ i)
- {
- (*i)->release();
- delete *i;
- }
- m_StorageList.clear();
- for (typename std::vector<ItemPtrList>::iterator i = m_vHashPtr.begin(); i != m_vHashPtr.end(); ++ i)
- i->clear();
- m_iCurrSize = 0;
- }
- private:
- std::list<T*> m_StorageList;
- typedef typename std::list<T*>::iterator ItemPtr;
- typedef std::list<ItemPtr> ItemPtrList;
- std::vector<ItemPtrList> m_vHashPtr;
- int m_iMaxSize;
- int m_iHashSize;
- int m_iCurrSize;
- srt::sync::Mutex m_Lock;
- private:
- CCache(const CCache&);
- CCache& operator=(const CCache&);
- };
- class CInfoBlock
- {
- public:
- uint32_t m_piIP[4]; // IP address, machine read only, not human readable format.
- int m_iIPversion; // Address family: AF_INET or AF_INET6.
- uint64_t m_ullTimeStamp; // Last update time.
- int m_iSRTT; // Smoothed RTT.
- int m_iBandwidth; // Estimated link bandwidth.
- int m_iLossRate; // Average loss rate.
- int m_iReorderDistance; // Packet reordering distance.
- double m_dInterval; // Inter-packet time (Congestion Control).
- double m_dCWnd; // Congestion window size (Congestion Control).
- public:
- CInfoBlock() {} // NOTE: leaves uninitialized
- CInfoBlock& copyFrom(const CInfoBlock& obj);
- CInfoBlock(const CInfoBlock& src) { copyFrom(src); }
- CInfoBlock& operator=(const CInfoBlock& src) { return copyFrom(src); }
- bool operator==(const CInfoBlock& obj) const;
- CInfoBlock* clone();
- int getKey();
- void release() {}
- public:
- /// convert sockaddr structure to an integer array
- /// @param [in] addr network address
- /// @param [in] ver IP version
- /// @param [out] ip the result machine readable IP address in integer array
- static void convert(const sockaddr_any& addr, uint32_t ip[4]);
- };
- } // namespace srt
- #endif
|