OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../include/fxcrt/fx_basic.h" | 7 #include "../../include/fxcrt/fx_basic.h" |
8 #include "plex.h" | 8 #include "plex.h" |
9 | 9 |
10 static void ConstructElement(CFX_ByteString* pNewData) | 10 static void ConstructElement(CFX_ByteString* pNewData) { |
11 { | 11 new (pNewData) CFX_ByteString(); |
12 new (pNewData) CFX_ByteString(); | 12 } |
13 } | 13 static void DestructElement(CFX_ByteString* pOldData) { |
14 static void DestructElement(CFX_ByteString* pOldData) | 14 pOldData->~CFX_ByteString(); |
15 { | |
16 pOldData->~CFX_ByteString(); | |
17 } | 15 } |
18 CFX_MapPtrToPtr::CFX_MapPtrToPtr(int nBlockSize) | 16 CFX_MapPtrToPtr::CFX_MapPtrToPtr(int nBlockSize) |
19 : m_pHashTable(NULL) | 17 : m_pHashTable(NULL), |
20 , m_nHashTableSize(17) | 18 m_nHashTableSize(17), |
21 , m_nCount(0) | 19 m_nCount(0), |
22 , m_pFreeList(NULL) | 20 m_pFreeList(NULL), |
23 , m_pBlocks(NULL) | 21 m_pBlocks(NULL), |
24 , m_nBlockSize(nBlockSize) | 22 m_nBlockSize(nBlockSize) { |
25 { | 23 ASSERT(m_nBlockSize > 0); |
26 ASSERT(m_nBlockSize > 0); | 24 } |
27 } | 25 void CFX_MapPtrToPtr::RemoveAll() { |
28 void CFX_MapPtrToPtr::RemoveAll() | 26 if (m_pHashTable) { |
29 { | 27 FX_Free(m_pHashTable); |
30 if (m_pHashTable) { | 28 m_pHashTable = NULL; |
31 FX_Free(m_pHashTable); | 29 } |
32 m_pHashTable = NULL; | 30 m_nCount = 0; |
33 } | 31 m_pFreeList = NULL; |
34 m_nCount = 0; | 32 m_pBlocks->FreeDataChain(); |
35 m_pFreeList = NULL; | 33 m_pBlocks = NULL; |
36 m_pBlocks->FreeDataChain(); | 34 } |
37 m_pBlocks = NULL; | 35 CFX_MapPtrToPtr::~CFX_MapPtrToPtr() { |
38 } | 36 RemoveAll(); |
39 CFX_MapPtrToPtr::~CFX_MapPtrToPtr() | 37 ASSERT(m_nCount == 0); |
40 { | 38 } |
| 39 FX_DWORD CFX_MapPtrToPtr::HashKey(void* key) const { |
| 40 return ((FX_DWORD)(uintptr_t)key) >> 4; |
| 41 } |
| 42 void CFX_MapPtrToPtr::GetNextAssoc(FX_POSITION& rNextPosition, |
| 43 void*& rKey, |
| 44 void*& rValue) const { |
| 45 ASSERT(m_pHashTable != NULL); |
| 46 CAssoc* pAssocRet = (CAssoc*)rNextPosition; |
| 47 ASSERT(pAssocRet != NULL); |
| 48 if (pAssocRet == (CAssoc*)-1) { |
| 49 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) |
| 50 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { |
| 51 break; |
| 52 } |
| 53 ASSERT(pAssocRet != NULL); |
| 54 } |
| 55 CAssoc* pAssocNext; |
| 56 if ((pAssocNext = pAssocRet->pNext) == NULL) { |
| 57 for (FX_DWORD nBucket = (HashKey(pAssocRet->key) % m_nHashTableSize) + 1; |
| 58 nBucket < m_nHashTableSize; nBucket++) { |
| 59 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { |
| 60 break; |
| 61 } |
| 62 } |
| 63 } |
| 64 rNextPosition = (FX_POSITION)pAssocNext; |
| 65 rKey = pAssocRet->key; |
| 66 rValue = pAssocRet->value; |
| 67 } |
| 68 FX_BOOL CFX_MapPtrToPtr::Lookup(void* key, void*& rValue) const { |
| 69 FX_DWORD nHash; |
| 70 CAssoc* pAssoc = GetAssocAt(key, nHash); |
| 71 if (pAssoc == NULL) { |
| 72 return FALSE; |
| 73 } |
| 74 rValue = pAssoc->value; |
| 75 return TRUE; |
| 76 } |
| 77 void* CFX_MapPtrToPtr::GetValueAt(void* key) const { |
| 78 FX_DWORD nHash; |
| 79 CAssoc* pAssoc = GetAssocAt(key, nHash); |
| 80 if (pAssoc == NULL) { |
| 81 return NULL; |
| 82 } |
| 83 return pAssoc->value; |
| 84 } |
| 85 void*& CFX_MapPtrToPtr::operator[](void* key) { |
| 86 FX_DWORD nHash; |
| 87 CAssoc* pAssoc; |
| 88 if ((pAssoc = GetAssocAt(key, nHash)) == NULL) { |
| 89 if (m_pHashTable == NULL) { |
| 90 InitHashTable(m_nHashTableSize); |
| 91 } |
| 92 pAssoc = NewAssoc(); |
| 93 pAssoc->key = key; |
| 94 pAssoc->pNext = m_pHashTable[nHash]; |
| 95 m_pHashTable[nHash] = pAssoc; |
| 96 } |
| 97 return pAssoc->value; |
| 98 } |
| 99 CFX_MapPtrToPtr::CAssoc* CFX_MapPtrToPtr::GetAssocAt(void* key, |
| 100 FX_DWORD& nHash) const { |
| 101 nHash = HashKey(key) % m_nHashTableSize; |
| 102 if (m_pHashTable == NULL) { |
| 103 return NULL; |
| 104 } |
| 105 CAssoc* pAssoc; |
| 106 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) { |
| 107 if (pAssoc->key == key) { |
| 108 return pAssoc; |
| 109 } |
| 110 } |
| 111 return NULL; |
| 112 } |
| 113 CFX_MapPtrToPtr::CAssoc* CFX_MapPtrToPtr::NewAssoc() { |
| 114 if (m_pFreeList == NULL) { |
| 115 CFX_Plex* newBlock = CFX_Plex::Create(m_pBlocks, m_nBlockSize, |
| 116 sizeof(CFX_MapPtrToPtr::CAssoc)); |
| 117 CFX_MapPtrToPtr::CAssoc* pAssoc = |
| 118 (CFX_MapPtrToPtr::CAssoc*)newBlock->data(); |
| 119 pAssoc += m_nBlockSize - 1; |
| 120 for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) { |
| 121 pAssoc->pNext = m_pFreeList; |
| 122 m_pFreeList = pAssoc; |
| 123 } |
| 124 } |
| 125 ASSERT(m_pFreeList != NULL); |
| 126 CFX_MapPtrToPtr::CAssoc* pAssoc = m_pFreeList; |
| 127 m_pFreeList = m_pFreeList->pNext; |
| 128 m_nCount++; |
| 129 ASSERT(m_nCount > 0); |
| 130 pAssoc->key = 0; |
| 131 pAssoc->value = 0; |
| 132 return pAssoc; |
| 133 } |
| 134 void CFX_MapPtrToPtr::InitHashTable(FX_DWORD nHashSize, FX_BOOL bAllocNow) { |
| 135 ASSERT(m_nCount == 0); |
| 136 ASSERT(nHashSize > 0); |
| 137 if (m_pHashTable != NULL) { |
| 138 FX_Free(m_pHashTable); |
| 139 m_pHashTable = NULL; |
| 140 } |
| 141 if (bAllocNow) { |
| 142 m_pHashTable = FX_Alloc(CAssoc*, nHashSize); |
| 143 } |
| 144 m_nHashTableSize = nHashSize; |
| 145 } |
| 146 FX_BOOL CFX_MapPtrToPtr::RemoveKey(void* key) { |
| 147 if (m_pHashTable == NULL) { |
| 148 return FALSE; |
| 149 } |
| 150 CAssoc** ppAssocPrev; |
| 151 ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize]; |
| 152 CAssoc* pAssoc; |
| 153 for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) { |
| 154 if (pAssoc->key == key) { |
| 155 *ppAssocPrev = pAssoc->pNext; |
| 156 FreeAssoc(pAssoc); |
| 157 return TRUE; |
| 158 } |
| 159 ppAssocPrev = &pAssoc->pNext; |
| 160 } |
| 161 return FALSE; |
| 162 } |
| 163 void CFX_MapPtrToPtr::FreeAssoc(CFX_MapPtrToPtr::CAssoc* pAssoc) { |
| 164 pAssoc->pNext = m_pFreeList; |
| 165 m_pFreeList = pAssoc; |
| 166 m_nCount--; |
| 167 ASSERT(m_nCount >= 0); |
| 168 if (m_nCount == 0) { |
41 RemoveAll(); | 169 RemoveAll(); |
42 ASSERT(m_nCount == 0); | 170 } |
43 } | 171 } |
44 FX_DWORD CFX_MapPtrToPtr::HashKey(void* key) const | 172 CFX_MapByteStringToPtr::CFX_MapByteStringToPtr(int nBlockSize) |
45 { | 173 : m_pHashTable(NULL), |
46 return ((FX_DWORD)(uintptr_t)key) >> 4; | 174 m_nHashTableSize(17), |
47 } | 175 m_nCount(0), |
48 void CFX_MapPtrToPtr::GetNextAssoc(FX_POSITION& rNextPosition, void*& rKey, void
*& rValue) const | 176 m_pFreeList(NULL), |
49 { | 177 m_pBlocks(NULL), |
50 ASSERT(m_pHashTable != NULL); | 178 m_nBlockSize(nBlockSize) { |
51 CAssoc* pAssocRet = (CAssoc*)rNextPosition; | 179 ASSERT(m_nBlockSize > 0); |
| 180 } |
| 181 void CFX_MapByteStringToPtr::RemoveAll() { |
| 182 if (m_pHashTable != NULL) { |
| 183 for (FX_DWORD nHash = 0; nHash < m_nHashTableSize; nHash++) { |
| 184 CAssoc* pAssoc; |
| 185 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; |
| 186 pAssoc = pAssoc->pNext) { |
| 187 DestructElement(&pAssoc->key); |
| 188 } |
| 189 } |
| 190 FX_Free(m_pHashTable); |
| 191 m_pHashTable = NULL; |
| 192 } |
| 193 m_nCount = 0; |
| 194 m_pFreeList = NULL; |
| 195 m_pBlocks->FreeDataChain(); |
| 196 m_pBlocks = NULL; |
| 197 } |
| 198 CFX_MapByteStringToPtr::~CFX_MapByteStringToPtr() { |
| 199 RemoveAll(); |
| 200 ASSERT(m_nCount == 0); |
| 201 } |
| 202 void CFX_MapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition, |
| 203 CFX_ByteString& rKey, |
| 204 void*& rValue) const { |
| 205 ASSERT(m_pHashTable != NULL); |
| 206 CAssoc* pAssocRet = (CAssoc*)rNextPosition; |
| 207 ASSERT(pAssocRet != NULL); |
| 208 if (pAssocRet == (CAssoc*)-1) { |
| 209 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) |
| 210 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { |
| 211 break; |
| 212 } |
52 ASSERT(pAssocRet != NULL); | 213 ASSERT(pAssocRet != NULL); |
53 if (pAssocRet == (CAssoc*) - 1) { | 214 } |
54 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) | 215 CAssoc* pAssocNext; |
55 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { | 216 if ((pAssocNext = pAssocRet->pNext) == NULL) { |
56 break; | 217 for (FX_DWORD nBucket = pAssocRet->nHashValue + 1; |
57 } | 218 nBucket < m_nHashTableSize; nBucket++) |
58 ASSERT(pAssocRet != NULL); | 219 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { |
59 } | 220 break; |
60 CAssoc* pAssocNext; | 221 } |
61 if ((pAssocNext = pAssocRet->pNext) == NULL) { | 222 } |
62 for (FX_DWORD nBucket = (HashKey(pAssocRet->key) % m_nHashTableSize) + 1
; nBucket < m_nHashTableSize; nBucket ++) { | 223 rNextPosition = (FX_POSITION)pAssocNext; |
63 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { | 224 rKey = pAssocRet->key; |
64 break; | 225 rValue = pAssocRet->value; |
65 } | 226 } |
66 } | 227 void* CFX_MapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const { |
67 } | 228 ASSERT(m_pHashTable != NULL); |
68 rNextPosition = (FX_POSITION) pAssocNext; | 229 CAssoc* pAssocRet = (CAssoc*)rNextPosition; |
69 rKey = pAssocRet->key; | 230 ASSERT(pAssocRet != NULL); |
70 rValue = pAssocRet->value; | 231 if (pAssocRet == (CAssoc*)-1) { |
71 } | 232 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) |
72 FX_BOOL CFX_MapPtrToPtr::Lookup(void* key, void*& rValue) const | 233 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { |
73 { | 234 break; |
74 FX_DWORD nHash; | 235 } |
75 CAssoc* pAssoc = GetAssocAt(key, nHash); | 236 ASSERT(pAssocRet != NULL); |
76 if (pAssoc == NULL) { | 237 } |
77 return FALSE; | 238 CAssoc* pAssocNext; |
78 } | 239 if ((pAssocNext = pAssocRet->pNext) == NULL) { |
79 rValue = pAssoc->value; | 240 for (FX_DWORD nBucket = pAssocRet->nHashValue + 1; |
80 return TRUE; | 241 nBucket < m_nHashTableSize; nBucket++) |
81 } | 242 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { |
82 void* CFX_MapPtrToPtr::GetValueAt(void* key) const | 243 break; |
83 { | 244 } |
84 FX_DWORD nHash; | 245 } |
85 CAssoc* pAssoc = GetAssocAt(key, nHash); | 246 rNextPosition = (FX_POSITION)pAssocNext; |
86 if (pAssoc == NULL) { | 247 return pAssocRet->value; |
87 return NULL; | 248 } |
88 } | 249 void*& CFX_MapByteStringToPtr::operator[](const CFX_ByteStringC& key) { |
89 return pAssoc->value; | 250 FX_DWORD nHash; |
90 } | 251 CAssoc* pAssoc; |
91 void*& CFX_MapPtrToPtr::operator[](void* key) | 252 if ((pAssoc = GetAssocAt(key, nHash)) == NULL) { |
92 { | |
93 FX_DWORD nHash; | |
94 CAssoc* pAssoc; | |
95 if ((pAssoc = GetAssocAt(key, nHash)) == NULL) { | |
96 if (m_pHashTable == NULL) { | |
97 InitHashTable(m_nHashTableSize); | |
98 } | |
99 pAssoc = NewAssoc(); | |
100 pAssoc->key = key; | |
101 pAssoc->pNext = m_pHashTable[nHash]; | |
102 m_pHashTable[nHash] = pAssoc; | |
103 } | |
104 return pAssoc->value; | |
105 } | |
106 CFX_MapPtrToPtr::CAssoc* | |
107 CFX_MapPtrToPtr::GetAssocAt(void* key, FX_DWORD& nHash) const | |
108 { | |
109 nHash = HashKey(key) % m_nHashTableSize; | |
110 if (m_pHashTable == NULL) { | 253 if (m_pHashTable == NULL) { |
111 return NULL; | 254 InitHashTable(m_nHashTableSize); |
112 } | 255 } |
113 CAssoc* pAssoc; | 256 pAssoc = NewAssoc(); |
114 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) { | 257 pAssoc->nHashValue = nHash; |
115 if (pAssoc->key == key) { | 258 pAssoc->key = key; |
116 return pAssoc; | 259 pAssoc->pNext = m_pHashTable[nHash]; |
117 } | 260 m_pHashTable[nHash] = pAssoc; |
118 } | 261 } |
| 262 return pAssoc->value; |
| 263 } |
| 264 CFX_MapByteStringToPtr::CAssoc* CFX_MapByteStringToPtr::NewAssoc() { |
| 265 if (m_pFreeList == NULL) { |
| 266 CFX_Plex* newBlock = CFX_Plex::Create( |
| 267 m_pBlocks, m_nBlockSize, sizeof(CFX_MapByteStringToPtr::CAssoc)); |
| 268 CFX_MapByteStringToPtr::CAssoc* pAssoc = |
| 269 (CFX_MapByteStringToPtr::CAssoc*)newBlock->data(); |
| 270 pAssoc += m_nBlockSize - 1; |
| 271 for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) { |
| 272 pAssoc->pNext = m_pFreeList; |
| 273 m_pFreeList = pAssoc; |
| 274 } |
| 275 } |
| 276 ASSERT(m_pFreeList != NULL); |
| 277 CFX_MapByteStringToPtr::CAssoc* pAssoc = m_pFreeList; |
| 278 m_pFreeList = m_pFreeList->pNext; |
| 279 m_nCount++; |
| 280 ASSERT(m_nCount > 0); |
| 281 ConstructElement(&pAssoc->key); |
| 282 pAssoc->value = 0; |
| 283 return pAssoc; |
| 284 } |
| 285 void CFX_MapByteStringToPtr::FreeAssoc(CFX_MapByteStringToPtr::CAssoc* pAssoc) { |
| 286 DestructElement(&pAssoc->key); |
| 287 pAssoc->pNext = m_pFreeList; |
| 288 m_pFreeList = pAssoc; |
| 289 m_nCount--; |
| 290 ASSERT(m_nCount >= 0); |
| 291 if (m_nCount == 0) { |
| 292 RemoveAll(); |
| 293 } |
| 294 } |
| 295 CFX_MapByteStringToPtr::CAssoc* CFX_MapByteStringToPtr::GetAssocAt( |
| 296 const CFX_ByteStringC& key, |
| 297 FX_DWORD& nHash) const { |
| 298 nHash = HashKey(key) % m_nHashTableSize; |
| 299 if (m_pHashTable == NULL) { |
119 return NULL; | 300 return NULL; |
120 } | 301 } |
121 CFX_MapPtrToPtr::CAssoc* | 302 CAssoc* pAssoc; |
122 CFX_MapPtrToPtr::NewAssoc() | 303 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) { |
123 { | 304 if (pAssoc->key == key) { |
124 if (m_pFreeList == NULL) { | 305 return pAssoc; |
125 CFX_Plex* newBlock = CFX_Plex::Create(m_pBlocks, m_nBlockSize, sizeof(CF
X_MapPtrToPtr::CAssoc)); | 306 } |
126 CFX_MapPtrToPtr::CAssoc* pAssoc = (CFX_MapPtrToPtr::CAssoc*)newBlock->da
ta(); | 307 } |
127 pAssoc += m_nBlockSize - 1; | 308 return NULL; |
128 for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) { | 309 } |
129 pAssoc->pNext = m_pFreeList; | 310 FX_BOOL CFX_MapByteStringToPtr::Lookup(const CFX_ByteStringC& key, |
130 m_pFreeList = pAssoc; | 311 void*& rValue) const { |
131 } | 312 FX_DWORD nHash; |
132 } | 313 CAssoc* pAssoc = GetAssocAt(key, nHash); |
133 ASSERT(m_pFreeList != NULL); | 314 if (pAssoc == NULL) { |
134 CFX_MapPtrToPtr::CAssoc* pAssoc = m_pFreeList; | |
135 m_pFreeList = m_pFreeList->pNext; | |
136 m_nCount++; | |
137 ASSERT(m_nCount > 0); | |
138 pAssoc->key = 0; | |
139 pAssoc->value = 0; | |
140 return pAssoc; | |
141 } | |
142 void CFX_MapPtrToPtr::InitHashTable( | |
143 FX_DWORD nHashSize, FX_BOOL bAllocNow) | |
144 { | |
145 ASSERT(m_nCount == 0); | |
146 ASSERT(nHashSize > 0); | |
147 if (m_pHashTable != NULL) { | |
148 FX_Free(m_pHashTable); | |
149 m_pHashTable = NULL; | |
150 } | |
151 if (bAllocNow) { | |
152 m_pHashTable = FX_Alloc(CAssoc*, nHashSize); | |
153 } | |
154 m_nHashTableSize = nHashSize; | |
155 } | |
156 FX_BOOL CFX_MapPtrToPtr::RemoveKey(void* key) | |
157 { | |
158 if (m_pHashTable == NULL) { | |
159 return FALSE; | |
160 } | |
161 CAssoc** ppAssocPrev; | |
162 ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize]; | |
163 CAssoc* pAssoc; | |
164 for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) { | |
165 if (pAssoc->key == key) { | |
166 *ppAssocPrev = pAssoc->pNext; | |
167 FreeAssoc(pAssoc); | |
168 return TRUE; | |
169 } | |
170 ppAssocPrev = &pAssoc->pNext; | |
171 } | |
172 return FALSE; | 315 return FALSE; |
173 } | 316 } |
174 void CFX_MapPtrToPtr::FreeAssoc(CFX_MapPtrToPtr::CAssoc* pAssoc) | 317 rValue = pAssoc->value; |
175 { | 318 return TRUE; |
176 pAssoc->pNext = m_pFreeList; | 319 } |
177 m_pFreeList = pAssoc; | 320 void CFX_MapByteStringToPtr::InitHashTable(FX_DWORD nHashSize, |
178 m_nCount--; | 321 FX_BOOL bAllocNow) { |
179 ASSERT(m_nCount >= 0); | 322 ASSERT(m_nCount == 0); |
180 if (m_nCount == 0) { | 323 ASSERT(nHashSize > 0); |
181 RemoveAll(); | 324 if (m_pHashTable != NULL) { |
182 } | 325 FX_Free(m_pHashTable); |
183 } | 326 m_pHashTable = NULL; |
184 CFX_MapByteStringToPtr::CFX_MapByteStringToPtr(int nBlockSize) | 327 } |
185 : m_pHashTable(NULL) | 328 if (bAllocNow) { |
186 , m_nHashTableSize(17) | 329 m_pHashTable = FX_Alloc(CAssoc*, nHashSize); |
187 , m_nCount(0) | 330 } |
188 , m_pFreeList(NULL) | 331 m_nHashTableSize = nHashSize; |
189 , m_pBlocks(NULL) | 332 } |
190 , m_nBlockSize(nBlockSize) | 333 inline FX_DWORD CFX_MapByteStringToPtr::HashKey( |
191 { | 334 const CFX_ByteStringC& key) const { |
192 ASSERT(m_nBlockSize > 0); | 335 FX_DWORD nHash = 0; |
193 } | 336 int len = key.GetLength(); |
194 void CFX_MapByteStringToPtr::RemoveAll() | 337 const uint8_t* buf = key.GetPtr(); |
195 { | 338 for (int i = 0; i < len; i++) { |
196 if (m_pHashTable != NULL) { | 339 nHash = (nHash << 5) + nHash + buf[i]; |
197 for (FX_DWORD nHash = 0; nHash < m_nHashTableSize; nHash++) { | 340 } |
198 CAssoc* pAssoc; | 341 return nHash; |
199 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; | 342 } |
200 pAssoc = pAssoc->pNext) { | 343 FX_BOOL CFX_MapByteStringToPtr::RemoveKey(const CFX_ByteStringC& key) { |
201 DestructElement(&pAssoc->key); | 344 if (m_pHashTable == NULL) { |
202 } | 345 return FALSE; |
203 } | 346 } |
204 FX_Free(m_pHashTable); | 347 CAssoc** ppAssocPrev; |
205 m_pHashTable = NULL; | 348 ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize]; |
206 } | 349 CAssoc* pAssoc; |
207 m_nCount = 0; | 350 for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) { |
208 m_pFreeList = NULL; | 351 if (pAssoc->key == key) { |
209 m_pBlocks->FreeDataChain(); | 352 *ppAssocPrev = pAssoc->pNext; |
210 m_pBlocks = NULL; | 353 FreeAssoc(pAssoc); |
211 } | 354 return TRUE; |
212 CFX_MapByteStringToPtr::~CFX_MapByteStringToPtr() | 355 } |
213 { | 356 ppAssocPrev = &pAssoc->pNext; |
214 RemoveAll(); | 357 } |
215 ASSERT(m_nCount == 0); | 358 return FALSE; |
216 } | 359 } |
217 void CFX_MapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition, | 360 struct _CompactString { |
218 CFX_ByteString& rKey, void*& rValue) const | 361 uint8_t m_CompactLen; |
219 { | 362 uint8_t m_LenHigh; |
220 ASSERT(m_pHashTable != NULL); | 363 uint8_t m_LenLow; |
221 CAssoc* pAssocRet = (CAssoc*)rNextPosition; | 364 uint8_t m_Unused; |
222 ASSERT(pAssocRet != NULL); | 365 uint8_t* m_pBuffer; |
223 if (pAssocRet == (CAssoc*) - 1) { | 366 }; |
224 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) | 367 static void _CompactStringRelease(_CompactString* pCompact) { |
225 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { | 368 if (pCompact->m_CompactLen == 0xff) { |
226 break; | 369 FX_Free(pCompact->m_pBuffer); |
227 } | 370 } |
228 ASSERT(pAssocRet != NULL); | 371 } |
229 } | 372 static FX_BOOL _CompactStringSame(_CompactString* pCompact, |
230 CAssoc* pAssocNext; | 373 const uint8_t* pStr, |
231 if ((pAssocNext = pAssocRet->pNext) == NULL) { | 374 int len) { |
232 for (FX_DWORD nBucket = pAssocRet->nHashValue + 1; | 375 if (len < sizeof(_CompactString)) { |
233 nBucket < m_nHashTableSize; nBucket++) | 376 if (pCompact->m_CompactLen != len) { |
234 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { | 377 return FALSE; |
235 break; | 378 } |
236 } | 379 return FXSYS_memcmp(&pCompact->m_LenHigh, pStr, len) == 0; |
237 } | 380 } |
238 rNextPosition = (FX_POSITION) pAssocNext; | 381 if (pCompact->m_CompactLen != 0xff || |
239 rKey = pAssocRet->key; | 382 pCompact->m_LenHigh * 256 + pCompact->m_LenLow != len) { |
240 rValue = pAssocRet->value; | 383 return FALSE; |
241 } | 384 } |
242 void* CFX_MapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const | 385 return FXSYS_memcmp(pCompact->m_pBuffer, pStr, len) == 0; |
243 { | 386 } |
244 ASSERT(m_pHashTable != NULL); | 387 static void _CompactStringStore(_CompactString* pCompact, |
245 CAssoc* pAssocRet = (CAssoc*)rNextPosition; | 388 const uint8_t* pStr, |
246 ASSERT(pAssocRet != NULL); | 389 int len) { |
247 if (pAssocRet == (CAssoc*) - 1) { | 390 if (len < (int)sizeof(_CompactString)) { |
248 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) | 391 pCompact->m_CompactLen = (uint8_t)len; |
249 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { | 392 FXSYS_memcpy(&pCompact->m_LenHigh, pStr, len); |
250 break; | 393 return; |
251 } | 394 } |
252 ASSERT(pAssocRet != NULL); | 395 pCompact->m_CompactLen = 0xff; |
253 } | 396 pCompact->m_LenHigh = len / 256; |
254 CAssoc* pAssocNext; | 397 pCompact->m_LenLow = len % 256; |
255 if ((pAssocNext = pAssocRet->pNext) == NULL) { | 398 pCompact->m_pBuffer = FX_Alloc(uint8_t, len); |
256 for (FX_DWORD nBucket = pAssocRet->nHashValue + 1; | 399 FXSYS_memcpy(pCompact->m_pBuffer, pStr, len); |
257 nBucket < m_nHashTableSize; nBucket++) | 400 } |
258 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { | 401 static CFX_ByteStringC _CompactStringGet(_CompactString* pCompact) { |
259 break; | 402 if (pCompact->m_CompactLen == 0xff) { |
260 } | 403 return CFX_ByteStringC(pCompact->m_pBuffer, |
261 } | 404 pCompact->m_LenHigh * 256 + pCompact->m_LenLow); |
262 rNextPosition = (FX_POSITION) pAssocNext; | 405 } |
263 return pAssocRet->value; | 406 if (pCompact->m_CompactLen == 0xfe) { |
264 } | 407 return CFX_ByteStringC(); |
265 void*& CFX_MapByteStringToPtr::operator[](const CFX_ByteStringC& key) | 408 } |
266 { | 409 return CFX_ByteStringC(&pCompact->m_LenHigh, pCompact->m_CompactLen); |
267 FX_DWORD nHash; | 410 } |
268 CAssoc* pAssoc; | 411 #define CMAP_ALLOC_STEP 8 |
269 if ((pAssoc = GetAssocAt(key, nHash)) == NULL) { | 412 #define CMAP_INDEX_SIZE 8 |
270 if (m_pHashTable == NULL) { | 413 CFX_CMapByteStringToPtr::CFX_CMapByteStringToPtr() |
271 InitHashTable(m_nHashTableSize); | 414 : m_Buffer(sizeof(_CompactString) + sizeof(void*), |
272 } | 415 CMAP_ALLOC_STEP, |
273 pAssoc = NewAssoc(); | 416 CMAP_INDEX_SIZE) {} |
274 pAssoc->nHashValue = nHash; | 417 CFX_CMapByteStringToPtr::~CFX_CMapByteStringToPtr() { |
275 pAssoc->key = key; | 418 RemoveAll(); |
276 pAssoc->pNext = m_pHashTable[nHash]; | 419 } |
277 m_pHashTable[nHash] = pAssoc; | 420 void CFX_CMapByteStringToPtr::RemoveAll() { |
278 } | 421 int size = m_Buffer.GetSize(); |
279 return pAssoc->value; | 422 for (int i = 0; i < size; i++) { |
280 } | 423 _CompactStringRelease((_CompactString*)m_Buffer.GetAt(i)); |
281 CFX_MapByteStringToPtr::CAssoc* | 424 } |
282 CFX_MapByteStringToPtr::NewAssoc() | 425 m_Buffer.RemoveAll(); |
283 { | 426 } |
284 if (m_pFreeList == NULL) { | 427 FX_POSITION CFX_CMapByteStringToPtr::GetStartPosition() const { |
285 CFX_Plex* newBlock = CFX_Plex::Create(m_pBlocks, m_nBlockSize, sizeof(CF
X_MapByteStringToPtr::CAssoc)); | 428 int size = m_Buffer.GetSize(); |
286 CFX_MapByteStringToPtr::CAssoc* pAssoc = (CFX_MapByteStringToPtr::CAssoc
*)newBlock->data(); | 429 for (int i = 0; i < size; i++) { |
287 pAssoc += m_nBlockSize - 1; | 430 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(i); |
288 for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) { | 431 if (pKey->m_CompactLen != 0xfe) { |
289 pAssoc->pNext = m_pFreeList; | 432 return (FX_POSITION)(uintptr_t)(i + 1); |
290 m_pFreeList = pAssoc; | 433 } |
291 } | 434 } |
292 } | 435 return NULL; |
293 ASSERT(m_pFreeList != NULL); | 436 } |
294 CFX_MapByteStringToPtr::CAssoc* pAssoc = m_pFreeList; | 437 void CFX_CMapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition, |
295 m_pFreeList = m_pFreeList->pNext; | 438 CFX_ByteString& rKey, |
296 m_nCount++; | 439 void*& rValue) const { |
297 ASSERT(m_nCount > 0); | 440 if (rNextPosition == NULL) { |
298 ConstructElement(&pAssoc->key); | 441 return; |
299 pAssoc->value = 0; | 442 } |
300 return pAssoc; | 443 int index = (int)(uintptr_t)rNextPosition - 1; |
301 } | 444 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); |
302 void CFX_MapByteStringToPtr::FreeAssoc(CFX_MapByteStringToPtr::CAssoc* pAssoc) | 445 rKey = _CompactStringGet(pKey); |
303 { | 446 rValue = *(void**)(pKey + 1); |
304 DestructElement(&pAssoc->key); | 447 index++; |
305 pAssoc->pNext = m_pFreeList; | 448 int size = m_Buffer.GetSize(); |
306 m_pFreeList = pAssoc; | 449 while (index < size) { |
307 m_nCount--; | 450 pKey = (_CompactString*)m_Buffer.GetAt(index); |
308 ASSERT(m_nCount >= 0); | 451 if (pKey->m_CompactLen != 0xfe) { |
309 if (m_nCount == 0) { | 452 rNextPosition = (FX_POSITION)(uintptr_t)(index + 1); |
310 RemoveAll(); | 453 return; |
311 } | 454 } |
312 } | 455 index++; |
313 CFX_MapByteStringToPtr::CAssoc* | 456 } |
314 CFX_MapByteStringToPtr::GetAssocAt(const CFX_ByteStringC& key, FX_DWORD& nHash)
const | 457 rNextPosition = NULL; |
315 { | 458 } |
316 nHash = HashKey(key) % m_nHashTableSize; | 459 void* CFX_CMapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const { |
317 if (m_pHashTable == NULL) { | 460 if (rNextPosition == NULL) { |
318 return NULL; | |
319 } | |
320 CAssoc* pAssoc; | |
321 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) { | |
322 if (pAssoc->key == key) { | |
323 return pAssoc; | |
324 } | |
325 } | |
326 return NULL; | 461 return NULL; |
327 } | 462 } |
328 FX_BOOL CFX_MapByteStringToPtr::Lookup(const CFX_ByteStringC& key, void*& rValue
) const | 463 int index = (int)(uintptr_t)rNextPosition - 1; |
329 { | 464 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); |
330 FX_DWORD nHash; | 465 void* rValue = *(void**)(pKey + 1); |
331 CAssoc* pAssoc = GetAssocAt(key, nHash); | 466 index++; |
332 if (pAssoc == NULL) { | 467 int size = m_Buffer.GetSize(); |
333 return FALSE; | 468 while (index < size) { |
334 } | 469 pKey = (_CompactString*)m_Buffer.GetAt(index); |
335 rValue = pAssoc->value; | 470 if (pKey->m_CompactLen != 0xfe) { |
336 return TRUE; | 471 rNextPosition = (FX_POSITION)(uintptr_t)(index + 1); |
337 } | 472 return rValue; |
338 void CFX_MapByteStringToPtr::InitHashTable( | 473 } |
339 FX_DWORD nHashSize, FX_BOOL bAllocNow) | 474 index++; |
340 { | 475 } |
341 ASSERT(m_nCount == 0); | 476 rNextPosition = NULL; |
342 ASSERT(nHashSize > 0); | 477 return rValue; |
343 if (m_pHashTable != NULL) { | 478 } |
344 FX_Free(m_pHashTable); | 479 FX_BOOL _CMapLookupCallback(void* param, void* pData) { |
345 m_pHashTable = NULL; | 480 return !_CompactStringSame((_CompactString*)pData, |
346 } | 481 ((CFX_ByteStringC*)param)->GetPtr(), |
347 if (bAllocNow) { | 482 ((CFX_ByteStringC*)param)->GetLength()); |
348 m_pHashTable = FX_Alloc(CAssoc*, nHashSize); | 483 } |
349 } | 484 FX_BOOL CFX_CMapByteStringToPtr::Lookup(const CFX_ByteStringC& key, |
350 m_nHashTableSize = nHashSize; | 485 void*& rValue) const { |
351 } | 486 void* p = m_Buffer.Iterate(_CMapLookupCallback, (void*)&key); |
352 inline FX_DWORD CFX_MapByteStringToPtr::HashKey(const CFX_ByteStringC& key) cons
t | 487 if (!p) { |
353 { | |
354 FX_DWORD nHash = 0; | |
355 int len = key.GetLength(); | |
356 const uint8_t* buf = key.GetPtr(); | |
357 for (int i = 0; i < len; i ++) { | |
358 nHash = (nHash << 5) + nHash + buf[i]; | |
359 } | |
360 return nHash; | |
361 } | |
362 FX_BOOL CFX_MapByteStringToPtr::RemoveKey(const CFX_ByteStringC& key) | |
363 { | |
364 if (m_pHashTable == NULL) { | |
365 return FALSE; | |
366 } | |
367 CAssoc** ppAssocPrev; | |
368 ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize]; | |
369 CAssoc* pAssoc; | |
370 for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) { | |
371 if (pAssoc->key == key) { | |
372 *ppAssocPrev = pAssoc->pNext; | |
373 FreeAssoc(pAssoc); | |
374 return TRUE; | |
375 } | |
376 ppAssocPrev = &pAssoc->pNext; | |
377 } | |
378 return FALSE; | 488 return FALSE; |
379 } | 489 } |
380 struct _CompactString { | 490 rValue = *(void**)((_CompactString*)p + 1); |
381 uint8_t» » m_CompactLen; | 491 return TRUE; |
382 uint8_t» » m_LenHigh; | 492 } |
383 uint8_t» » m_LenLow; | 493 void CFX_CMapByteStringToPtr::SetAt(const CFX_ByteStringC& key, void* value) { |
384 uint8_t» » m_Unused; | 494 ASSERT(value != NULL); |
385 uint8_t*» m_pBuffer; | 495 int index, key_len = key.GetLength(); |
386 }; | 496 int size = m_Buffer.GetSize(); |
387 static void _CompactStringRelease(_CompactString* pCompact) | 497 for (index = 0; index < size; index++) { |
388 { | |
389 if (pCompact->m_CompactLen == 0xff) { | |
390 FX_Free(pCompact->m_pBuffer); | |
391 } | |
392 } | |
393 static FX_BOOL _CompactStringSame(_CompactString* pCompact, const uint8_t* pStr,
int len) | |
394 { | |
395 if (len < sizeof(_CompactString)) { | |
396 if (pCompact->m_CompactLen != len) { | |
397 return FALSE; | |
398 } | |
399 return FXSYS_memcmp(&pCompact->m_LenHigh, pStr, len) == 0; | |
400 } | |
401 if (pCompact->m_CompactLen != 0xff || pCompact->m_LenHigh * 256 + pCompact->
m_LenLow != len) { | |
402 return FALSE; | |
403 } | |
404 return FXSYS_memcmp(pCompact->m_pBuffer, pStr, len) == 0; | |
405 } | |
406 static void _CompactStringStore(_CompactString* pCompact, const uint8_t* pStr, i
nt len) | |
407 { | |
408 if (len < (int)sizeof(_CompactString)) { | |
409 pCompact->m_CompactLen = (uint8_t)len; | |
410 FXSYS_memcpy(&pCompact->m_LenHigh, pStr, len); | |
411 return; | |
412 } | |
413 pCompact->m_CompactLen = 0xff; | |
414 pCompact->m_LenHigh = len / 256; | |
415 pCompact->m_LenLow = len % 256; | |
416 pCompact->m_pBuffer = FX_Alloc(uint8_t, len); | |
417 FXSYS_memcpy(pCompact->m_pBuffer, pStr, len); | |
418 } | |
419 static CFX_ByteStringC _CompactStringGet(_CompactString* pCompact) | |
420 { | |
421 if (pCompact->m_CompactLen == 0xff) { | |
422 return CFX_ByteStringC(pCompact->m_pBuffer, pCompact->m_LenHigh * 256 +
pCompact->m_LenLow); | |
423 } | |
424 if (pCompact->m_CompactLen == 0xfe) { | |
425 return CFX_ByteStringC(); | |
426 } | |
427 return CFX_ByteStringC(&pCompact->m_LenHigh, pCompact->m_CompactLen); | |
428 } | |
429 #define CMAP_ALLOC_STEP»» 8 | |
430 #define CMAP_INDEX_SIZE»» 8 | |
431 CFX_CMapByteStringToPtr::CFX_CMapByteStringToPtr() | |
432 : m_Buffer(sizeof(_CompactString) + sizeof(void*), CMAP_ALLOC_STEP, CMAP_IND
EX_SIZE) | |
433 { | |
434 } | |
435 CFX_CMapByteStringToPtr::~CFX_CMapByteStringToPtr() | |
436 { | |
437 RemoveAll(); | |
438 } | |
439 void CFX_CMapByteStringToPtr::RemoveAll() | |
440 { | |
441 int size = m_Buffer.GetSize(); | |
442 for (int i = 0; i < size; i++) { | |
443 _CompactStringRelease((_CompactString*)m_Buffer.GetAt(i)); | |
444 } | |
445 m_Buffer.RemoveAll(); | |
446 } | |
447 FX_POSITION CFX_CMapByteStringToPtr::GetStartPosition() const | |
448 { | |
449 int size = m_Buffer.GetSize(); | |
450 for (int i = 0; i < size; i ++) { | |
451 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(i); | |
452 if (pKey->m_CompactLen != 0xfe) { | |
453 return (FX_POSITION)(uintptr_t)(i + 1); | |
454 } | |
455 } | |
456 return NULL; | |
457 } | |
458 void CFX_CMapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition, CFX_ByteS
tring& rKey, void*& rValue) const | |
459 { | |
460 if (rNextPosition == NULL) { | |
461 return; | |
462 } | |
463 int index = (int)(uintptr_t)rNextPosition - 1; | |
464 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); | 498 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); |
465 rKey = _CompactStringGet(pKey); | 499 if (!_CompactStringSame(pKey, key.GetPtr(), key_len)) { |
466 rValue = *(void**)(pKey + 1); | 500 continue; |
467 index ++; | 501 } |
468 int size = m_Buffer.GetSize(); | 502 *(void**)(pKey + 1) = value; |
469 while (index < size) { | 503 return; |
470 pKey = (_CompactString*)m_Buffer.GetAt(index); | 504 } |
471 if (pKey->m_CompactLen != 0xfe) { | 505 for (index = 0; index < size; index++) { |
472 rNextPosition = (FX_POSITION)(uintptr_t)(index + 1); | |
473 return; | |
474 } | |
475 index ++; | |
476 } | |
477 rNextPosition = NULL; | |
478 } | |
479 void* CFX_CMapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const | |
480 { | |
481 if (rNextPosition == NULL) { | |
482 return NULL; | |
483 } | |
484 int index = (int)(uintptr_t)rNextPosition - 1; | |
485 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); | 506 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); |
486 void* rValue = *(void**)(pKey + 1); | 507 if (pKey->m_CompactLen) { |
487 index ++; | 508 continue; |
488 int size = m_Buffer.GetSize(); | 509 } |
489 while (index < size) { | |
490 pKey = (_CompactString*)m_Buffer.GetAt(index); | |
491 if (pKey->m_CompactLen != 0xfe) { | |
492 rNextPosition = (FX_POSITION)(uintptr_t)(index + 1); | |
493 return rValue; | |
494 } | |
495 index ++; | |
496 } | |
497 rNextPosition = NULL; | |
498 return rValue; | |
499 } | |
500 FX_BOOL _CMapLookupCallback(void* param, void* pData) | |
501 { | |
502 return !_CompactStringSame((_CompactString*)pData, ((CFX_ByteStringC*)param)
->GetPtr(), ((CFX_ByteStringC*)param)->GetLength()); | |
503 } | |
504 FX_BOOL CFX_CMapByteStringToPtr::Lookup(const CFX_ByteStringC& key, void*& rValu
e) const | |
505 { | |
506 void* p = m_Buffer.Iterate(_CMapLookupCallback, (void*)&key); | |
507 if (!p) { | |
508 return FALSE; | |
509 } | |
510 rValue = *(void**)((_CompactString*)p + 1); | |
511 return TRUE; | |
512 } | |
513 void CFX_CMapByteStringToPtr::SetAt(const CFX_ByteStringC& key, void* value) | |
514 { | |
515 ASSERT(value != NULL); | |
516 int index, key_len = key.GetLength(); | |
517 int size = m_Buffer.GetSize(); | |
518 for (index = 0; index < size; index ++) { | |
519 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); | |
520 if (!_CompactStringSame(pKey, key.GetPtr(), key_len)) { | |
521 continue; | |
522 } | |
523 *(void**)(pKey + 1) = value; | |
524 return; | |
525 } | |
526 for (index = 0; index < size; index ++) { | |
527 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); | |
528 if (pKey->m_CompactLen) { | |
529 continue; | |
530 } | |
531 _CompactStringStore(pKey, key.GetPtr(), key_len); | |
532 *(void**)(pKey + 1) = value; | |
533 return; | |
534 } | |
535 _CompactString* pKey = (_CompactString*)m_Buffer.Add(); | |
536 _CompactStringStore(pKey, key.GetPtr(), key_len); | 510 _CompactStringStore(pKey, key.GetPtr(), key_len); |
537 *(void**)(pKey + 1) = value; | 511 *(void**)(pKey + 1) = value; |
538 } | 512 return; |
539 void CFX_CMapByteStringToPtr::AddValue(const CFX_ByteStringC& key, void* value) | 513 } |
540 { | 514 _CompactString* pKey = (_CompactString*)m_Buffer.Add(); |
541 ASSERT(value != NULL); | 515 _CompactStringStore(pKey, key.GetPtr(), key_len); |
542 _CompactString* pKey = (_CompactString*)m_Buffer.Add(); | 516 *(void**)(pKey + 1) = value; |
543 _CompactStringStore(pKey, key.GetPtr(), key.GetLength()); | 517 } |
544 *(void**)(pKey + 1) = value; | 518 void CFX_CMapByteStringToPtr::AddValue(const CFX_ByteStringC& key, |
545 } | 519 void* value) { |
546 void CFX_CMapByteStringToPtr::RemoveKey(const CFX_ByteStringC& key) | 520 ASSERT(value != NULL); |
547 { | 521 _CompactString* pKey = (_CompactString*)m_Buffer.Add(); |
548 int key_len = key.GetLength(); | 522 _CompactStringStore(pKey, key.GetPtr(), key.GetLength()); |
549 int size = m_Buffer.GetSize(); | 523 *(void**)(pKey + 1) = value; |
550 for (int index = 0; index < size; index++) { | 524 } |
551 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); | 525 void CFX_CMapByteStringToPtr::RemoveKey(const CFX_ByteStringC& key) { |
552 if (!_CompactStringSame(pKey, key.GetPtr(), key_len)) { | 526 int key_len = key.GetLength(); |
553 continue; | 527 int size = m_Buffer.GetSize(); |
554 } | 528 for (int index = 0; index < size; index++) { |
555 _CompactStringRelease(pKey); | 529 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); |
556 pKey->m_CompactLen = 0xfe; | 530 if (!_CompactStringSame(pKey, key.GetPtr(), key_len)) { |
557 return; | 531 continue; |
558 } | 532 } |
559 } | 533 _CompactStringRelease(pKey); |
560 int CFX_CMapByteStringToPtr::GetCount() const | 534 pKey->m_CompactLen = 0xfe; |
561 { | 535 return; |
562 int count = 0; | 536 } |
563 int size = m_Buffer.GetSize(); | 537 } |
564 for (int i = 0; i < size; i ++) { | 538 int CFX_CMapByteStringToPtr::GetCount() const { |
565 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(i); | 539 int count = 0; |
566 if (pKey->m_CompactLen != 0xfe) { | 540 int size = m_Buffer.GetSize(); |
567 count ++; | 541 for (int i = 0; i < size; i++) { |
568 } | 542 _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(i); |
569 } | 543 if (pKey->m_CompactLen != 0xfe) { |
570 return count; | 544 count++; |
| 545 } |
| 546 } |
| 547 return count; |
571 } | 548 } |
572 extern "C" { | 549 extern "C" { |
573 static int _CompareDWord(const void* p1, const void* p2) | 550 static int _CompareDWord(const void* p1, const void* p2) { |
574 { | 551 return (*(FX_DWORD*)p1) - (*(FX_DWORD*)p2); |
575 return (*(FX_DWORD*)p1) - (*(FX_DWORD*)p2); | 552 } |
576 } | |
577 }; | 553 }; |
578 struct _DWordPair { | 554 struct _DWordPair { |
579 FX_DWORD key; | 555 FX_DWORD key; |
580 FX_DWORD value; | 556 FX_DWORD value; |
581 }; | 557 }; |
582 FX_BOOL CFX_CMapDWordToDWord::Lookup(FX_DWORD key, FX_DWORD& value) const | 558 FX_BOOL CFX_CMapDWordToDWord::Lookup(FX_DWORD key, FX_DWORD& value) const { |
583 { | 559 void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), |
584 void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), m_Buffer.GetSize()
/ sizeof(_DWordPair), | 560 m_Buffer.GetSize() / sizeof(_DWordPair), |
585 sizeof(_DWordPair), _CompareDWord); | 561 sizeof(_DWordPair), _CompareDWord); |
586 if (pResult == NULL) { | 562 if (pResult == NULL) { |
587 return FALSE; | 563 return FALSE; |
588 } | 564 } |
589 value = ((FX_DWORD*)pResult)[1]; | 565 value = ((FX_DWORD*)pResult)[1]; |
590 return TRUE; | 566 return TRUE; |
591 } | 567 } |
592 FX_POSITION CFX_CMapDWordToDWord::GetStartPosition() const | 568 FX_POSITION CFX_CMapDWordToDWord::GetStartPosition() const { |
593 { | 569 FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair); |
594 FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair); | 570 if (count == 0) { |
595 if (count == 0) { | 571 return NULL; |
596 return NULL; | 572 } |
597 } | 573 return (FX_POSITION)1; |
598 return (FX_POSITION)1; | 574 } |
599 } | 575 void CFX_CMapDWordToDWord::GetNextAssoc(FX_POSITION& pos, |
600 void CFX_CMapDWordToDWord::GetNextAssoc(FX_POSITION& pos, FX_DWORD& key, FX_DWOR
D& value) const | 576 FX_DWORD& key, |
601 { | 577 FX_DWORD& value) const { |
602 if (pos == 0) { | 578 if (pos == 0) { |
603 return; | 579 return; |
604 } | 580 } |
605 FX_DWORD index = ((FX_DWORD)(uintptr_t)pos) - 1; | 581 FX_DWORD index = ((FX_DWORD)(uintptr_t)pos) - 1; |
606 FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair); | 582 FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair); |
607 _DWordPair* buf = (_DWordPair*)m_Buffer.GetBuffer(); | 583 _DWordPair* buf = (_DWordPair*)m_Buffer.GetBuffer(); |
608 key = buf[index].key; | 584 key = buf[index].key; |
609 value = buf[index].value; | 585 value = buf[index].value; |
610 if (index == count - 1) { | 586 if (index == count - 1) { |
611 pos = 0; | 587 pos = 0; |
| 588 } else { |
| 589 pos = (FX_POSITION)((uintptr_t)pos + 1); |
| 590 } |
| 591 } |
| 592 void CFX_CMapDWordToDWord::SetAt(FX_DWORD key, FX_DWORD value) { |
| 593 FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair); |
| 594 _DWordPair* buf = (_DWordPair*)m_Buffer.GetBuffer(); |
| 595 _DWordPair pair = {key, value}; |
| 596 if (count == 0 || key > buf[count - 1].key) { |
| 597 m_Buffer.AppendBlock(&pair, sizeof(_DWordPair)); |
| 598 return; |
| 599 } |
| 600 int low = 0, high = count - 1; |
| 601 while (low <= high) { |
| 602 int mid = (low + high) / 2; |
| 603 if (buf[mid].key < key) { |
| 604 low = mid + 1; |
| 605 } else if (buf[mid].key > key) { |
| 606 high = mid - 1; |
612 } else { | 607 } else { |
613 pos = (FX_POSITION)((uintptr_t)pos + 1); | 608 buf[mid].value = value; |
614 } | 609 return; |
615 } | 610 } |
616 void CFX_CMapDWordToDWord::SetAt(FX_DWORD key, FX_DWORD value) | 611 } |
617 { | 612 m_Buffer.InsertBlock(low * sizeof(_DWordPair), &pair, sizeof(_DWordPair)); |
618 FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair); | 613 } |
619 _DWordPair* buf = (_DWordPair*)m_Buffer.GetBuffer(); | 614 void CFX_CMapDWordToDWord::EstimateSize(FX_DWORD size, FX_DWORD grow_by) { |
620 _DWordPair pair = {key, value}; | 615 m_Buffer.EstimateSize(size, grow_by); |
621 if (count == 0 || key > buf[count - 1].key) { | 616 } |
622 m_Buffer.AppendBlock(&pair, sizeof(_DWordPair)); | |
623 return; | |
624 } | |
625 int low = 0, high = count - 1; | |
626 while (low <= high) { | |
627 int mid = (low + high) / 2; | |
628 if (buf[mid].key < key) { | |
629 low = mid + 1; | |
630 } else if (buf[mid].key > key) { | |
631 high = mid - 1; | |
632 } else { | |
633 buf[mid].value = value; | |
634 return; | |
635 } | |
636 } | |
637 m_Buffer.InsertBlock(low * sizeof(_DWordPair), &pair, sizeof(_DWordPair)); | |
638 } | |
639 void CFX_CMapDWordToDWord::EstimateSize(FX_DWORD size, FX_DWORD grow_by) | |
640 { | |
641 m_Buffer.EstimateSize(size, grow_by); | |
642 } | |
OLD | NEW |