Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -71,12 +71,19 @@ * * \param key The key whose object should be removed */ - remove: (OFObject*)key; +/** + * \return The average number of items in a used bucket. Buckets that are + * completely empty are not in the calculation. If this value is >= 2.0, + * you should resize the dictionary, in most cases even earlier! + */ +- (float)averageItemsPerBucket; + /** * Changes the hash size of the dictionary. * * \param hashsize The new hash size for the dictionary */ - changeHashSize: (int)hashsize; @end Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -173,10 +173,27 @@ } } @throw [OFNotInSetException newWithClass: isa]; } + +- (float)averageItemsPerBucket +{ + size_t items, buckets, i; + + items = 0; + buckets = 0; + + for (i = 0; i < size; i++) { + if (data[i] != nil) { + items += [data[i] items] / 2; + buckets++; + } + } + + return (float)items / buckets; +} - changeHashSize: (int)hashsize { OFList **newdata; size_t newsize, i; Index: tests/OFDictionary/OFDictionary.m ================================================================== --- tests/OFDictionary/OFDictionary.m +++ tests/OFDictionary/OFDictionary.m @@ -40,35 +40,39 @@ [dict set: key2 to: value2]; [pool release]; if (strcmp([[dict get: @"key1"] cString], "value1")) { - puts("\033[K\033[1;31mTest 1/7 failed!\033[m"); + puts("\033[K\033[1;31mTest 1/8 failed!\033[m"); return 1; } if (strcmp([[dict get: key2] cString], "value2")) { - puts("\033[K\033[1;31mTest 2/7 failed!\033[m"); + puts("\033[K\033[1;31mTest 2/8 failed!\033[m"); return 1; } if (![[iter nextObject] isEqual: @"key2"] || ![[iter nextObject] isEqual: @"value2"] || ![[iter nextObject] isEqual: @"key1"] || ![[iter nextObject] isEqual: @"value1"]) { - puts("\033[K\033[1;31mTest 3/7 failed!\033[m"); + puts("\033[K\033[1;31mTest 3/8 failed!\033[m"); return 1; } - [iter release]; [dict changeHashSize: 8]; iter = [dict iterator]; if (![[iter nextObject] isEqual: @"key1"] || ![[iter nextObject] isEqual: @"value1"] || ![[iter nextObject] isEqual: @"key2"] || ![[iter nextObject] isEqual: @"value2"]) { - puts("\033[K\033[1;31mTest 4/7 failed!\033[m"); + puts("\033[K\033[1;31mTest 4/8 failed!\033[m"); + return 1; + } + + if ([dict averageItemsPerBucket] != 1.0) { + puts("\033[K\033[1;31mTest 5/8 failed!\033[m"); return 1; } caught = NO; @try { @@ -75,11 +79,11 @@ [iter nextObject]; } @catch (OFNotInSetException *e) { caught = YES; } if (!caught) { - puts("\033[K\033[1;31mTest 5/7 failed!\033[m"); + puts("\033[K\033[1;31mTest 6/8 failed!\033[m"); return 1; } caught = NO; @try { @@ -86,11 +90,11 @@ [dict get: @"key3"]; } @catch (OFNotInSetException *e) { caught = YES; } if (!caught) { - puts("\033[K\033[1;31mTest 6/7 failed!\033[m"); + puts("\033[K\033[1;31mTest 7/8 failed!\033[m"); return 1; } [dict remove: @"key2"]; caught = NO; @@ -98,13 +102,13 @@ [dict remove: @"key2"]; } @catch (OFNotInSetException *e) { caught = YES; } if (!caught) { - puts("\033[K\033[1;31mTest 7/7 failed!\033[m"); + puts("\033[K\033[1;31mTest 8/8 failed!\033[m"); return 1; } - puts("\033[1;32mTests successful: 7/7\033[0m"); + puts("\033[1;32mTests successful: 8/8\033[0m"); return 0; }