config and string reworked, hashtable updated to use arc_errno

This commit is contained in:
herbglitch 2023-01-17 01:59:08 -07:00
parent 0bbce28469
commit f8d987da8e
12 changed files with 1121 additions and 657 deletions

View file

@ -11,7 +11,7 @@ struct ARC_Hashtable {
ARC_Hashtable_KeyCompare compare;
};
int32_t CRC32(void *key, size_t *keysize, uint32_t *hashval){
void CRC32(void *key, size_t *keysize, uint32_t *hashval){
*hashval = 0xffffffff;
for(size_t i = 0; i < *keysize; i++){
@ -25,10 +25,9 @@ int32_t CRC32(void *key, size_t *keysize, uint32_t *hashval){
}
*hashval = ~*hashval;
return 0;
}
int32_t ARC_Default_Key_Compare(void *key1, size_t *key1size, void *key2, size_t *key2size){
int8_t ARC_Default_Key_Compare(void *key1, size_t *key1size, void *key2, size_t *key2size){
return key1 - key2;
}
@ -40,17 +39,18 @@ void ARC_HashtableNode_Create(ARC_HashtableNode **node, void *key, size_t *keysi
(*node)->node = NULL;
}
int32_t ARC_HashtableNode_Destroy(ARC_HashtableNode *node, ARC_HashtableNode_DestroyExternal external, void *userdata){
if(node == NULL){ return 0; }
void ARC_HashtableNode_Destroy(ARC_HashtableNode *node, ARC_HashtableNode_DestroyExternal external, void *userdata){
if(node == NULL){
return;
}
ARC_HashtableNode_Destroy(node->node, external, userdata);
if(external){
int32_t err = external(node, userdata);
if(err){ return err; }
external(node, userdata);
}
free(node);
return 0;
}
void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hashtable_Hash hash, ARC_Hashtable_KeyCompare compare){
@ -61,89 +61,93 @@ void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hasht
(*htable)->compare = (compare)? compare : ARC_Default_Key_Compare;
}
int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata){
void ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata){
for(uint32_t i = 0; i < htable->size; i++){
if(htable->nodes[i]){
int32_t err = ARC_HashtableNode_Destroy(htable->nodes[i], external, userdata);
if(err){ return err; }
ARC_HashtableNode_Destroy(htable->nodes[i], external, userdata);
}
}
free(htable->nodes);
free(htable);
return 0;
}
int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data){
void ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data){
uint32_t size = 0;
int32_t err = htable->hash(key, &keysize, &size);
if(err){ return err; }
htable->hash(key, &keysize, &size);
ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
if(!bucket){
ARC_HashtableNode_Create(&bucket, key, &keysize, data);
htable->nodes[size % htable->size] = bucket;
return 0;
return;
}
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){ return ARC_ERRNO_EXISTS; }
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
arc_errno = ARC_ERRNO_EXISTS;
return;
}
while(bucket->node){
if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){ return ARC_ERRNO_EXISTS; }
if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){
arc_errno = ARC_ERRNO_EXISTS;
return;
}
bucket = bucket->node;
}
ARC_HashtableNode_Create(&(bucket->node), key, &keysize, data);
return 0;
}
int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data){
void ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data){
uint32_t size = 0;
int32_t err = htable->hash(key, &keysize, &size);
if(err){ return err; }
htable->hash(key, &keysize, &size);
ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
if(!bucket){
*data = NULL;
return ARC_ERRNO_NULL;
arc_errno = ARC_ERRNO_NULL;
return;
}
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
*data = bucket->data;
return 0;
return;
}
while(bucket->node){
if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){
*data = bucket->node->data;
return 0;
return;
}
bucket = bucket->node;
}
return ARC_ERRNO_NULL;
arc_errno = ARC_ERRNO_NULL;
}
int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata){
void ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata){
uint32_t size = 0;
int32_t err = htable->hash(key, &keysize, &size);
if(err){ return err; }
htable->hash(key, &keysize, &size);
ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
if(!bucket){ return ARC_ERRNO_NULL; }
if(!bucket){
arc_errno = ARC_ERRNO_NULL;
return;
}
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
ARC_HashtableNode *temp = bucket;
htable->nodes[size % htable->size] = bucket->node;
if(external){
err = external(temp, userdata);
if(err){ return err; }
external(temp, userdata);
}
free(temp);
return 0;
return;
}
while(bucket->node){
@ -152,16 +156,15 @@ int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, A
bucket->node = bucket->node->node;
if(external){
err = external(temp, userdata);
if(err){ return err; }
external(temp, userdata);
}
free(temp);
return 0;
return;
}
bucket = bucket->node;
}
return ARC_ERRNO_NULL;
arc_errno = ARC_ERRNO_NULL;
}