(file) Return to HashTable.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 mike  1.1 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000 The Open Group, BMC Software, Tivoli Systems, IBM
  4           //
  5           // Permission is hereby granted, free of charge, to any person obtaining a
  6           // copy of this software and associated documentation files (the "Software"),
  7           // to deal in the Software without restriction, including without limitation
  8           // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9           // and/or sell copies of the Software, and to permit persons to whom the
 10           // Software is furnished to do so, subject to the following conditions:
 11           //
 12           // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 13           // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 14           // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 15           // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 16           // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 17           // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 18           // DEALINGS IN THE SOFTWARE.
 19           //
 20           //==============================================================================
 21           //
 22 mike  1.1 // Author: Mike Brasher (mbrasher@bmc.com)
 23           //
 24           // Modified By:
 25           //
 26           //%/////////////////////////////////////////////////////////////////////////////
 27           
 28           #include <cstring>
 29           #include "HashTable.h"
 30           
 31           PEGASUS_NAMESPACE_BEGIN
 32           
 33           ////////////////////////////////////////////////////////////////////////////////
 34           //
 35           // Hash()
 36           //
 37           ////////////////////////////////////////////////////////////////////////////////
 38           
 39           Uint32 Hash(const String& str)
 40           {
 41               Uint32 h = 0;
 42           
 43 mike  1.1     for (Uint32 i = 0, n = str.getLength(); i < n; i++)
 44                   h = 5 * h + str[i];
 45           
 46               return h;
 47           }
 48           
 49           ////////////////////////////////////////////////////////////////////////////////
 50           //
 51 mike  1.2 // _HashTableBase::_BucketBase
 52 mike  1.1 //
 53           ////////////////////////////////////////////////////////////////////////////////
 54           
 55 mike  1.2 _BucketBase::~_BucketBase()
 56 mike  1.1 {
 57           
 58           }
 59           
 60           ////////////////////////////////////////////////////////////////////////////////
 61           //
 62 mike  1.2 // _HashTableIteratorBase
 63 mike  1.1 //
 64           ////////////////////////////////////////////////////////////////////////////////
 65           
 66 mike  1.2 _HashTableIteratorBase _HashTableIteratorBase::operator++(int)
 67 mike  1.1 {
 68 mike  1.2     _HashTableIteratorBase tmp = *this;
 69 mike  1.1     operator++();
 70               return tmp;
 71           }
 72           
 73 mike  1.2 _HashTableIteratorBase& _HashTableIteratorBase::operator++()
 74 mike  1.1 {
 75               // At the end?
 76           
 77               if (!_bucket)
 78                   return *this;
 79           
 80               // More buckets this chain?
 81           
 82               if ((_bucket = _bucket->next))
 83                   return *this;
 84           
 85               // Find the next non-empty chain:
 86           
 87               _bucket = 0;
 88           
 89               while (_first != _last)
 90               {
 91                   if (*_first)
 92           	{
 93           	    _bucket = *_first++;
 94           	    break;
 95 mike  1.1 	}
 96           
 97           	_first++;
 98               }
 99           
100               return *this;
101           }
102           
103 mike  1.2 _HashTableIteratorBase::_HashTableIteratorBase(
104               _BucketBase** first, 
105               _BucketBase** last) : _first(first), _last(last)
106 mike  1.1 {
107               while (_first != last)
108               {
109                   if (*_first)
110           	{
111           	    _bucket = *_first++;
112           	    break;
113           	}
114           
115           	_first++;
116               }
117           }
118           
119           ////////////////////////////////////////////////////////////////////////////////
120           //
121 mike  1.2 // _HashTableBase
122 mike  1.1 //
123           ////////////////////////////////////////////////////////////////////////////////
124           
125 mike  1.2 _HashTableBase::_HashTableBase(Uint32 numChains) : _size(0), _numChains(numChains)
126 mike  1.1 {
127               if (numChains < 8)
128           	numChains = 8;
129           
130 mike  1.2     _chains = new _BucketBase*[_numChains];
131               memset(_chains, 0, sizeof(_BucketBase*) * _numChains);
132 mike  1.1 }
133           
134 mike  1.2 _HashTableBase::_HashTableBase(const _HashTableBase& x)
135           {
136               _size = 0;
137               _numChains = 0;
138               _chains = 0;
139               operator=(x);
140           }
141           
142           _HashTableBase::~_HashTableBase()
143 mike  1.1 {
144               clear();
145 mike  1.2     delete [] _chains;
146 mike  1.1 }
147           
148 mike  1.2 _HashTableBase& _HashTableBase::operator=(const _HashTableBase& x)
149 mike  1.1 {
150 mike  1.2     if (this == &x)
151           	return *this;
152           
153               // Destroy the old representation:
154           
155               clear();
156           
157               if (_chains)
158           	delete [] _chains;
159           
160               // Create chain array:
161           
162               _chains = new _BucketBase*[_numChains = x._numChains];
163               memset(_chains, 0, sizeof(_BucketBase*) * _numChains);
164               _size = x._size;
165           
166               // Copy over the buckets:
167           
168 mike  1.1     for (Uint32 i = 0; i < _numChains; i++)
169               {
170 mike  1.2 	if (x._chains[i])
171 mike  1.1 	{
172 mike  1.2 	    _chains[i] = x._chains[i]->clone();
173           
174           	    _BucketBase* curr = _chains[i];
175           	    _BucketBase* next = x._chains[i]->next;
176           
177           	    for (; next; next = next->next)
178           	    {
179           		curr->next = next->clone();
180           		curr = curr->next;
181           	    }
182           	}
183               }
184           
185               return *this;
186           }
187           
188           void _HashTableBase::clear()
189           {
190               for (Uint32 i = 0; i < _numChains; i++)
191               {
192           	for (_BucketBase* bucket = _chains[i]; bucket; )
193 mike  1.2 	{
194           	    _BucketBase* next = bucket->next;
195 mike  1.1 	    delete bucket;
196           	    bucket = next;
197           	}
198               }
199           
200               _size = 0;
201 mike  1.2 
202               if (_numChains)
203           	memset(_chains, 0, sizeof(_BucketBase*) * _numChains);
204 mike  1.1 }
205           
206 mike  1.2 Boolean _HashTableBase::insert(
207 mike  1.1     Uint32 hashCode, 
208 mike  1.2     _BucketBase* bucket, 
209 mike  1.1     const void* key)
210           {
211               // Check for duplicate entry with same key:
212           
213               Uint32 i = hashCode % _numChains;
214 mike  1.2     _BucketBase* last = 0;
215 mike  1.1 
216 mike  1.2     for (_BucketBase* bucket = _chains[i]; bucket; bucket = bucket->next)
217 mike  1.1     {
218           	if (bucket->equal(key))
219           	{
220           	    delete bucket;
221           	    return false;
222           	}
223           
224           	last = bucket;
225               }
226           
227               // Insert bucket:
228           
229               bucket->next = 0;
230           
231               if (last)
232           	last->next = bucket;
233               else
234           	_chains[i] = bucket;
235           
236               _size++;
237               return true;
238 mike  1.1 }
239           
240 mike  1.2 const _BucketBase* _HashTableBase::lookup(
241 mike  1.1     Uint32 hashCode, 
242               const void* key)
243           {
244               Uint32 i = hashCode % _numChains;
245           
246 mike  1.2     for (_BucketBase* bucket = _chains[i]; bucket; bucket = bucket->next)
247 mike  1.1     {
248           	if (bucket->equal(key))
249           	    return bucket;
250               }
251           
252               // Not found!
253               return 0;
254           }
255           
256 mike  1.2 Boolean _HashTableBase::remove(Uint32 hashCode, const void* key)
257 mike  1.1 {
258               for (Uint32 i = 0; i < _numChains; i++)
259               {
260 mike  1.2 	_BucketBase* prev = 0;
261 mike  1.1 
262 mike  1.2 	for (_BucketBase* bucket = _chains[i]; bucket; bucket = bucket->next)
263 mike  1.1 	{
264           	    if (bucket->equal(key))
265           	    {
266           		if (prev)
267           		    prev->next = bucket->next;
268           		else
269           		    _chains[i] = bucket->next;
270           
271           		delete bucket;
272           		_size--;
273           		return true;
274           	    }
275           	    prev = bucket;
276           	}
277               }
278           
279               return false;
280           }
281           
282           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2