@@ -937,11 +937,30 @@ static NSUInteger _JKDictionaryCapacity(JKDictionary *dictionary) {
937
937
}
938
938
939
939
static void _JKDictionaryRemoveObjectWithEntry (JKDictionary *dictionary, JKHashTableEntry *entry) {
940
- NSCParameterAssert ((dictionary != NULL ) && (entry != NULL ) && (entry->key != NULL ) && (entry->object != NULL ) && (dictionary->count > 0UL ));
940
+ NSCParameterAssert ((dictionary != NULL ) && (entry != NULL ) && (entry->key != NULL ) && (entry->object != NULL ) && (dictionary->count > 0UL ) && (dictionary->count <= dictionary->capacity) );
941
941
CFRelease (entry->key ); entry->key = NULL ;
942
942
CFRelease (entry->object ); entry->object = NULL ;
943
943
entry->keyHash = 0UL ;
944
944
dictionary->count --;
945
+ // In order for certain invariants that are used to speed up the search for a particular key, we need to "re-add" all the entries in the hash table following this entry until we hit a NULL entry.
946
+ NSUInteger removeIdx = entry - dictionary->entry , idx = 0UL ;
947
+ NSCParameterAssert ((removeIdx < dictionary->capacity));
948
+ for (idx = 0UL ; idx < dictionary->capacity ; idx++) {
949
+ NSUInteger entryIdx = (removeIdx + idx + 1UL ) % dictionary->capacity ;
950
+ JKHashTableEntry *atEntry = &dictionary->entry [entryIdx];
951
+ if (atEntry->key == NULL ) { break ; }
952
+ NSUInteger keyHash = atEntry->keyHash ;
953
+ id key = atEntry->key , object = atEntry->object ;
954
+ NSCParameterAssert (object != NULL );
955
+ atEntry->keyHash = 0UL ;
956
+ atEntry->key = NULL ;
957
+ atEntry->object = NULL ;
958
+ NSUInteger addKeyEntry = keyHash % dictionary->capacity , addIdx = 0UL ;
959
+ for (addIdx = 0UL ; addIdx < dictionary->capacity ; addIdx++) {
960
+ JKHashTableEntry *atAddEntry = &dictionary->entry [((addKeyEntry + addIdx) % dictionary->capacity)];
961
+ if (JK_EXPECT_T (atAddEntry->key == NULL )) { NSCParameterAssert((atAddEntry->keyHash == 0UL ) && (atAddEntry->object == NULL )); atAddEntry->key = key; atAddEntry->object = object; atAddEntry->keyHash = keyHash; break ; }
962
+ }
963
+ }
945
964
}
946
965
947
966
static void _JKDictionaryAddObject (JKDictionary *dictionary, NSUInteger keyHash, id key, id object) {
@@ -951,7 +970,7 @@ static void _JKDictionaryAddObject(JKDictionary *dictionary, NSUInteger keyHash,
951
970
NSUInteger entryIdx = (keyEntry + idx) % dictionary->capacity ;
952
971
JKHashTableEntry *atEntry = &dictionary->entry [entryIdx];
953
972
if (JK_EXPECT_F (atEntry->keyHash == keyHash) && JK_EXPECT_T (atEntry->key != NULL ) && (JK_EXPECT_F (key == atEntry->key ) || JK_EXPECT_F (CFEqual (atEntry->key , key)))) { _JKDictionaryRemoveObjectWithEntry (dictionary, atEntry); }
954
- if (JK_EXPECT_T (atEntry->key == NULL )) { atEntry->key = key; atEntry->object = object; atEntry->keyHash = keyHash; dictionary->count ++; return ; }
973
+ if (JK_EXPECT_T (atEntry->key == NULL )) { NSCParameterAssert((atEntry-> keyHash == 0UL ) && (atEntry-> object == NULL )); atEntry->key = key; atEntry->object = object; atEntry->keyHash = keyHash; dictionary->count ++; return ; }
955
974
}
956
975
957
976
// We should never get here. If we do, we -release the key / object because it's our responsibility.
0 commit comments