@@ -57,17 +57,10 @@ defaultEqual(void *object1, void *object2) { return (object1 == object2); } -OF_DIRECT_MEMBERS -@interface OFMapTable () -- (void)of_setObject: (void *)object - forKey: (void *)key - hash: (unsigned long)hash; -@end - OF_DIRECT_MEMBERS @interface OFMapTableEnumerator () - (instancetype)of_initWithMapTable: (OFMapTable *)mapTable buckets: (struct of_map_table_bucket **)buckets capacity: (unsigned long)capacity @@ -242,14 +235,13 @@ capacity: _capacity]; @try { for (unsigned long i = 0; i < _capacity; i++) if (_buckets[i] != NULL && _buckets[i] != &deleted) - [copy of_setObject: _buckets[i]->object - forKey: _buckets[i]->key - hash: OF_ROR(_buckets[i]->hash, - _rotate)]; + setObject(copy, _buckets[i]->key, + _buckets[i]->object, + OF_ROR(_buckets[i]->hash, _rotate)); } @catch (id e) { [copy release]; @throw e; } @@ -294,159 +286,167 @@ } return NULL; } -- (void)of_resizeForCount: (unsigned long)count OF_DIRECT +static void +resizeForCount(OFMapTable *self, unsigned long count) { unsigned long fullness, capacity; struct of_map_table_bucket **buckets; - if (count > ULONG_MAX / sizeof(*_buckets) || count > ULONG_MAX / 8) + if (count > ULONG_MAX / sizeof(*self->_buckets) || + count > ULONG_MAX / 8) @throw [OFOutOfRangeException exception]; - fullness = count * 8 / _capacity; + fullness = count * 8 / self->_capacity; if (fullness >= 6) { - if (_capacity > ULONG_MAX / 2) + if (self->_capacity > ULONG_MAX / 2) return; - capacity = _capacity * 2; + capacity = self->_capacity * 2; } else if (fullness <= 1) - capacity = _capacity / 2; + capacity = self->_capacity / 2; else return; /* * 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) + if ((capacity < self->_capacity && count > self->_count) || + capacity < MIN_CAPACITY) return; buckets = of_alloc_zeroed(capacity, sizeof(*buckets)); - for (unsigned long i = 0; i < _capacity; i++) { - if (_buckets[i] != NULL && _buckets[i] != &deleted) { + for (unsigned long i = 0; i < self->_capacity; i++) { + if (self->_buckets[i] != NULL && + self->_buckets[i] != &deleted) { unsigned long j, last; last = capacity; - for (j = _buckets[i]->hash & (capacity - 1); + for (j = self->_buckets[i]->hash & (capacity - 1); j < last && buckets[j] != NULL; j++); /* In case the last bucket is already used */ if (j >= last) { - last = _buckets[i]->hash & (capacity - 1); + last = self->_buckets[i]->hash & (capacity - 1); for (j = 0; j < last && buckets[j] != NULL; j++); } if (j >= last) @throw [OFOutOfRangeException exception]; - buckets[j] = _buckets[i]; + buckets[j] = self->_buckets[i]; } } - free(_buckets); - _buckets = buckets; - _capacity = capacity; + free(self->_buckets); + self->_buckets = buckets; + self->_capacity = capacity; } -- (void)of_setObject: (void *)object - forKey: (void *)key - hash: (unsigned long)hash +static void +setObject(OFMapTable *restrict self, void *key, void *object, + unsigned long hash) { unsigned long i, last; void *old; if (key == NULL || object == NULL) @throw [OFInvalidArgumentException exception]; - hash = OF_ROL(hash, _rotate); - last = _capacity; + hash = OF_ROL(hash, self->_rotate); + last = self->_capacity; - for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) { - if (_buckets[i] == &deleted) + for (i = hash & (self->_capacity - 1); + i < last && self->_buckets[i] != NULL; i++) { + if (self->_buckets[i] == &deleted) continue; - if (_keyFunctions.equal(_buckets[i]->key, key)) + if (self->_keyFunctions.equal(self->_buckets[i]->key, key)) break; } /* In case the last bucket is already used */ if (i >= last) { - last = hash & (_capacity - 1); + last = hash & (self->_capacity - 1); - for (i = 0; i < last && _buckets[i] != NULL; i++) { - if (_buckets[i] == &deleted) + for (i = 0; i < last && self->_buckets[i] != NULL; i++) { + if (self->_buckets[i] == &deleted) continue; - if (_keyFunctions.equal(_buckets[i]->key, key)) + if (self->_keyFunctions.equal( + self->_buckets[i]->key, key)) break; } } /* Key not in map table */ - if (i >= last || _buckets[i] == NULL || _buckets[i] == &deleted || - !_keyFunctions.equal(_buckets[i]->key, key)) { + if (i >= last || self->_buckets[i] == NULL || + self->_buckets[i] == &deleted || + !self->_keyFunctions.equal(self->_buckets[i]->key, key)) { struct of_map_table_bucket *bucket; - [self of_resizeForCount: _count + 1]; + resizeForCount(self, self->_count + 1); - _mutations++; - last = _capacity; + self->_mutations++; + last = self->_capacity; - for (i = hash & (_capacity - 1); i < last && - _buckets[i] != NULL && _buckets[i] != &deleted; i++); + for (i = hash & (self->_capacity - 1); i < last && + self->_buckets[i] != NULL && self->_buckets[i] != &deleted; + i++); /* In case the last bucket is already used */ if (i >= last) { - last = hash & (_capacity - 1); + last = hash & (self->_capacity - 1); - for (i = 0; i < last && _buckets[i] != NULL && - _buckets[i] != &deleted; i++); + for (i = 0; i < last && self->_buckets[i] != NULL && + self->_buckets[i] != &deleted; i++); } if (i >= last) @throw [OFOutOfRangeException exception]; bucket = of_alloc(1, sizeof(*bucket)); @try { - bucket->key = _keyFunctions.retain(key); + bucket->key = self->_keyFunctions.retain(key); } @catch (id e) { free(bucket); @throw e; } @try { - bucket->object = _objectFunctions.retain(object); + bucket->object = self->_objectFunctions.retain(object); } @catch (id e) { - _keyFunctions.release(bucket->key); + self->_keyFunctions.release(bucket->key); free(bucket); @throw e; } bucket->hash = hash; - _buckets[i] = bucket; - _count++; + self->_buckets[i] = bucket; + self->_count++; return; } - old = _buckets[i]->object; - _buckets[i]->object = _objectFunctions.retain(object); - _objectFunctions.release(old); + old = self->_buckets[i]->object; + self->_buckets[i]->object = self->_objectFunctions.retain(object); + self->_objectFunctions.release(old); } - (void)setObject: (void *)object forKey: (void *)key { - [self of_setObject: object forKey: key hash: _keyFunctions.hash(key)]; + setObject(self, key, object,_keyFunctions.hash(key)); } - (void)removeObjectForKey: (void *)key { unsigned long i, hash, last; @@ -469,11 +469,11 @@ free(_buckets[i]); _buckets[i] = &deleted; _count--; - [self of_resizeForCount: _count]; + resizeForCount(self, _count); return; } } @@ -494,11 +494,11 @@ free(_buckets[i]); _buckets[i] = &deleted; _count--; _mutations++; - [self of_resizeForCount: _count]; + resizeForCount(self, _count); return; } } }