Differences From Artifact [8775708778]:
- File
src/OFMapTable.m
— part of check-in
[aeb403a1ed]
at
2020-10-10 14:27:37
on branch trunk
— OFObject: Change type of -[hash] to unsigned long
The internal hash is still 32 bit in most places, but this way, it is at
least not baked into the API and ABI and can be upgraded later, should
that ever be necessary. (user: js, size: 16545) [annotate] [blame] [check-ins using]
To Artifact [bb1c57067e]:
- File src/OFMapTable.m — part of check-in [da1fb6b21c] at 2020-11-05 02:27:35 on branch trunk — Further reduce usage of -[allocMemoryWithSize:] (user: js, size: 16387) [annotate] [blame] [check-ins using] [more...]
︙ | ︙ | |||
159 160 161 162 163 164 165 | if (capacity * 8 / _capacity >= 6) if (_capacity <= ULONG_MAX / 2) _capacity *= 2; if (_capacity < MIN_CAPACITY) _capacity = MIN_CAPACITY; | | < | > | > > > | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | if (capacity * 8 / _capacity >= 6) if (_capacity <= ULONG_MAX / 2) _capacity *= 2; if (_capacity < MIN_CAPACITY) _capacity = MIN_CAPACITY; _buckets = of_calloc(_capacity, sizeof(*_buckets)); if (of_hash_seed != 0) _rotate = of_random16() & 31; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { for (unsigned long i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deleted) { _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); free(_buckets[i]); } } free(_buckets); [super dealloc]; } - (bool)isEqual: (id)object { OFMapTable *mapTable; |
︙ | ︙ | |||
318 319 320 321 322 323 324 | /* * Don't downsize if we have an initial capacity or if we would fall * below the minimum capacity. */ if ((capacity < _capacity && count > _count) || capacity < MIN_CAPACITY) return; | | < | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | /* * Don't downsize if we have an initial capacity or if we would fall * below the minimum capacity. */ if ((capacity < _capacity && count > _count) || capacity < MIN_CAPACITY) return; buckets = of_calloc(capacity, sizeof(*buckets)); for (unsigned long i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deleted) { unsigned long j, last; last = capacity; |
︙ | ︙ | |||
345 346 347 348 349 350 351 | if (j >= last) @throw [OFOutOfRangeException exception]; buckets[j] = _buckets[i]; } } | | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | if (j >= last) @throw [OFOutOfRangeException exception]; buckets[j] = _buckets[i]; } } free(_buckets); _buckets = buckets; _capacity = capacity; } - (void)of_setObject: (void *)object forKey: (void *)key hash: (unsigned long)hash |
︙ | ︙ | |||
408 409 410 411 412 413 414 | for (i = 0; i < last && _buckets[i] != NULL && _buckets[i] != &deleted; i++); } if (i >= last) @throw [OFOutOfRangeException exception]; | | | | | 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | for (i = 0; i < last && _buckets[i] != NULL && _buckets[i] != &deleted; i++); } if (i >= last) @throw [OFOutOfRangeException exception]; bucket = of_malloc(1, sizeof(*bucket)); @try { bucket->key = _keyFunctions.retain(key); } @catch (id e) { free(bucket); @throw e; } @try { bucket->object = _objectFunctions.retain(object); } @catch (id e) { _keyFunctions.release(bucket->key); free(bucket); @throw e; } bucket->hash = hash; _buckets[i] = bucket; _count++; |
︙ | ︙ | |||
466 467 468 469 470 471 472 | if (_keyFunctions.equal(_buckets[i]->key, key)) { _mutations++; _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); | | | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | if (_keyFunctions.equal(_buckets[i]->key, key)) { _mutations++; _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); free(_buckets[i]); _buckets[i] = &deleted; _count--; [self of_resizeForCount: _count]; return; } |
︙ | ︙ | |||
490 491 492 493 494 495 496 | if (_buckets[i] == &deleted) continue; if (_keyFunctions.equal(_buckets[i]->key, key)) { _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); | | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | if (_buckets[i] == &deleted) continue; if (_keyFunctions.equal(_buckets[i]->key, key)) { _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); free(_buckets[i]); _buckets[i] = &deleted; _count--; _mutations++; [self of_resizeForCount: _count]; return; |
︙ | ︙ | |||
514 515 516 517 518 519 520 | _buckets[i] = NULL; continue; } _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); | | < | < | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 | _buckets[i] = NULL; continue; } _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); free(_buckets[i]); _buckets[i] = NULL; } } _count = 0; _capacity = MIN_CAPACITY; _buckets = of_realloc(_buckets, _capacity, sizeof(*_buckets)); /* * Get a new random value for _rotate, so that it is not less secure * than creating a new hash map. */ if (of_hash_seed != 0) _rotate = of_random16() & 31; |
︙ | ︙ |