Index: src/OFMapTable.h ================================================================== --- src/OFMapTable.h +++ src/OFMapTable.h @@ -46,11 +46,11 @@ */ @interface OFMapTable: OFObject { of_map_table_functions_t _keyFunctions, _valueFunctions; struct of_map_table_bucket **_buckets; - uint32_t _minCapacity, _capacity, _count; + uint32_t _count, _capacity; uint8_t _rotate; unsigned long _mutations; } /*! Index: src/OFMapTable.m ================================================================== --- src/OFMapTable.m +++ src/OFMapTable.m @@ -145,12 +145,10 @@ _capacity <<= 1; if (_capacity < MIN_CAPACITY) _capacity = MIN_CAPACITY; - _minCapacity = _capacity; - _buckets = [self allocMemoryWithSize: sizeof(*_buckets) count: _capacity]; memset(_buckets, 0, _capacity * sizeof(*_buckets)); @@ -244,12 +242,10 @@ } @catch (id e) { [copy release]; @throw e; } - copy->_minCapacity = MIN_CAPACITY; - return copy; } - (size_t)count { @@ -309,11 +305,15 @@ else if (fullness <= 1) capacity = _capacity >> 1; else return; - if (capacity < _capacity && capacity < _minCapacity) + /* + * 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 = [self allocMemoryWithSize: sizeof(*buckets) count: capacity]; Index: src/OFMutableDictionary.h ================================================================== --- src/OFMutableDictionary.h +++ src/OFMutableDictionary.h @@ -22,10 +22,28 @@ /*! * @brief An abstract class for storing and changing objects in a dictionary. */ @interface OFMutableDictionary: OFDictionary +/*! + * @brief Creates a new OFMutableDictionary with enough memory to hold the + * specified number of objects. + * + * @param capacity The initial capacity for the OFMutableDictionary + * @return A new autoreleased OFMutableDictionary + */ ++ (instancetype)dictionaryWithCapacity: (size_t)capacity; + +/*! + * @brief Initializes an already allocated OFMutableDictionary with enough + * memory to hold the specified number of objects. + * + * @param capacity The initial capacity for the OFMutableDictionary + * @return A new initialized OFMutableDictionary + */ +- initWithCapacity: (size_t)capacity; + /*! * @brief Sets an object for a key. * * A key can be any object that conforms to the OFCopying protocol. * Index: src/OFMutableDictionary.m ================================================================== --- src/OFMutableDictionary.m +++ src/OFMutableDictionary.m @@ -89,10 +89,16 @@ - initWithSerialization: (OFXMLElement*)element { return (id)[[OFMutableDictionary_hashtable alloc] initWithSerialization: element]; } + +- initWithCapacity: (size_t)capacity +{ + return (id)[[OFMutableDictionary_hashtable alloc] + initWithCapacity: capacity]; +} - retain { return self; } @@ -128,10 +134,15 @@ if (self == [OFMutableDictionary class]) return (id)&placeholder; return [super alloc]; } + ++ dictionaryWithCapacity: (size_t)capacity +{ + return [[[self alloc] initWithCapacity: capacity] autorelease]; +} - init { if (object_getClass(self) == [OFMutableDictionary class]) { @try { @@ -143,10 +154,21 @@ } } return [super init]; } + +- initWithCapacity: (size_t)capacity +{ + @try { + [self doesNotRecognizeSelector: _cmd]; + abort(); + } @catch (id e) { + [self release]; + @throw e; + } +} - (void)setObject: (id)object forKey: (id)key { [self doesNotRecognizeSelector: _cmd];