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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2