2
* libpal - Automated Placement of Labels Library
4
* Copyright (C) 2008 Maxence Laurent, MIS-TIC, HEIG-VD
5
* University of Applied Sciences, Western Switzerland
9
* maxence.laurent <at> heig-vd <dot> ch
11
* eric.taillard <at> heig-vd <dot> ch
13
* This file is part of libpal.
15
* libpal is free software: you can redistribute it and/or modify
16
* it under the terms of the GNU General Public License as published by
17
* the Free Software Foundation, either version 3 of the License, or
18
* (at your option) any later version.
20
* libpal is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
* GNU General Public License for more details.
25
* You should have received a copy of the GNU General Public License
26
* along with libpal. If not, see <http://www.gnu.org/licenses/>.
34
#ifndef _HASHTABLE_HPP_
35
#define _HASHTABLE_HPP_
41
#include "linkedlist.hpp"
46
// Each hash entry stores a key, object pair
47
template <typename Data>
55
// This is a Hash table that maps string keys to objects of type Data
56
template <typename Data>
62
LinkedList<HashTableEntry<Data>*> **_hashtable;
64
unsigned long hash( const char * key );
67
HashTable( int tableSize );
69
bool insertItem( const char * key, Data data );
70
Data* find( const char * key );
71
bool removeElement( const char * key );
76
template <typename Data> HashTable<Data>::~HashTable()
79
LinkedList<HashTableEntry<Data>*> *list;
80
HashTableEntry <Data> *entry;
82
for ( i = 0; i < tableSize; i++ )
87
while ( list->size() > 0 )
89
entry = list->pop_front();
99
template <typename Data>
100
unsigned long HashTable<Data>::hash( const char * key )
102
unsigned long hash = 5381;
105
while (( c = *key++ ) )
107
hash = (( hash << 5 ) + hash ) + c; // hash*33 + c
110
return hash % tableSize;
114
template <typename Data>
115
HashTable<Data>::HashTable( int tableSize ) : tableSize( tableSize )
117
// TODO: Initialize the hash table
118
_hashtable = new LinkedList<HashTableEntry<Data>*>*[tableSize];
121
for ( int i = 0; i < tableSize; i++ )
123
_hashtable[i] = NULL;
127
template <class Data>
128
bool hashEntryCompare( HashTableEntry<Data> *a, HashTableEntry<Data> *b )
130
return strcmp( a->_key, b->_key ) == 0;
133
template <typename Data>
134
bool HashTable<Data>::insertItem( const char * key, Data data )
136
unsigned long i = hash( key );
138
LinkedList<HashTableEntry<Data>*> *e = _hashtable[i];
140
HashTableEntry<Data> *entry = new HashTableEntry<Data>();
141
entry->_key = new char[strlen( key ) +1];
142
strcpy( entry->_key, key );
147
Cell<HashTableEntry<Data>*> *elem = e->search( entry );
148
if ( elem ) // change data
150
elem->item->_data = data;
151
delete[] entry->_key;
156
e->push_back( entry );
162
e = _hashtable[i] = new LinkedList<HashTableEntry<Data>*> ( hashEntryCompare );
163
e->push_back( entry );
172
template <typename Data>
173
Data* HashTable<Data>::find( const char * key )
175
unsigned long i = hash( key );
177
HashTableEntry<Data> * entry = new HashTableEntry<Data> ();
178
entry->_key = new char[strlen( key ) +1];
179
strcpy( entry->_key, key );
181
LinkedList<HashTableEntry<Data>*> *e = _hashtable[i];
183
Cell<HashTableEntry<Data>*> *cell;
187
delete[] entry->_key;
193
if (( cell = e->search( entry ) ) == NULL )
195
delete[] entry->_key;
201
delete[] entry->_key;
203
return & ( cell->item->_data );
208
template<typename Data>
209
void HashTable<Data>::printStat()
216
for ( i = 0; i < tableSize; i++ )
221
c += _hashtable[i]->size();
225
std::cout << "# elem: " << c << std::endl;
226
std::cout << "# linked list : " << n << " / " << tableSize << std::endl;
227
std::cout << "nb elem / real list" << c / n << std::endl;
228
std::cout << "nb elem / tableSize" << c / tableSize << std::endl;
232
template <typename Data>
233
bool HashTable<Data>::removeElement( const char * key )
235
// TODO: Remove the element that has this key from the hash table.
236
// Return true if the entry is found or false otherwise.
238
HashTableEntry<Data> *eC = _buckets[i];
239
HashTableEntry<Data> *eP = NULL;
241
while(eC != NULL && strcmp(key, eC->_key) != 0)
251
eP->_next = eC->_next;
253
_buckets[i] = eC->_next;
262
/////////////////////////////////////
264
// Class used to iterate over the hash table
266
/////////////////////////////////////
267
/*template <typename Data>
268
class HashTableIterator {
269
int _currentBucket; // Current bucket that is being iterated
270
HashTableEntry<Data> *_currentEntry; // Current entry iterated
271
HashTable<Data> * _hashTable; // Pointer to the hash table being iterated
273
HashTableIterator(HashTable<Data> * hashTable);
274
bool next(const char * & key, Data & data);
278
template <typename Data>
279
HashTableIterator<Data>::HashTableIterator(HashTable<Data> * hashTable)
281
// TODO: Initialize iterator. "hashTable" is the table to be iterated.
282
_hashTable = hashTable;
285
template <typename Data>
286
bool HashTableIterator<Data>::next(const char * & key, Data & data)
288
// TODO: Returns the next element in the hash table.
289
// The key and data values are stored in the references passed
290
// as argument. It returns true if there are more entries or