home *** CD-ROM | disk | FTP | other *** search
- // This may look like C code, but it is really -*- C++ -*-
- /*
- Copyright (C) 1988 Free Software Foundation
- written by Doug Lea (dl@rocky.oswego.edu)
-
- This file is part of GNU CC.
-
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the GNU CC General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- GNU CC, but only under the conditions described in the
- GNU CC General Public License. A copy of this license is
- supposed to have been given to you along with GNU CC so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies.
- */
-
- #include <stream.h>
- #include "<T>ChainedHashTable.h"
-
- // error handling
-
-
- void default_<T>ChainedHashTable_error_handler(char* msg)
- {
- cerr << "Fatal <T>ChainedHashTable error. " << msg << "\n";
- exit(1);
- }
-
- one_arg_error_handler_t <T>ChainedHashTable_error_handler = default_<T>ChainedHashTable_error_handler;
-
- one_arg_error_handler_t set_<T>ChainedHashTable_error_handler(one_arg_error_handler_t f)
- {
- one_arg_error_handler_t old = <T>ChainedHashTable_error_handler;
- <T>ChainedHashTable_error_handler = f;
- return old;
- }
-
- void <T>ChainedHashTable::error(const char* msg)
- {
- (*<T>ChainedHashTable_error_handler)(msg);
- }
-
- <T>ChainedHashTable::<T>ChainedHashTable(int sz, <U>HashFunction f,
- <T>KeyAccess acc)
- {
- tab = (<T>SLListNode**)(new <T>SLListNodePtr[size = sz]);
- for (int i = 0; i < size; ++i) tab[i] = 0;
- hash = f;
- getkey = acc;
- cnt = 0;
- }
-
-
- int <T>ChainedHashTable::access(<U&> key, <T>& item)
- {
- int h = (*hash)(key) % size;
-
- for (<T>SLListNode* t = tab[h]; t != 0; t = t->tl)
- if ((*getkey)(t->hd) == key)
- {
- item = t->hd;
- return 1;
- }
- return 0;
- }
-
- int <T>ChainedHashTable::contains(<U&> key)
- {
- int h = (*hash)(key) % size;
-
- for (<T>SLListNode* t = tab[h]; t != 0; t = t->tl)
- if ((*getkey)(t->hd) == key)
- return 1;
- return 0;
- }
-
- int <T>ChainedHashTable::add_or_access(<T>& item)
- {
- int h = (*hash)((*getkey)(item)) % size;
-
- for (<T>SLListNode* t = tab[h]; t != 0; t = t->tl)
- if ((*getkey)(t->hd) == (*getkey)(item))
- {
- item = t->hd;
- return 1;
- }
-
- t = new <T>SLListNode(item);
- t->tl = tab[h];
- tab[h] = t;
- ++cnt;
- return 0;
- }
-
- int <T>ChainedHashTable::add(<T&> item)
- {
- int h = (*hash)((*getkey)(item)) % size;
-
- for (<T>SLListNode* t = tab[h]; t != 0; t = t->tl)
- if ((*getkey)(t->hd) == (*getkey)(item))
- return 0;
-
- t = new <T>SLListNode(item);
- t->tl = tab[h];
- tab[h] = t;
- ++cnt;
- return 1;
- }
-
-
- int <T>ChainedHashTable::del(<U&> key)
- {
- int h = (*hash)(key) % size;
-
- <T>SLListNode* t = tab[h];
- <T>SLListNode* trail = t;
- while (t != 0)
- {
- if (getkey(t->hd) == key)
- {
- if (trail == t)
- tab[h] = t->tl;
- else
- trail->tl = t->tl;
- delete t;
- --cnt;
- return 1;
- }
- trail = t;
- t = t->tl;
- }
- return 0;
- }
-
- void <T>ChainedHashTable::apply(<T>Procedure f)
- {
- for (int i = 0; i < size; ++i)
- {
- for (<T>SLListNode* p = tab[i]; p != 0; p = p->tl)
- (*f)(p->hd);
- }
- }
-
- void <T>ChainedHashTable::clear()
- {
- for (int i = 0; i < size; ++i)
- {
- <T>SLListNode* p = tab[i];
- tab[i] = 0;
- while (p != 0)
- {
- <T>SLListNode* nxt = p->tl;
- delete(p);
- p = nxt;
- }
- }
- cnt = 0;
- }
-
- <T>ChainedHashTableTrav::<T>ChainedHashTableTrav(<T>ChainedHashTable& a)
- {
- h = &a;
- for (int i = 0; i < h->size; ++i)
- {
- if (h->tab[i] != 0)
- {
- pos = i;
- p = h->tab[i];
- return;
- }
- }
- pos = -1;
- p = 0;
- }
-
- void <T>ChainedHashTableTrav::advance()
- {
- if (p->tl != 0)
- p = p->tl;
- else
- {
- for (int i = pos + 1; i < h->size; ++i)
- {
- if (h->tab[i] != 0)
- {
- pos = i;
- p = h->tab[i];
- return;
- }
- }
- pos = -1;
- p = 0;
- }
- }
-
- int operator == (<T>ChainedHashTable& a, <T>ChainedHashTable& b)
- {
- if (a.cnt != b.cnt)
- return 0;
- for (<T>ChainedHashTableTrav p(a); p; p.advance())
- if (!b.contains(p.get()))
- return 0;
- return 1;
- }
-
-
-