home *** CD-ROM | disk | FTP | other *** search
- /*
- * hash.c - This module implements and maintains a closed hash table
- * containing one entry for each colormap.
- *
- * Note that the data structure is stored locally in hash_tab.
- *
- * Exported routines:
- * H_MakeNull
- * H_Insert
- * H_Member
- * H_Delete
- */
-
- /**************************************************************************
- * palette - a colormap editor
- * Copyright (c) 1988 Wayne Mesard *
- * *
- * This is free software. It may be reproduced, retransmitted, *
- * redistributed and otherwise propogated at will, provided that *
- * no monetary profit is realized and that this notice remains *
- * intact and in place. *
- * *
- * Please direct bug reports, code enhancements and comments *
- * to mesard@BBN.COM. *
- * *
- **************************************************************************/
-
- #include <stdio.h>
- #include "hash.h"
- #include <strings.h>
-
- #define NullP(ENTRY) (ENTRY.name[0] == '\0')
- #define NotNullP(ENTRY) (ENTRY.name[0] != '\0')
- #define DeletedP(ENTRY) (ENTRY.name[0] == '\001')
- #define NotDeletedP(ENTRY) (ENTRY.name[0] != '\001')
- #define DoDelete(ENTRY) (ENTRY.name[0] = '\001')
- #define STREQ(S1, S2) (!strcmp(S1, S2))
-
- static cms_tab_t hash_tab;
-
- /*
- * H_MakeNull
- */
-
- void H_MakeNull()
- {
- int i;
-
- for (i = -1; ++i < CMS_TAB_SIZE;)
- hash_tab[i].name[0] = '\0';
- }
-
-
- /*
- * H_Insert - Places an entry in the table if it isn't already there.
- * Returns false, iff the hash table was full.
- */
-
- boolean H_Insert(targ, size, presentation, RGB)
- char *targ;
- int size;
- caddr_t presentation;
- struct cms_map *RGB;
- {
- int b;
-
- if (!STREQ(hash_tab[b = locate(targ, false)].name, targ)) {
- b = locate(targ, true);
- if (NullP(hash_tab[b]) || DeletedP(hash_tab[b])) {
- (void) strcpy(hash_tab[b].name, targ);
- hash_tab[b].size = size;
- hash_tab[b].presentation = presentation;
- hash_tab[b].map = *RGB;
- return(true);
- }
- else
- return(false);
- }
- else
- return(true);
- }
-
-
-
- /*
- * H_Member - Returns zero if targ is not in the hash table. Otherwise
- * it returns the size field. Additionally, if the second
- * and third params are non-null, it fills copies the map and
- * presentation fields into them.
- */
-
- int H_Member(targ, cms, presentation)
- char *targ;
- caddr_t *presentation;
- struct cms_map *cms;
- {
- int b;
-
- if (STREQ(hash_tab[b = locate(targ, false)].name, targ)) {
- if (cms)
- bcopy((char *)&(hash_tab[b].map), (char *)cms,
- sizeof(struct cms_map));
- if (presentation)
- *presentation = hash_tab[b].presentation;
- return(hash_tab[b].size);
- }
- else
- return(0);
- }
-
-
-
-
- /*
- * H_Delete - Removes an entry from the hash-table.
- * Note non-modular bogosity: frees memory which was not
- * allocated by this package.
- */
-
- void H_Delete(targ)
- char *targ;
- {
- int b = locate(targ, false);
-
- if (STREQ(hash_tab[b].name, targ)) {
- DoDelete(hash_tab[b]);
- free((char *) hash_tab[b].map.cm_red);
- free((char *) hash_tab[b].map.cm_green);
- free((char *) hash_tab[b].map.cm_blue);
- }
- }
-
-
-
- static int h(s)
- char *s;
- {
- int val = 0;
-
- while (*s)
- val += (*s++<<1);
-
- return (val % CMS_TAB_SIZE);
- }
-
-
- /*
- * locate - Scans until it finds targ or an empty bucket. If deletedP
- * is true it will also stop at deleted buckets. Returns the
- * bucket number.
- */
-
- static int locate(targ, deletedP)
- char *targ;
- boolean deletedP;
- {
- int h();
- int i=0, initial=h(targ);
-
- while ((i < CMS_TAB_SIZE) &&
- NotNullP(hash_tab[(initial+i) % CMS_TAB_SIZE]) &&
- (deletedP ? NotDeletedP(hash_tab[(initial+i) % CMS_TAB_SIZE]) : true) &&
- !STREQ(hash_tab[(initial+i) % CMS_TAB_SIZE].name, targ))
- i++;
-
- return((initial+i) % CMS_TAB_SIZE);
- }
-
-