diff options
author | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-21 11:24:27 +0000 |
---|---|---|
committer | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-21 11:24:27 +0000 |
commit | 5fe0cb1f487c4141ec62245fffb66f5b84208831 (patch) | |
tree | 2c8c83f8cc423f63fbb9207dea0fb297f26faaac /libobjc/hash.c | |
parent | a790c42a3de743bab009d77eab7090ce3bbc3495 (diff) | |
download | gcc-5fe0cb1f487c4141ec62245fffb66f5b84208831.tar.gz |
In libobjc/:
2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
* hash.c: Tidied up comments and indentation. No code changes.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168110 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libobjc/hash.c')
-rw-r--r-- | libobjc/hash.c | 287 |
1 files changed, 150 insertions, 137 deletions
diff --git a/libobjc/hash.c b/libobjc/hash.c index 3ecc54a170a..e699f024172 100644 --- a/libobjc/hash.c +++ b/libobjc/hash.c @@ -23,12 +23,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #include "objc-private/common.h" -#include <assert.h> /* For assert */ +#include <assert.h> /* For assert. */ -#include "objc/runtime.h" /* For objc_calloc */ -#include "objc/thr.h" /* Required by objc-private/runtime.h. */ +#include "objc/runtime.h" /* For objc_calloc. */ +#include "objc/thr.h" /* Required by objc-private/runtime.h. */ #include "objc-private/hash.h" -#include "objc-private/runtime.h" /* for DEBUG_PRINTF */ +#include "objc-private/runtime.h" /* for DEBUG_PRINTF. */ /* These two macros determine when a hash table is full and by how much it should be expanded respectively. @@ -49,27 +49,27 @@ objc_hash_new (unsigned int size, hash_func_type hash_func, assert (size); assert (! (size & (size - 1))); - /* Allocate the cache structure. calloc insures - its initialization for default values. */ + /* Allocate the cache structure. calloc insures its initialization + for default values. */ cache = (cache_ptr) objc_calloc (1, sizeof (struct cache)); assert (cache); - /* Allocate the array of buckets for the cache. - calloc initializes all of the pointers to NULL. */ + /* Allocate the array of buckets for the cache. calloc initializes + all of the pointers to NULL. */ cache->node_table = (node_ptr *) objc_calloc (size, sizeof (node_ptr)); assert (cache->node_table); cache->size = size; - /* This should work for all processor architectures? */ + /* This should work for all processor architectures (?). */ cache->mask = (size - 1); /* Store the hashing function so that codes can be computed. */ cache->hash_func = hash_func; - /* Store the function that compares hash keys to - determine if they are equal. */ + /* Store the function that compares hash keys to determine if they + are equal. */ cache->compare_func = compare_func; return cache; @@ -85,19 +85,22 @@ objc_hash_delete (cache_ptr cache) /* Purge all key/value pairs from the table. */ /* Step through the nodes one by one and remove every node WITHOUT - using objc_hash_next. this makes objc_hash_delete much more efficient. */ - for (i = 0;i < cache->size;i++) { - if ((node = cache->node_table[i])) { - /* an entry in the hash table has been found, now step through the - nodes next in the list and free them. */ - while ((next_node = node->next)) { - objc_hash_remove (cache,node->key); - node = next_node; - } - - objc_hash_remove (cache,node->key); + using objc_hash_next. this makes objc_hash_delete much more + efficient. */ + for (i = 0; i < cache->size; i++) + { + if ((node = cache->node_table[i])) + { + /* An entry in the hash table has been found. Now step + through the nodes next in the list and free them. */ + while ((next_node = node->next)) + { + objc_hash_remove (cache,node->key); + node = next_node; + } + objc_hash_remove (cache,node->key); + } } - } /* Release the array of nodes and the cache itself. */ objc_free(cache->node_table); @@ -108,10 +111,9 @@ objc_hash_delete (cache_ptr cache) void objc_hash_add (cache_ptr *cachep, const void *key, void *value) { - size_t indx = (*(*cachep)->hash_func)(*cachep, key); + size_t indx = (*(*cachep)->hash_func) (*cachep, key); node_ptr node = (node_ptr) objc_calloc (1, sizeof (struct cache_node)); - assert (node); /* Initialize the new node. */ @@ -119,16 +121,15 @@ objc_hash_add (cache_ptr *cachep, const void *key, void *value) node->value = value; node->next = (*cachep)->node_table[indx]; - /* Debugging. - Check the list for another key. */ + /* Debugging. Check the list for another key. */ #ifdef DEBUG - { node_ptr node1 = (*cachep)->node_table[indx]; - - while (node1) { - - assert (node1->key != key); - node1 = node1->next; - } + { + node_ptr node1 = (*cachep)->node_table[indx]; + while (node1) + { + assert (node1->key != key); + node1 = node1->next; + } } #endif @@ -137,69 +138,72 @@ objc_hash_add (cache_ptr *cachep, const void *key, void *value) /* Bump the number of entries in the cache. */ ++(*cachep)->used; - - /* Check the hash table's fullness. We're going - to expand if it is above the fullness level. */ - if (FULLNESS (*cachep)) { - - /* The hash table has reached its fullness level. Time to - expand it. - - I'm using a slow method here but is built on other - primitive functions thereby increasing its - correctness. */ - node_ptr node1 = NULL; - cache_ptr new = objc_hash_new (EXPANSION (*cachep), - (*cachep)->hash_func, - (*cachep)->compare_func); - - DEBUG_PRINTF ("Expanding cache %#x from %d to %d\n", - (int) *cachep, (*cachep)->size, new->size); - - /* Copy the nodes from the first hash table to the new one. */ - while ((node1 = objc_hash_next (*cachep, node1))) - objc_hash_add (&new, node1->key, node1->value); - - /* Trash the old cache. */ - objc_hash_delete (*cachep); - - /* Return a pointer to the new hash table. */ - *cachep = new; - } + + /* Check the hash table's fullness. We're going to expand if it is + above the fullness level. */ + if (FULLNESS (*cachep)) + { + /* The hash table has reached its fullness level. Time to + expand it. + + I'm using a slow method here but is built on other primitive + functions thereby increasing its correctness. */ + node_ptr node1 = NULL; + cache_ptr new = objc_hash_new (EXPANSION (*cachep), + (*cachep)->hash_func, + (*cachep)->compare_func); + + DEBUG_PRINTF ("Expanding cache %#x from %d to %d\n", + (int) *cachep, (*cachep)->size, new->size); + + /* Copy the nodes from the first hash table to the new one. */ + while ((node1 = objc_hash_next (*cachep, node1))) + objc_hash_add (&new, node1->key, node1->value); + + /* Trash the old cache. */ + objc_hash_delete (*cachep); + + /* Return a pointer to the new hash table. */ + *cachep = new; + } } - void objc_hash_remove (cache_ptr cache, const void *key) { - size_t indx = (*cache->hash_func)(cache, key); + size_t indx = (*cache->hash_func) (cache, key); node_ptr node = cache->node_table[indx]; - - /* We assume there is an entry in the table. Error if it is not. */ + /* We assume there is an entry in the table. Error if it is + not. */ assert (node); - /* Special case. First element is the key/value pair to be removed. */ - if ((*cache->compare_func)(node->key, key)) { - cache->node_table[indx] = node->next; - objc_free(node); - } else { - - /* Otherwise, find the hash entry. */ - node_ptr prev = node; - BOOL removed = NO; - - do { - - if ((*cache->compare_func)(node->key, key)) { - prev->next = node->next, removed = YES; - objc_free(node); - } else - prev = node, node = node->next; - } while (! removed && node); - assert (removed); - } - + /* Special case. First element is the key/value pair to be + removed. */ + if ((*cache->compare_func) (node->key, key)) + { + cache->node_table[indx] = node->next; + objc_free(node); + } + else + { + /* Otherwise, find the hash entry. */ + node_ptr prev = node; + BOOL removed = NO; + do + { + if ((*cache->compare_func) (node->key, key)) + { + prev->next = node->next, removed = YES; + objc_free(node); + } + else + prev = node, node = node->next; + } + while (!removed && node); + assert (removed); + } + /* Decrement the number of entries in the hash table. */ --cache->used; } @@ -208,76 +212,85 @@ objc_hash_remove (cache_ptr cache, const void *key) node_ptr objc_hash_next (cache_ptr cache, node_ptr node) { - /* If the scan is being started then reset the last node - visitied pointer and bucket index. */ - if (! node) + /* If the scan is being started then reset the last node visitied + pointer and bucket index. */ + if (!node) cache->last_bucket = 0; - - /* If there is a node visited last then check for another - entry in the same bucket; Otherwise step to the next bucket. */ - if (node) { - if (node->next) - /* There is a node which follows the last node - returned. Step to that node and retun it. */ - return node->next; - else - ++cache->last_bucket; - } - - /* If the list isn't exhausted then search the buckets for - other nodes. */ - if (cache->last_bucket < cache->size) { - /* Scan the remainder of the buckets looking for an entry - at the head of the list. Return the first item found. */ - while (cache->last_bucket < cache->size) - if (cache->node_table[cache->last_bucket]) - return cache->node_table[cache->last_bucket]; + + /* If there is a node visited last then check for another entry in + the same bucket. Otherwise step to the next bucket. */ + if (node) + { + if (node->next) + { + /* There is a node which follows the last node returned. + Step to that node and retun it. */ + return node->next; + } else - ++cache->last_bucket; + ++cache->last_bucket; + } - /* No further nodes were found in the hash table. */ - return NULL; - } else + /* If the list isn't exhausted then search the buckets for other + nodes. */ + if (cache->last_bucket < cache->size) + { + /* Scan the remainder of the buckets looking for an entry at + the head of the list. Return the first item found. */ + while (cache->last_bucket < cache->size) + if (cache->node_table[cache->last_bucket]) + return cache->node_table[cache->last_bucket]; + else + ++cache->last_bucket; + + /* No further nodes were found in the hash table. */ + return NULL; + } + else return NULL; } -/* Given KEY, return corresponding value for it in CACHE. - Return NULL if the KEY is not recorded. */ - +/* Given KEY, return corresponding value for it in CACHE. Return NULL + if the KEY is not recorded. */ void * objc_hash_value_for_key (cache_ptr cache, const void *key) { - node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)]; + node_ptr node = cache->node_table[(*cache->hash_func) (cache, key)]; void *retval = NULL; if (node) - do { - if ((*cache->compare_func)(node->key, key)) { - retval = node->value; - break; - } else - node = node->next; - } while (! retval && node); - + do + { + if ((*cache->compare_func) (node->key, key)) + { + retval = node->value; + break; + } + else + node = node->next; + } + while (! retval && node); + return retval; } -/* Given KEY, return YES if it exists in the CACHE. - Return NO if it does not */ - +/* Given KEY, return YES if it exists in the CACHE. Return NO if it + does not */ BOOL objc_hash_is_key_in_hash (cache_ptr cache, const void *key) { - node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)]; - + node_ptr node = cache->node_table[(*cache->hash_func) (cache, key)]; + if (node) - do { - if ((*cache->compare_func)(node->key, key)) + do + { + if ((*cache->compare_func)(node->key, key)) return YES; - else - node = node->next; - } while (node); + else + node = node->next; + } + while (node); return NO; } |