| 272 | } |
| 273 | |
| 274 | bool Insert(const TKey& key, bool forceAdd, TKey** keyPtr, TValue** valuePtr) |
| 275 | { |
| 276 | if (mBuckets == NULL) Initialize(0); |
| 277 | int_cosize hashCode = (int_cosize)BeefHash<TKey>()(key) & 0x7FFFFFFF; |
| 278 | int_cosize targetBucket = hashCode % (int_cosize)mAllocSize; |
| 279 | |
| 280 | if (!forceAdd) |
| 281 | { |
| 282 | for (int_cosize i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext) |
| 283 | { |
| 284 | if ((mEntries[i].mHashCode == hashCode) && (*(TKey*)&mEntries[i].mKey == key)) |
| 285 | { |
| 286 | if (keyPtr != NULL) |
| 287 | *keyPtr = (TKey*)&mEntries[i].mKey; |
| 288 | if (valuePtr != NULL) |
| 289 | *valuePtr = (TValue*)&mEntries[i].mValue; |
| 290 | return false; |
| 291 | } |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | int_cosize index; |
| 296 | if (mFreeCount > 0) |
| 297 | { |
| 298 | index = mFreeList; |
| 299 | mFreeList = mEntries[index].mNext; |
| 300 | mFreeCount--; |
| 301 | } |
| 302 | else |
| 303 | { |
| 304 | if (mCount == mAllocSize) |
| 305 | { |
| 306 | Resize(); |
| 307 | targetBucket = hashCode % (int_cosize)mAllocSize; |
| 308 | } |
| 309 | index = mCount; |
| 310 | mCount++; |
| 311 | } |
| 312 | |
| 313 | mEntries[index].mHashCode = hashCode; |
| 314 | mEntries[index].mNext = mBuckets[targetBucket]; |
| 315 | new (&mEntries[index].mKey) TKey(key); |
| 316 | mBuckets[targetBucket] = index; |
| 317 | |
| 318 | if (keyPtr != NULL) |
| 319 | *keyPtr = (TKey*)&mEntries[index].mKey; |
| 320 | if (valuePtr != NULL) |
| 321 | *valuePtr = (TValue*)&mEntries[index].mValue; |
| 322 | return true; |
| 323 | } |
| 324 | |
| 325 | void RemoveIdx(int_cosize bucket, int_cosize i, int_cosize last) |
| 326 | { |