/* -*-Mode: C++;-*- * PRCS - The Project Revision Control System * Copyright (C) 1997 Josh MacDonald * Copyright (C) 1995 P. N. Hilfinger * * This program 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 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: hash.h 1.2.1.2.2.1.1.2 Mon, 01 Jun 1998 01:44:36 -0700 jmacd $ */ #ifndef _HASH_H_ #define _HASH_H_ #include #include "dynarray.h" template class Pair { public: Pair(const X& x0, const Y& y0) :x1(x0), y1(y0) { } const X& x() const { return x1; } X& x() { return x1; } const Y& y() const { return y1; } Y& y() { return y1; } private: X x1; Y y1; }; template class List { public: List(const T& h0, List* t0) :h(h0), t(t0) { } const T& head() const { return h; } T& head() { return h; } List* tail() const { return t; } List*& tail() { return t; } void deleteList() { if ( t != NULL ) t->deleteList(); delete this; } List* nreverse(); private: T h; List* t; }; #define generic template #define selftype HashTable generic class HashTable { public: typedef Pair< Key, Data > HashItem; typedef List< HashItem > ItemList; HashTable(int (*func0)(const Key&, int) = NULL, bool (*equal0)(const Key&, const Key&) = NULL); ~HashTable(); void remove(const Key& x); Data* lookup(const Key& x) const; HashItem* lookup_pair(const Key& x) const; Data* insert(const Key& x, const Data& init); bool isdefined(const Key& x) const { return lookup(x) != NULL; } int M; /* Number of buckets. */ class HashIterator { public: HashIterator(selftype* h0) { h = h0; list_index = -1; list_head = NULL; next(); } HashItem& operator*() const { return list_head->head(); } void next() { do { if(list_head) { list_head = list_head->tail(); } else { list_index += 1; if(list_index >= h->M) return; list_head = h->L[list_index]; } } while(!list_head); } bool finished() const { return list_index >= h->M; } private: selftype* h; int list_index; ItemList* list_head; }; friend class HashIterator; private: ItemList** L; /* array of buckets */ int N; /* The number of items in the hash table. */ int prime; /* Index into a table of prime sizes. */ Data* find(const Key& x, int hashValue) const; /* Internal routine to find a Data item on L[hashValue]. */ void init(int p); /* Used to initialize a HashTable to be empty and with primes[p] */ /* buckets. */ int (*func)(const Key&, int); bool (*equalfunc)(const Key&, const Key&); }; #undef selftype #undef generic #define generic template #define selftype OrderedTable generic class OrderedTable { public: OrderedTable (); ~OrderedTable (); typedef Dynarray KeyArray; typedef Dynarray DataArray; typedef HashTable Table; Data* insert(const Key& x, const Data& init); Data* lookup(const Key& x) const; void remove(const Key& x); Table* table() const; KeyArray* key_array() const; DataArray* data_array() const; private: Table* _table; KeyArray* _key_array; DataArray* _data_array; }; #undef selftype #undef generic #endif