home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "entry.h"
- #include "diblock.h"
- #include "talloc.h"
- #include "nels.h"
-
- #define TABZ 127
-
- #define abs(n) (((n) < 0) ? -(n) : (n))
-
- static entry *hash_table[TABZ];
-
- static
- entry *
- mkent(dipc, key, data)
- dinstrn *dipc;
- unsigned long key;
- unsigned long data;
- {
- entry *p;
-
- if ((p = talloc(entry)) == (entry *)0)
- {
- GLOBALdipc = dipc;
- vcouldnot("allocate %d bytes for hash entry", sizeof(entry));
- return (entry *)0;
- }
-
- p->ent_key = key;
- p->ent_data = data;
- p->ent_right = (entry *)0;
- p->ent_left = (entry *)0;
-
- return p;
- }
-
- /*
- * Given a key, return a pointer to the entry
- * in the table corresponding to that key - or
- * a pointer to the entry where it should be if
- * it is not there.
- */
- static
- entry **
- lookup(key)
- unsigned long key;
- {
- entry **pp;
- int flag;
-
- pp = &hash_table[abs(key) % nels(hash_table)];
-
- while
- (
- *pp != (entry *)0
- &&
- (flag = (key - (*pp)->ent_key)) != 0
- )
- pp = (flag > 0) ? &((*pp)->ent_right) : &((*pp)->ent_left);
-
- return pp;
- }
-
- /*
- * Delete an entry with the given key.
- * If not there, return 0, else 1.
- */
- static
- int
- del(key)
- unsigned long key;
- {
- entry **p;
- entry *l;
- entry *r;
-
- if (*(p = lookup(key)) == (entry *)0)
- return 0;
-
- l = (*p)->ent_left;
- r = (*p)->ent_right;
- (void)free(*p);
-
- if (l == (entry *)0)
- {
- *p = r;
- return 1;
- }
-
- if (r == (entry *)0)
- {
- *p = l;
- return 1;
- }
-
- *p = l;
- while (l->ent_right != (entry *)0)
- l = l->ent_right;
- l->ent_right = r;
-
- return 1;
- }
-
- diblock *
- addr_to_decoded_block(dipc, addr)
- dinstrn *dipc;
- unsigned long addr;
- {
- static unsigned long lastaddr;
- static diblock *lastdiblockp;
- entry **pp;
- entry *p;
-
- addr /= SIMULATED_PAGE_SIZE;
-
- if (addr == lastaddr)
- return lastdiblockp;
-
- lastaddr = addr;
-
- if ((p = *(pp = lookup(addr))) == (entry *)0)
- {
- diblock *diblockp;
-
- if ((diblockp = talloc(diblock)) == (diblock *)0)
- {
- GLOBALdipc = dipc;
- vcouldnot("allocate %d bytes for diblock", sizeof(diblock));
- return (diblock *)0;
- }
-
- diblockp->dib_want_init = 1;
- diblockp->dib_first_addr = addr * SIMULATED_PAGE_SIZE;
-
- if ((p = mkent(dipc, addr, (unsigned long)diblockp)) == (entry *)0)
- return (diblock *)0;
-
- *pp = p;
- }
-
- lastdiblockp = (diblock *)p->ent_data;
-
- return lastdiblockp;
- }
-