Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -26,11 +26,11 @@ * * \return A new autoreleased OFDictionary */ + dictionary; -/* +/** * Creates a new OFDictionary with a hash of N bits. * * \param bits The size of the hash to use * \return A new autoreleased OFDictionary */ @@ -41,35 +41,42 @@ * * \return An initialized OFDictionary */ - init; -/* +/** * Initializes an already allocated OFDictionary with a hash of N bits. * * \param bits The size of the hash to use * \return An initialized OFDictionary */ - initWithHashSize: (int)hashsize; -/* +/** * Sets a key to an object. A key can be any object. * * \param key The key to set * \param obj The object to set the key to */ - set: (OFObject*)key to: (OFObject*)obj; -/* +/** * \param key The key whose object should be returned * \return The object for the given key */ - get: (OFObject*)key; -/* +/** * Remove the object with the given key from the dictionary. * * \param key The key whose object should be removed */ - remove: (OFObject*)key; + +/** + * 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 @@ -14,10 +14,11 @@ #include #import "OFDictionary.h" #import "OFIterator.h" #import "OFExceptions.h" +#import "OFMacros.h" /* Reference for static linking */ void _reference_to_OFIterator_in_OFDictionary() { [OFIterator class]; } @implementation OFDictionary @@ -56,16 +57,15 @@ - initWithHashSize: (int)hashsize { self = [super init]; - if (hashsize < 8 || hashsize > 31) { + if (hashsize < 8 || hashsize >= 28) { Class c = isa; [super free]; - @throw [OFInvalidArgumentException - newWithClass: c - andSelector: _cmd]; + @throw [OFInvalidArgumentException newWithClass: c + andSelector: _cmd]; } size = (size_t)1 << hashsize; @try { @@ -173,13 +173,53 @@ } } @throw [OFNotInSetException newWithClass: isa]; } + +- changeHashSize: (int)hashsize +{ + OFList **newdata; + size_t newsize, i; + of_list_object_t *iter; + + if (hashsize < 8 || hashsize >= 28) + @throw [OFInvalidArgumentException newWithClass: isa + andSelector: _cmd]; + + newsize = (size_t)1 << hashsize; + newdata = [self allocNItems: newsize + withSize: sizeof(OFList*)]; + memset(data, 0, newsize * sizeof(OFList*)); + + for (i = 0; i < size; i++) { + if (OF_LIKELY(data[i] == nil)) + continue; + + for (iter = [data[i] first]; iter != NULL; + iter = iter->next->next) { + uint32_t hash = [iter->object hash] & (newsize - 1); + + if (newdata[hash] == nil) + newdata[hash] = [[OFList alloc] init]; + + [newdata[hash] append: iter->object]; + [newdata[hash] append: iter->next->object]; + } + + [data[i] release]; + } + + [self freeMem: data]; + data = newdata; + size = newsize; + + return self; +} /* FIXME: Implement this! */ /* - (BOOL)isEqual { } */ @end Index: tests/OFDictionary/OFDictionary.m ================================================================== --- tests/OFDictionary/OFDictionary.m +++ tests/OFDictionary/OFDictionary.m @@ -40,24 +40,35 @@ [dict set: key2 to: value2]; [pool release]; if (strcmp([[dict get: @"key1"] cString], "value1")) { - puts("\033[K\033[1;31mTest 1/6 failed!\033[m"); + puts("\033[K\033[1;31mTest 1/7 failed!\033[m"); return 1; } if (strcmp([[dict get: key2] cString], "value2")) { - puts("\033[K\033[1;31mTest 2/6 failed!\033[m"); + puts("\033[K\033[1;31mTest 2/7 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/6 failed!\033[m"); + puts("\033[K\033[1;31mTest 3/7 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"); return 1; } caught = NO; @try { @@ -64,11 +75,11 @@ [iter nextObject]; } @catch (OFNotInSetException *e) { caught = YES; } if (!caught) { - puts("\033[K\033[1;31mTest 4/6 failed!\033[m"); + puts("\033[K\033[1;31mTest 5/7 failed!\033[m"); return 1; } caught = NO; @try { @@ -75,11 +86,11 @@ [dict get: @"key3"]; } @catch (OFNotInSetException *e) { caught = YES; } if (!caught) { - puts("\033[K\033[1;31mTest 5/6 failed!\033[m"); + puts("\033[K\033[1;31mTest 6/7 failed!\033[m"); return 1; } [dict remove: @"key2"]; caught = NO; @@ -87,13 +98,13 @@ [dict remove: @"key2"]; } @catch (OFNotInSetException *e) { caught = YES; } if (!caught) { - puts("\033[K\033[1;31mTest 6/6 failed!\033[m"); + puts("\033[K\033[1;31mTest 7/7 failed!\033[m"); return 1; } - puts("\033[1;32mTests successful: 6/6\033[0m"); + puts("\033[1;32mTests successful: 7/7\033[0m"); return 0; }