(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 mike  1.3 Uint32 HashFunc<String>::hash(const String& str)
 40 mike  1.1 {
 41               Uint32 h = 0;
 42           
 43 mike  1.6     for (Uint32 i = 0, n = str.size(); i < n; i++)
 44 mike  1.1         h = 5 * h + str[i];
 45           
 46               return h;
 47           }
 48           
 49           ////////////////////////////////////////////////////////////////////////////////
 50           //
 51 mike  1.3 // _HashTableRep::_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 mike  1.4     _bucket = 0;
108           
109 mike  1.1     while (_first != last)
110               {
111                   if (*_first)
112           	{
113           	    _bucket = *_first++;
114           	    break;
115           	}
116           
117           	_first++;
118               }
119           }
120           
121           ////////////////////////////////////////////////////////////////////////////////
122           //
123 mike  1.3 // _HashTableRep
124 mike  1.1 //
125           ////////////////////////////////////////////////////////////////////////////////
126           
127 mike  1.3 _HashTableRep::_HashTableRep(Uint32 numChains) : _size(0), _numChains(numChains)
128 mike  1.1 {
129               if (numChains < 8)
130           	numChains = 8;
131           
132 mike  1.2     _chains = new _BucketBase*[_numChains];
133               memset(_chains, 0, sizeof(_BucketBase*) * _numChains);
134 mike  1.1 }
135           
136 mike  1.3 _HashTableRep::_HashTableRep(const _HashTableRep& x)
137 mike  1.2 {
138               _size = 0;
139               _numChains = 0;
140               _chains = 0;
141               operator=(x);
142           }
143           
144 mike  1.3 _HashTableRep::~_HashTableRep()
145 mike  1.1 {
146               clear();
147 mike  1.2     delete [] _chains;
148 mike  1.1 }
149           
150 mike  1.3 _HashTableRep& _HashTableRep::operator=(const _HashTableRep& x)
151 mike  1.1 {
152 mike  1.2     if (this == &x)
153           	return *this;
154           
155               // Destroy the old representation:
156           
157               clear();
158           
159               if (_chains)
160           	delete [] _chains;
161           
162               // Create chain array:
163           
164               _chains = new _BucketBase*[_numChains = x._numChains];
165               memset(_chains, 0, sizeof(_BucketBase*) * _numChains);
166               _size = x._size;
167           
168               // Copy over the buckets:
169           
170 mike  1.1     for (Uint32 i = 0; i < _numChains; i++)
171               {
172 mike  1.2 	if (x._chains[i])
173 mike  1.1 	{
174 mike  1.2 	    _chains[i] = x._chains[i]->clone();
175           
176           	    _BucketBase* curr = _chains[i];
177           	    _BucketBase* next = x._chains[i]->next;
178           
179           	    for (; next; next = next->next)
180           	    {
181           		curr->next = next->clone();
182           		curr = curr->next;
183           	    }
184           	}
185               }
186           
187               return *this;
188           }
189           
190 mike  1.3 void _HashTableRep::clear()
191 mike  1.2 {
192               for (Uint32 i = 0; i < _numChains; i++)
193               {
194           	for (_BucketBase* bucket = _chains[i]; bucket; )
195           	{
196           	    _BucketBase* next = bucket->next;
197 mike  1.1 	    delete bucket;
198           	    bucket = next;
199           	}
200               }
201           
202               _size = 0;
203 mike  1.2 
204               if (_numChains)
205           	memset(_chains, 0, sizeof(_BucketBase*) * _numChains);
206 mike  1.1 }
207           
208 mike  1.3 Boolean _HashTableRep::insert(
209 mike  1.1     Uint32 hashCode, 
210 mike  1.2     _BucketBase* bucket, 
211 mike  1.1     const void* key)
212           {
213               // Check for duplicate entry with same key:
214           
215               Uint32 i = hashCode % _numChains;
216 mike  1.2     _BucketBase* last = 0;
217 mike  1.1 
218 mike  1.5     for (_BucketBase* b = _chains[i]; b; b = b->next)
219 mike  1.1     {
220 mike  1.5 	if (b->equal(key))
221 mike  1.1 	{
222           	    delete bucket;
223           	    return false;
224           	}
225           
226 mike  1.5 	last = b;
227 mike  1.1     }
228           
229               // Insert bucket:
230           
231               bucket->next = 0;
232           
233               if (last)
234           	last->next = bucket;
235               else
236           	_chains[i] = bucket;
237           
238               _size++;
239               return true;
240           }
241           
242 mike  1.3 const _BucketBase* _HashTableRep::lookup(
243 mike  1.1     Uint32 hashCode, 
244               const void* key)
245           {
246               Uint32 i = hashCode % _numChains;
247           
248 mike  1.2     for (_BucketBase* bucket = _chains[i]; bucket; bucket = bucket->next)
249 mike  1.1     {
250           	if (bucket->equal(key))
251           	    return bucket;
252               }
253           
254               // Not found!
255               return 0;
256           }
257           
258 mike  1.3 Boolean _HashTableRep::remove(Uint32 hashCode, const void* key)
259 mike  1.1 {
260               for (Uint32 i = 0; i < _numChains; i++)
261               {
262 mike  1.2 	_BucketBase* prev = 0;
263 mike  1.1 
264 mike  1.2 	for (_BucketBase* bucket = _chains[i]; bucket; bucket = bucket->next)
265 mike  1.1 	{
266           	    if (bucket->equal(key))
267           	    {
268           		if (prev)
269           		    prev->next = bucket->next;
270           		else
271           		    _chains[i] = bucket->next;
272           
273           		delete bucket;
274           		_size--;
275           		return true;
276           	    }
277           	    prev = bucket;
278           	}
279               }
280           
281               return false;
282           }
283           
284           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2