]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - libobjc/hash.c
Imported gcc-4.4.3
[msp430-gcc.git] / libobjc / hash.c
diff --git a/libobjc/hash.c b/libobjc/hash.c
deleted file mode 100644 (file)
index 223991f..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Hash tables for Objective C internal structures
-   Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-/* As a special exception, if you link this library with files
-   compiled with GCC to produce an executable, this does not cause
-   the resulting executable to be covered by the GNU General Public License.
-   This exception does not however invalidate any other reasons why
-   the executable file might be covered by the GNU General Public License.  */
-
-#include "assert.h"
-
-#include "hash.h"
-
-#include "runtime.h"           /* for DEBUG_PRINTF */
-
-/* These two macros determine when a hash table is full and
-   by how much it should be expanded respectively.
-
-   These equations are percentages.  */
-#define FULLNESS(cache) \
-   ((((cache)->size * 75) / 100) <= (cache)->used)
-#define EXPANSION(cache) \
-  ((cache)->size * 2)
-
-cache_ptr
-hash_new (unsigned int size, hash_func_type hash_func,
-         compare_func_type compare_func)
-{
-  cache_ptr cache;
-
-  /* Pass me a value greater than 0 and a power of 2.  */
-  assert (size);
-  assert (!(size & (size - 1)));
-
-  /* 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.  */
-  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? */
-  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.  */
-  cache->compare_func = compare_func;
-
-  return cache;
-}
-
-
-void
-hash_delete (cache_ptr cache)
-{
-  node_ptr node;
-  node_ptr next_node;
-  unsigned int i;
-
-  /* Purge all key/value pairs from the table.  */
-  /* Step through the nodes one by one and remove every node WITHOUT
-     using hash_next. this makes 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)) {
-       hash_remove (cache,node->key);
-       node = next_node;
-      }
-
-      hash_remove (cache,node->key);
-    }
-  }
-
-  /* Release the array of nodes and the cache itself.  */
-  objc_free(cache->node_table);
-  objc_free(cache);
-}
-
-
-void
-hash_add (cache_ptr *cachep, const void *key, void *value)
-{
-  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.  */
-  node->key    = key;
-  node->value  = value;
-  node->next  = (*cachep)->node_table[indx];
-
-  /* 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;
-    }
-  }
-#endif
-
-  /* Install the node as the first element on the list.  */
-  (*cachep)->node_table[indx] = node;
-
-  /* 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 = hash_new (EXPANSION (*cachep),
-                             (*cachep)->hash_func,
-                             (*cachep)->compare_func);
-
-    DEBUG_PRINTF ("Expanding cache %#x from %d to %d\n",
-                 *cachep, (*cachep)->size, new->size);
-
-    /* Copy the nodes from the first hash table to the new one.  */
-    while ((node1 = hash_next (*cachep, node1)))
-      hash_add (&new, node1->key, node1->value);
-
-    /* Trash the old cache.  */
-    hash_delete (*cachep);
-
-    /* Return a pointer to the new hash table.  */
-    *cachep = new;
-  }
-}
-
-
-void
-hash_remove (cache_ptr cache, const void *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.  */
-  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);
-  }
-
-  /* Decrement the number of entries in the hash table.  */
-  --cache->used;
-}
-
-
-node_ptr
-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)
-    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];
-      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.  */
-
-void *
-hash_value_for_key (cache_ptr cache, const void *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);
-
-  return retval;
-}
-
-/* Given KEY, return YES if it exists in the CACHE.
-   Return NO if it does not */
-
-BOOL
-hash_is_key_in_hash (cache_ptr cache, const void *key)
-{
-  node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)];
-
-  if (node)
-    do {
-      if ((*cache->compare_func)(node->key, key))
-         return YES;
-      else
-        node = node->next;
-    } while (node);
-
-  return NO;
-}