| 295 | } |
| 296 | |
| 297 | Dictionary::Entry *Dictionary::add(StringTableEntry name) |
| 298 | { |
| 299 | // Try to find an existing match. |
| 300 | //printf("Add Variable %s\n", name); |
| 301 | |
| 302 | Entry* ret = lookup(name); |
| 303 | if (ret) |
| 304 | return ret; |
| 305 | |
| 306 | // Rehash if the table get's too crowded. Be aware that this might |
| 307 | // modify a table that we don't own. |
| 308 | |
| 309 | hashTable->count++; |
| 310 | if (hashTable->count > hashTable->size * 2) |
| 311 | { |
| 312 | // Allocate a new table. |
| 313 | |
| 314 | const U32 newTableSize = hashTable->size * 4 - 1; |
| 315 | Entry** newTableData = new Entry*[newTableSize]; |
| 316 | dMemset(newTableData, 0, newTableSize * sizeof(Entry*)); |
| 317 | |
| 318 | // Move the entries over. |
| 319 | |
| 320 | for (U32 i = 0; i < hashTable->size; ++i) |
| 321 | for (Entry* entry = hashTable->data[i]; entry != NULL; ) |
| 322 | { |
| 323 | Entry* next = entry->nextEntry; |
| 324 | U32 index = HashPointer(entry->name) % newTableSize; |
| 325 | |
| 326 | entry->nextEntry = newTableData[index]; |
| 327 | newTableData[index] = entry; |
| 328 | |
| 329 | entry = next; |
| 330 | } |
| 331 | |
| 332 | // Switch the tables. |
| 333 | |
| 334 | delete[] hashTable->data; |
| 335 | hashTable->data = newTableData; |
| 336 | hashTable->size = newTableSize; |
| 337 | } |
| 338 | |
| 339 | #ifdef DEBUG_SPEW |
| 340 | Platform::outputDebugString("[ConsoleInternal] Adding entry '%s'", name); |
| 341 | #endif |
| 342 | |
| 343 | // Add the new entry. |
| 344 | |
| 345 | ret = hashTable->mChunker.alloc(); |
| 346 | constructInPlace(ret, name); |
| 347 | U32 idx = HashPointer(name) % hashTable->size; |
| 348 | ret->nextEntry = hashTable->data[idx]; |
| 349 | hashTable->data[idx] = ret; |
| 350 | |
| 351 | return ret; |
| 352 | } |
| 353 | |
| 354 | // deleteVariables() assumes remove() is a stable remove (will not reorder entries on remove) |
nothing calls this directly
no test coverage detected