OLD | NEW |
| (Empty) |
1 /***************************************************************************** | |
2 Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois. | |
3 All rights reserved. | |
4 | |
5 Redistribution and use in source and binary forms, with or without | |
6 modification, are permitted provided that the following conditions are | |
7 met: | |
8 | |
9 * Redistributions of source code must retain the above | |
10 copyright notice, this list of conditions and the | |
11 following disclaimer. | |
12 | |
13 * Redistributions in binary form must reproduce the | |
14 above copyright notice, this list of conditions | |
15 and the following disclaimer in the documentation | |
16 and/or other materials provided with the distribution. | |
17 | |
18 * Neither the name of the University of Illinois | |
19 nor the names of its contributors may be used to | |
20 endorse or promote products derived from this | |
21 software without specific prior written permission. | |
22 | |
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
24 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
25 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
26 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
34 *****************************************************************************/ | |
35 | |
36 /***************************************************************************** | |
37 written by | |
38 Yunhong Gu, last updated 05/05/2009 | |
39 *****************************************************************************/ | |
40 | |
41 #ifdef WIN32 | |
42 #include <winsock2.h> | |
43 #include <ws2tcpip.h> | |
44 #ifdef LEGACY_WIN32 | |
45 #include <wspiapi.h> | |
46 #endif | |
47 #endif | |
48 | |
49 #include <cstring> | |
50 #include "cache.h" | |
51 #include "core.h" | |
52 | |
53 using namespace std; | |
54 | |
55 CCache::CCache(const int& size): | |
56 m_iMaxSize(size), | |
57 m_iHashSize(size * 3), | |
58 m_iCurrSize(0) | |
59 { | |
60 m_vHashPtr.resize(m_iHashSize); | |
61 | |
62 #ifndef WIN32 | |
63 pthread_mutex_init(&m_Lock, NULL); | |
64 #else | |
65 m_Lock = CreateMutex(NULL, false, NULL); | |
66 #endif | |
67 } | |
68 | |
69 CCache::~CCache() | |
70 { | |
71 for (list<CCacheItem*>::iterator i = m_StorageList.begin(); i != m_StorageLis
t.end(); ++ i) | |
72 delete *i; | |
73 m_StorageList.clear(); | |
74 | |
75 #ifndef WIN32 | |
76 pthread_mutex_destroy(&m_Lock); | |
77 #else | |
78 CloseHandle(m_Lock); | |
79 #endif | |
80 } | |
81 | |
82 int CCache::lookup(CCacheItem* data) | |
83 { | |
84 CGuard cacheguard(m_Lock); | |
85 | |
86 int key = data->getKey(); | |
87 | |
88 if (key < 0) | |
89 return -1; | |
90 | |
91 if (key >= m_iMaxSize) | |
92 key %= m_iHashSize; | |
93 | |
94 for (list<list<CCacheItem*>::iterator>::iterator i = m_vHashPtr[key].begin();
i != m_vHashPtr[key].end(); ++ i) | |
95 { | |
96 if (*data == ***i) | |
97 { | |
98 // copy the cached info | |
99 *data = ***i; | |
100 return 0; | |
101 } | |
102 } | |
103 | |
104 return -1; | |
105 } | |
106 | |
107 int CCache::update(CCacheItem* data) | |
108 { | |
109 CGuard cacheguard(m_Lock); | |
110 | |
111 int key = data->getKey(); | |
112 | |
113 if (key < 0) | |
114 return -1; | |
115 | |
116 if (key >= m_iMaxSize) | |
117 key %= m_iHashSize; | |
118 | |
119 CCacheItem* curr = NULL; | |
120 | |
121 for (list<list<CCacheItem*>::iterator>::iterator i = m_vHashPtr[key].begin();
i != m_vHashPtr[key].end(); ++ i) | |
122 { | |
123 if (*data == ***i) | |
124 { | |
125 // update the existing entry with the new value | |
126 ***i = *data; | |
127 curr = **i; | |
128 | |
129 // remove the current entry | |
130 m_StorageList.erase(*i); | |
131 m_vHashPtr[key].erase(i); | |
132 | |
133 // re-insert to the front | |
134 m_StorageList.push_front(curr); | |
135 m_vHashPtr[key].push_front(m_StorageList.begin()); | |
136 | |
137 return 0; | |
138 } | |
139 } | |
140 | |
141 // create new entry and insert to front | |
142 curr = data->clone(); | |
143 m_StorageList.push_front(curr); | |
144 m_vHashPtr[key].push_front(m_StorageList.begin()); | |
145 | |
146 ++ m_iCurrSize; | |
147 if (m_iCurrSize >= m_iMaxSize) | |
148 { | |
149 CCacheItem* last_data = m_StorageList.back(); | |
150 int last_key = last_data->getKey() % m_iHashSize; | |
151 | |
152 for (list<list<CCacheItem*>::iterator>::iterator i = m_vHashPtr[last_key].
begin(); i != m_vHashPtr[last_key].end(); ++ i) | |
153 { | |
154 if (*last_data == ***i) | |
155 { | |
156 m_vHashPtr[last_key].erase(i); | |
157 break; | |
158 } | |
159 } | |
160 | |
161 delete last_data; | |
162 m_StorageList.pop_back(); | |
163 -- m_iCurrSize; | |
164 } | |
165 | |
166 return 0; | |
167 } | |
168 | |
169 | |
170 CInfoBlock& CInfoBlock::operator=(CCacheItem& obj) | |
171 { | |
172 try | |
173 { | |
174 const CInfoBlock& real_obj = dynamic_cast<CInfoBlock&>(obj); | |
175 | |
176 std::copy(real_obj.m_piIP, real_obj.m_piIP + 3, m_piIP); | |
177 m_iIPversion = real_obj.m_iIPversion; | |
178 m_ullTimeStamp = real_obj.m_ullTimeStamp; | |
179 m_iRTT = real_obj.m_iRTT; | |
180 m_iBandwidth = real_obj.m_iBandwidth; | |
181 m_iLossRate = real_obj.m_iLossRate; | |
182 m_iReorderDistance = real_obj.m_iReorderDistance; | |
183 m_dInterval = real_obj.m_dInterval; | |
184 m_dCWnd = real_obj.m_dCWnd; | |
185 } | |
186 catch (...) | |
187 { | |
188 } | |
189 | |
190 return *this; | |
191 } | |
192 | |
193 bool CInfoBlock::operator==(CCacheItem& obj) | |
194 { | |
195 try | |
196 { | |
197 const CInfoBlock& real_obj = dynamic_cast<CInfoBlock&>(obj); | |
198 | |
199 if (m_iIPversion != real_obj.m_iIPversion) | |
200 return false; | |
201 | |
202 else if (m_iIPversion == AF_INET) | |
203 return (m_piIP[0] == real_obj.m_piIP[0]); | |
204 | |
205 for (int i = 0; i < 4; ++ i) | |
206 { | |
207 if (m_piIP[i] != real_obj.m_piIP[i]) | |
208 return false; | |
209 } | |
210 } | |
211 catch (...) | |
212 { | |
213 return false; | |
214 } | |
215 | |
216 return true;} | |
217 | |
218 CInfoBlock* CInfoBlock::clone() | |
219 { | |
220 CInfoBlock* obj = new CInfoBlock; | |
221 | |
222 std::copy(m_piIP, m_piIP + 3, obj->m_piIP); | |
223 obj->m_iIPversion = m_iIPversion; | |
224 obj->m_ullTimeStamp = m_ullTimeStamp; | |
225 obj->m_iRTT = m_iRTT; | |
226 obj->m_iBandwidth = m_iBandwidth; | |
227 obj->m_iLossRate = m_iLossRate; | |
228 obj->m_iReorderDistance = m_iReorderDistance; | |
229 obj->m_dInterval = m_dInterval; | |
230 obj->m_dCWnd = m_dCWnd; | |
231 | |
232 return obj; | |
233 } | |
234 | |
235 int CInfoBlock::getKey() | |
236 { | |
237 if (m_iIPversion == AF_INET) | |
238 return m_piIP[0]; | |
239 | |
240 return m_piIP[0] + m_piIP[1] + m_piIP[2] + m_piIP[3]; | |
241 } | |
242 | |
243 void CInfoBlock::convert(const sockaddr* addr, const int& ver, uint32_t ip[]) | |
244 { | |
245 if (ver == AF_INET) | |
246 { | |
247 ip[0] = ((sockaddr_in*)addr)->sin_addr.s_addr; | |
248 ip[1] = ip[2] = ip[3] = 0; | |
249 } | |
250 else | |
251 { | |
252 memcpy((char*)ip, (char*)((sockaddr_in6*)addr)->sin6_addr.s6_addr, 16); | |
253 } | |
254 } | |
OLD | NEW |