mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-11-23 20:19:40 +00:00
More fixes - hopefully fixed for real now
This commit is contained in:
parent
8af05dd142
commit
84b18af68b
@ -15,7 +15,8 @@ typedef struct {
|
||||
objc_AssociationPolicy policy;
|
||||
} AssociationObjectEntry;
|
||||
|
||||
#define AssociationObjectEntrySize 4
|
||||
#define BucketsInitialSize 509 // Some prime size (and as a bonus, next three n*2+1 are prime too)
|
||||
#define AssociationObjectEntrySize 5
|
||||
|
||||
#define HASHPTR(p) (((unsigned int)p)>>5)
|
||||
|
||||
@ -31,18 +32,11 @@ typedef struct AssociationTable {
|
||||
AssociationHashBucket **buckets;
|
||||
} AssociationTable;
|
||||
|
||||
typedef struct {
|
||||
AssociationTable *table;
|
||||
unsigned int i;
|
||||
struct AssociationHashBucket *j;
|
||||
} NSHashEnumerator;
|
||||
|
||||
|
||||
AssociationTable *CreateAssociationTable(unsigned int capacity) {
|
||||
AssociationTable *table=malloc(sizeof(AssociationTable));
|
||||
|
||||
table->count=0;
|
||||
table->nBuckets=(capacity<4)?4:capacity;
|
||||
table->nBuckets=(capacity<5)?5:capacity;
|
||||
table->buckets=calloc(table->nBuckets,sizeof(AssociationHashBucket *));
|
||||
|
||||
return table;
|
||||
@ -65,31 +59,48 @@ void AssociationTableInsert(AssociationTable *table,id key, AssociationObjectEnt
|
||||
unsigned int i=hash%table->nBuckets;
|
||||
AssociationHashBucket *j;
|
||||
|
||||
for(j=table->buckets[i];j!=NULL;j=j->next)
|
||||
for(j=table->buckets[i];j!=NULL;j=j->next) {
|
||||
if(j->key==key){
|
||||
id oldKey=j->key;
|
||||
AssociationObjectEntry *oldValue=j->value;
|
||||
|
||||
j->key=key;
|
||||
j->value=value;
|
||||
j->value=value;
|
||||
|
||||
free(oldValue);
|
||||
return;
|
||||
}
|
||||
|
||||
if(table->count>=table->nBuckets){
|
||||
}
|
||||
int newSize = 0;
|
||||
if (table->count>=table->nBuckets) {
|
||||
// Expand the buckets size to limit collisions
|
||||
newSize=table->nBuckets*2+1; // Let"s use odd size
|
||||
} else if (table->count > BucketsInitialSize && table->count < table->nBuckets/2) {
|
||||
// Compact the table - plenty of free room
|
||||
newSize=table->nBuckets/2;
|
||||
if (newSize%2) {
|
||||
// Let"s use odd size
|
||||
newSize+=1;
|
||||
}
|
||||
}
|
||||
if(newSize != 0){
|
||||
unsigned int nBuckets=table->nBuckets;
|
||||
AssociationHashBucket **buckets=table->buckets,*next;
|
||||
AssociationHashBucket **buckets=table->buckets;
|
||||
|
||||
table->nBuckets=nBuckets*2;
|
||||
table->nBuckets=newSize;
|
||||
table->buckets=calloc(table->nBuckets,sizeof(AssociationHashBucket *));
|
||||
|
||||
for(i=0;i<nBuckets;i++)
|
||||
for(j=buckets[i];j!=NULL;j=next){
|
||||
unsigned int newi=HASHPTR(key)%table->nBuckets;
|
||||
// Get all of the existing buckets and place them into the new list
|
||||
for(i=0;i<nBuckets;i++) {
|
||||
j = buckets[i];
|
||||
while (j) {
|
||||
unsigned int newi=HASHPTR(j->key)%table->nBuckets;
|
||||
|
||||
next=j->next;
|
||||
AssociationHashBucket *next = j->next;
|
||||
j->next=table->buckets[newi];
|
||||
table->buckets[newi]=j;
|
||||
|
||||
j = next;
|
||||
}
|
||||
}
|
||||
free(buckets);
|
||||
i=hash%table->nBuckets;
|
||||
}
|
||||
@ -156,7 +167,7 @@ void AssociationTableRemove(AssociationTable *table,id key){
|
||||
AssociationObjectEntry *entry = j->value;
|
||||
|
||||
for (int i = 0; i < AssociationObjectEntrySize; i++) {
|
||||
AssociationObjectEntry *e = (AssociationObjectEntry *)entry + i;
|
||||
AssociationObjectEntry *e = entry + i;
|
||||
while (e) {
|
||||
switch (e->policy) {
|
||||
case OBJC_ASSOCIATION_ASSIGN:
|
||||
@ -176,9 +187,12 @@ void AssociationTableRemove(AssociationTable *table,id key){
|
||||
objectsToRelease[releaseCount++] = e->object;
|
||||
break;
|
||||
}
|
||||
void *prevEntry = e;
|
||||
AssociationObjectEntry *currentEntry = e;
|
||||
e = e->nextEntry;
|
||||
free(prevEntry);
|
||||
// Don't free the first entry of the list - it's part of the "entry" block that will be freed after the loop
|
||||
if (currentEntry != entry + i) {
|
||||
free(currentEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +229,7 @@ void objc_setAssociatedObject(id object, const void *key, id value, objc_Associa
|
||||
AssociationSpinLockLock(&AssociationLock);
|
||||
|
||||
if (associationTable == NULL) {
|
||||
associationTable = CreateAssociationTable(512);
|
||||
associationTable = CreateAssociationTable(BucketsInitialSize);
|
||||
}
|
||||
|
||||
AssociationObjectEntry *objectTable = AssociationTableGet(associationTable, object);
|
||||
|
Loading…
Reference in New Issue
Block a user