]> andersk Git - moira.git/blobdiff - lib/hash.c
Command line printer manipulation client, and build goo.
[moira.git] / lib / hash.c
index 1d61cbb310abd5ddb7ef0e172edc379a42555d70..c0c19d8eed8a84cf969b64d6d7a08b975623e0e7 100644 (file)
@@ -1,44 +1,57 @@
-/* $Header$
+/* $Id$
  *
  * Generic hash table routines.  Uses integer keys to store char * values.
+ *
+ * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
  */
 
-#include <ctype.h>
-#include "sms_app.h"
-#define NULL 0
+#include <mit-copyright.h>
+#include <moira.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+RCSID("$Header$");
 
+#define hash_func(h, key) (key >= 0 ? (key % h->size) : (-key % h->size))
 
 /* Create a hash table.  The size is just a hint, not a maximum. */
 
-struct hash *create_hash(size)
-int size;
+struct hash *create_hash(int size)
 {
-    struct hash *h;
-
-    h = (struct hash *) malloc(sizeof(struct hash));
-    h->size = size;
-    h->data = (struct bucket **) malloc(size * sizeof(char *));
-    bzero(h->data, size * sizeof(char *));
-    return(h);
+  struct hash *h;
+
+  h = malloc(sizeof(struct hash));
+  if (!h)
+    return NULL;
+  h->size = size;
+  h->data = malloc(size * sizeof(void *));
+  if (!h->data)
+    {
+      free(h);
+      return NULL;
+    }
+  memset(h->data, 0, size * sizeof(void *));
+  return h;
 }
 
 /* Lookup an object in the hash table.  Returns the value associated with
  * the key, or NULL (thus NULL is not a very good value to store...)
  */
 
-char *hash_lookup(h, key)
-struct hash *h;
-register int key;
+void *hash_lookup(struct hash *h, int key)
 {
-    register struct bucket *b;
-
-    b = h->data[key % h->size];
-    while (b && b->key != key)
-      b = b->next;
-    if (b && b->key == key)
-      return(b->data);
-    else
-      return(NULL);
+  struct bucket *b;
+
+  b = h->data[hash_func(h, key)];
+  while (b && b->key != key)
+    b = b->next;
+  if (b && b->key == key)
+    return b->data;
+  else
+    return NULL;
 }
 
 
@@ -46,55 +59,57 @@ register int key;
  * existed, or 0 if not.
  */
 
-int hash_update(h, key, value)
-struct hash *h;
-register int key;
-char *value;
+int hash_update(struct hash *h, int key, void *value)
 {
-    register struct bucket *b;
-
-    b = h->data[key % h->size];
-    while (b && b->key != key)
-      b = b->next;
-    if (b && b->key == key) {
-       b->data = value;
-       return(1);
-    } else
-      return(0);
+  struct bucket *b;
+
+  b = h->data[hash_func(h, key)];
+  while (b && b->key != key)
+    b = b->next;
+  if (b && b->key == key)
+    {
+      b->data = value;
+      return 1;
+    }
+  else
+    return 0;
 }
 
 
 /* Store an item in the hash table.  Returns 0 if the key was not previously
- * there, or 1 if it was.
+ * there, 1 if it was, or -1 if we ran out of memory.
  */
 
-int hash_store(h, key, value)
-struct hash *h;
-register int key;
-char *value;
+int hash_store(struct hash *h, int key, void *value)
 {
-    register struct bucket *b, **p;
-
-    p = &(h->data[key % h->size]);
-    if (*p == NULL) {
-       b = *p = (struct bucket *) malloc(sizeof(struct bucket));
-       b->next = NULL;
-       b->key = key;
-       b->data = value;
-       return(0);
+  struct bucket *b, **p;
+
+  p = &(h->data[hash_func(h, key)]);
+  if (!*p)
+    {
+      b = *p = malloc(sizeof(struct bucket));
+      if (!b)
+       return -1;
+      b->next = NULL;
+      b->key = key;
+      b->data = value;
+      return 0;
     }
 
-    for (b = *p; b && b->key != key; b = *p)
-      p = (struct bucket **) *p;
-    if (b && b->key == key) {
-       b->data = value;
-       return(1);
+  for (b = *p; b && b->key != key; b = *p)
+    p = (struct bucket **) *p;
+  if (b && b->key == key)
+    {
+      b->data = value;
+      return 1;
     }
-    b = *p = (struct bucket *) malloc(sizeof(struct bucket));
-    b->next = NULL;
-    b->key = key;
-    b->data = value;
-    return(0);
+  b = *p = malloc(sizeof(struct bucket));
+  if (!b)
+    return -1;
+  b->next = NULL;
+  b->key = key;
+  b->data = value;
+  return 0;
 }
 
 
@@ -102,17 +117,16 @@ char *value;
  * data with that value, call the callback proc with the corresponding key.
  */
 
-hash_search(h, value, callback)
-struct hash *h;
-register char *value;
-void (*callback)();
+void hash_search(struct hash *h, void *value, void (*callback)(int))
 {
-    register struct bucket *b, **p;
-
-    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
-       for (b = *p; b; b = b->next) {
-           if (b->data == value)
-             (*callback)(b->key);
+  struct bucket *b, **p;
+
+  for (p = &(h->data[h->size - 1]); p >= h->data; p--)
+    {
+      for (b = *p; b; b = b->next)
+       {
+         if (b->data == value)
+           (*callback)(b->key);
        }
     }
 }
@@ -121,32 +135,31 @@ void (*callback)();
 /* Step through the hash table, calling the callback proc with each key.
  */
 
-hash_step(h, callback, hint)
-struct hash *h;
-void (*callback)();
-char *hint;
+void hash_step(struct hash *h, void (*callback)(int, void *, void *),
+              void *hint)
 {
-    register struct bucket *b, **p;
+  struct bucket *b, **p;
 
-    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
-       for (b = *p; b; b = b->next) {
-           (*callback)(b->key, b->data, hint);
-       }
+  for (p = &(h->data[h->size - 1]); p >= h->data; p--)
+    {
+      for (b = *p; b; b = b->next)
+       (*callback)(b->key, b->data, hint);
     }
 }
 
 
 /* Deallocate all of the memory associated with a table */
 
-hash_destroy(h)
-struct hash *h;
+void hash_destroy(struct hash *h)
 {
-    register struct bucket *b, **p, *b1;
-
-    for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
-       for (b = *p; b; b = b1) {
-           b1 = b->next;
-           free(b);
+  struct bucket *b, **p, *b1;
+
+  for (p = &(h->data[h->size - 1]); p >= h->data; p--)
+    {
+      for (b = *p; b; b = b1)
+       {
+         b1 = b->next;
+         free(b);
        }
     }
 }
This page took 0.050559 seconds and 4 git commands to generate.