SWIHashMap.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:9k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. #if _MSC_VER >= 1100    // Visual C++ 5.x
  23. #pragma warning( disable : 4786 4503 )
  24. #endif
  25. #include "SWIHashMap.hpp"
  26. #include "SWItrdMonitor.hpp"
  27. const int SWIHashMap::DEFAULT_CAPACITY = 11;
  28. const double SWIHashMap::DEFAULT_LOAD_FACTOR = 0.75;
  29. SWIHashMap::Entry::Entry(const SWIHashable* key, const void *value):
  30.   _key(key->clone()), _value(value), _next(NULL), _prev(NULL)
  31. {}
  32. SWIHashMap::Entry::~Entry()
  33. {
  34.   delete _key;
  35. }
  36. const SWIHashable& SWIHashMap::Entry::getKey() const
  37. {
  38.   return *_key;
  39. }
  40. const void *SWIHashMap::Entry::getValue() const
  41. {
  42.   return _value;
  43. }
  44. const void *SWIHashMap::Entry::setValue(const void *value)
  45. {
  46.   const void *result = _value;
  47.   _value = value;
  48.   return result;
  49. }
  50. SWIHashMap::SWIHashMap()
  51. {
  52.   init(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
  53. }
  54. SWIHashMap::SWIHashMap(int capacity)
  55. {
  56.   init(capacity, DEFAULT_LOAD_FACTOR);
  57. }
  58. SWIHashMap::SWIHashMap(int capacity,
  59.                        double loadFactor)
  60. {
  61.   init(capacity, loadFactor);
  62. }
  63. void SWIHashMap::init(int capacity,
  64.                       double loadFactor)
  65. {
  66.   _capacity = capacity <= 0 ? 1 : capacity;
  67.   _loadFactor = loadFactor <= 0.0 ? DEFAULT_LOAD_FACTOR : loadFactor;
  68.   _size = 0;
  69.   _entries = new Entry*[capacity];
  70.   for (int i = 0; i < capacity; i++)
  71.   {
  72.     _entries[i] = NULL;
  73.   }
  74.   _threshold = (int) (_capacity * _loadFactor);
  75. }
  76. SWIHashMap::SWIHashMap(const SWIHashMap& original)
  77. {
  78.   init(original._capacity, original._loadFactor);
  79.   copy(original);
  80. }
  81. void SWIHashMap::copy(const SWIHashMap& original)
  82. {
  83.   _size = original.size();
  84.   for (int i = 0; i < _capacity; i++)
  85.   {
  86.     Entry *origEntry = original._entries[i];
  87.     Entry *lastEntry = NULL;
  88.     while (origEntry != NULL)
  89.     {
  90.       // Create a copy of the entry and insert it at the end of the
  91.       // list.
  92.       Entry *tmp = new Entry(origEntry->_key, origEntry->_value);
  93.       tmp->_hashCode = origEntry->_hashCode;
  94.       tmp->_next = NULL;
  95.       tmp->_prev = lastEntry;
  96.       if (lastEntry != NULL)
  97.         lastEntry->_next = tmp;
  98.       else
  99.         _entries[i] = tmp;
  100.       lastEntry = tmp;
  101.       origEntry = origEntry->_next;
  102.     }
  103.   }
  104. }
  105. SWIHashMap::~SWIHashMap()
  106. {
  107.   clear();
  108.   delete [] _entries;
  109. }
  110. void SWIHashMap::clear()
  111. {
  112.   Entry *tmp;
  113.   for (int i = 0; i < _capacity && _size > 0; i++)
  114.   {
  115.     while (_entries[i] != NULL)
  116.     {
  117.       tmp = _entries[i];
  118.       _entries[i] = tmp->_next;
  119.       delete tmp;
  120.       _size--;
  121.     }
  122.   }
  123. }
  124. const void *SWIHashMap::getValue(const SWIHashable& key) const
  125. {
  126.   unsigned int hashCode = key.hashCode();
  127.   const Entry *entry = _entries[hashCode % _capacity];
  128.   while (entry != NULL)
  129.   {
  130.     if (entry->_hashCode == hashCode &&
  131.         key.equals(entry->_key))
  132.     {
  133.       return entry->_value;
  134.     }
  135.     entry = entry->_next;
  136.   }
  137.   return NULL;
  138. }
  139. void SWIHashMap::rehash()
  140. {
  141.   int oldCapacity = _capacity;
  142.   Entry** oldEntries = _entries;
  143.   _capacity = _capacity * 2 + 1;
  144.   _entries = new Entry*[_capacity];
  145.   _threshold = (int)(_capacity * _loadFactor);
  146.   int i;
  147.   for (i = 0; i < _capacity; i++)
  148.   {
  149.     _entries[i] = NULL;
  150.   }
  151.   for (i = 0; i < oldCapacity; i++)
  152.   {
  153.     for (Entry * entry = oldEntries[i]; entry != NULL; )
  154.     {
  155.       Entry *e = entry;
  156.       entry = entry->_next;
  157.       int idx = e->_hashCode % _capacity;
  158.       if (_entries[idx] != NULL)
  159.       {
  160.         _entries[idx]->_prev = e;
  161.       }
  162.       e->_next = _entries[idx];
  163.       e->_prev = NULL;
  164.       _entries[idx] = e;
  165.     }
  166.   }
  167.   delete [] oldEntries;
  168. }
  169. const void * SWIHashMap::putValue(const SWIHashable& key, const void *value)
  170. {
  171.   unsigned int hashCode = key.hashCode();
  172.   int idx = hashCode % _capacity;
  173.   Entry *entry = _entries[idx];
  174.   while (entry != NULL)
  175.   {
  176.     if (entry->_hashCode == hashCode &&
  177.         key.equals(entry->_key))
  178.     {
  179.       // Replace current value by new one.
  180.       const void *result = entry->_value;
  181.       entry->_value = value;
  182.       return result;
  183.     }
  184.     entry = entry->_next;
  185.   }
  186.   //If we get here, we need to add the key into the hash table.
  187.   // First verify if we need to rehash.
  188.   if (_size >= _threshold)
  189.   {
  190.     rehash();
  191.     idx = hashCode % _capacity;
  192.   }
  193.   entry = new Entry(&key, value);
  194.   entry->_hashCode = hashCode;
  195.   entry->_next = _entries[idx];
  196.   if (entry->_next != NULL)
  197.     entry->_next->_prev = entry;
  198.   entry->_prev = NULL;
  199.   _entries[idx] = entry;
  200.   _size++;
  201.   return NULL;
  202. }
  203. void SWIHashMap::remove(Entry *entry, int idx)
  204. {
  205.   // Remove entry from the list.
  206.   if (entry->_next != NULL)
  207.     entry->_next->_prev = entry->_prev;
  208.   if (entry->_prev != NULL)
  209.     entry->_prev->_next = entry->_next;
  210.   else
  211.     _entries[idx] = entry->_next;
  212.   delete entry;
  213.   _size--;
  214. }
  215. const void *SWIHashMap::remove(const SWIHashable& key)
  216. {
  217.   unsigned int hashCode = key.hashCode();
  218.   int idx = hashCode % _capacity;
  219.   Entry *entry = _entries[idx];
  220.   while (entry != NULL)
  221.   {
  222.     if (entry->_hashCode == hashCode &&
  223.         key.equals(entry->_key))
  224.     {
  225.       const void *result = entry->_value;
  226.       remove(entry, idx);
  227.       return result;
  228.     }
  229.     entry = entry->_next;
  230.   }
  231.   return NULL;
  232. }
  233. void SWIHashMap::advance(Entry *&cursor, int& idx)
  234. {
  235.   if (cursor != NULL)
  236.   {
  237.     cursor = cursor->_next;
  238.     if (cursor == NULL)
  239.     {
  240.       while (++idx < _capacity)
  241.       {
  242.         if (_entries[idx] != NULL)
  243.         {
  244.           cursor = _entries[idx];
  245.           break;
  246.         }
  247.       }
  248.     }
  249.   }
  250.   else
  251.   {
  252.     for (idx = 0; idx < _capacity; idx++)
  253.     {
  254.       if (_entries[idx] != NULL)
  255.       {
  256.         cursor = _entries[idx];
  257.         break;
  258.       }
  259.     }
  260.   }
  261. }
  262. SWIHashMap& SWIHashMap::operator=(const SWIHashMap& rhs)
  263. {
  264.   if (this != &rhs)
  265.   {
  266.     clear();
  267.     if (_capacity < rhs._capacity)
  268.     {
  269.       delete [] _entries;
  270.       init(rhs._capacity, rhs._loadFactor);
  271.     }
  272.     else
  273.     {
  274.       _capacity = rhs._capacity;
  275.       _loadFactor = rhs._loadFactor;
  276.       _threshold = rhs._threshold;
  277.       _entries = new Entry *[_capacity];
  278.       for (int i = 0; i < _capacity; i++)
  279.       {
  280.         _entries[i] = NULL;
  281.       }
  282.     }
  283.     copy(rhs);
  284.   }
  285.   return *this;
  286. }
  287. int SWIHashMap::size() const
  288. {
  289.   return _size;
  290. }
  291. bool SWIHashMap::isEmpty() const
  292. {
  293.   return _size == 0;
  294. }
  295. SWIHashMap::Iterator::Iterator(SWIHashMap& hashMap):
  296.   _cursor(NULL), _idx(0), _prevCursor(NULL), _prevIdx(0)
  297. {
  298.   _hashMap = &hashMap;
  299.   _hashMap->advance(_cursor, _idx);
  300. }
  301. SWIHashMap::Iterator::Iterator(const Iterator& original)
  302. {
  303.   _hashMap = original._hashMap;
  304.   _cursor = original._cursor;
  305.   _idx = original._idx;
  306.   _prevCursor = original._prevCursor;
  307.   _prevIdx = original._prevIdx;
  308. }
  309. SWIHashMap::Iterator& SWIHashMap::Iterator::operator=(const Iterator& rhs)
  310. {
  311.   if (this != &rhs)
  312.   {
  313.     _hashMap = rhs._hashMap;
  314.     _cursor = rhs._cursor;
  315.     _idx = rhs._idx;
  316.     _prevCursor = rhs._prevCursor;
  317.     _prevIdx = rhs._prevIdx;
  318.   }
  319.   return *this;
  320. }
  321. SWIHashMap::Iterator::~Iterator()
  322. {}
  323. void SWIHashMap::Iterator::reset() const
  324. {
  325.   Iterator *pThis = (Iterator *) this;
  326.   pThis->_prevCursor = pThis->_cursor = NULL;
  327.   pThis->_prevIdx = pThis->_idx = 0;
  328.   pThis->_hashMap->advance(pThis->_cursor, pThis->_idx);
  329. }
  330. bool SWIHashMap::Iterator::hasNext() const
  331. {
  332.   return _cursor != NULL;
  333. }
  334. SWIHashMap::Entry *SWIHashMap::Iterator::next()
  335. {
  336.   if (_cursor == NULL)
  337.     return NULL;
  338.   _prevCursor = _cursor;
  339.   _prevIdx = _idx;
  340.   _hashMap->advance(_cursor, _idx);
  341.   return _prevCursor;
  342. }
  343. const SWIHashMap::Entry *SWIHashMap::Iterator::next() const
  344. {
  345.   Iterator *pThis = (Iterator *) this;
  346.   return pThis->next();
  347. }
  348. bool SWIHashMap::Iterator::remove()
  349. {
  350.   if (_prevCursor == NULL)
  351.   {
  352.     return false;
  353.   }
  354.   _hashMap->remove(_prevCursor, _prevIdx);
  355.   _prevCursor = NULL;
  356.   return true;
  357. }
  358. const void *SWIHashMap::Iterator::setValue(const void *value)
  359. {
  360.   if (_prevCursor == NULL)
  361.     return NULL;
  362.   const void *oldValue = _prevCursor->getValue();
  363.   _prevCursor->setValue(value);
  364.   return oldValue;
  365. }