Index: src/OFMapTable.h ================================================================== --- src/OFMapTable.h +++ src/OFMapTable.h @@ -47,10 +47,11 @@ @interface OFMapTable: OFObject { of_map_table_functions_t keyFunctions, valueFunctions; struct of_map_table_bucket **buckets; uint32_t minCapacity, capacity, count; + uint8_t rotate; unsigned long mutations; } /*! * @brief Creates a new OFMapTable with the specified key and value functions. Index: src/OFMapTable.m ================================================================== --- src/OFMapTable.m +++ src/OFMapTable.m @@ -150,10 +150,19 @@ buckets = [self allocMemoryWithSize: sizeof(*buckets) count: capacity]; memset(buckets, 0, capacity * sizeof(*buckets)); + + if (of_hash_seed != 0) +#if defined(OF_HAVE_ARC4RANDOM) + rotate = arc4random() & 31; +#elif defined(OF_HAVE_RANDOM) + rotate = random() & 31; +#else + rotate = rand() & 31; +#endif } @catch (id e) { [self release]; @throw e; } @@ -205,11 +214,11 @@ { uint32_t i, hash = 0; for (i = 0; i < capacity; i++) { if (buckets[i] != NULL && buckets[i] != &deleted) { - hash += buckets[i]->hash; + hash += OF_ROR(buckets[i]->hash, rotate); hash += valueFunctions.hash(buckets[i]->value); } } return hash; @@ -227,11 +236,12 @@ for (i = 0; i < capacity; i++) if (buckets[i] != NULL && buckets[i] != &deleted) [copy OF_setValue: buckets[i]->value forKey: buckets[i]->key - hash: buckets[i]->hash]; + hash: OF_ROR(buckets[i]->hash, + rotate)]; } @catch (id e) { [copy release]; @throw e; } @@ -252,11 +262,11 @@ if (key == NULL) @throw [OFInvalidArgumentException exceptionWithClass: [self class] selector: _cmd]; - hash = keyFunctions.hash(key); + hash = OF_ROL(keyFunctions.hash(key), rotate); last = capacity; for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) { if (buckets[i] == &deleted) continue; @@ -347,10 +357,11 @@ if (key == NULL || value == NULL) @throw [OFInvalidArgumentException exceptionWithClass: [self class] selector: _cmd]; + hash = OF_ROL(hash, rotate); last = capacity; for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) { if (buckets[i] == &deleted) continue; @@ -442,11 +453,11 @@ if (key == NULL) @throw [OFInvalidArgumentException exceptionWithClass: [self class] selector: _cmd]; - hash = keyFunctions.hash(key); + hash = OF_ROL(keyFunctions.hash(key), rotate); last = capacity; for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) { if (buckets[i] == &deleted) continue; Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -326,10 +326,13 @@ #endif #define OF_ROL(value, bits) \ (((value) << ((bits) % (sizeof(value) * 8))) | \ (value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) +#define OF_ROR(value, bits) \ + (((value) >> ((bits) % (sizeof(value) * 8))) | \ + (value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) #define OF_HASH_INIT(hash) hash = of_hash_seed #define OF_HASH_ADD(hash, byte) \ { \ hash += (uint8_t)(byte); \