dict.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:7k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: dict.cpp,v 1.4.32.3 2004/07/09 01:45:59 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hlxclib/string.h"
  50. #include "hxtypes.h"
  51. #include "dict.h"
  52. #include "hxheap.h"
  53. #ifdef _DEBUG
  54. #undef HX_THIS_FILE
  55. static const char HX_THIS_FILE[] = __FILE__;
  56. #endif
  57. unsigned int
  58. default_strhash(const char *key)
  59. { // Chris Torek's hash function
  60.     unsigned int h = 0x31fe;
  61.     while (*key)
  62. h = h*33 + *key++;
  63.     return h;
  64. }
  65. void
  66. Dict::init()
  67. {
  68.     _table = new Dict_entry*[_nbuckets];
  69.     for (unsigned int i = 0; i < _nbuckets; i++) 
  70. _table[i] = 0;
  71. }
  72. // Do this as a function (in case it's really a macro with args...need a
  73. // function ptr to use in Dict ctor.
  74. static int func_strcasecmp(const char* s1, const char* s2)
  75. {
  76.     return strcasecmp(s1, s2);
  77. }
  78. Dict::Dict(unsigned int nbuckets):
  79.     _count(0), _nbuckets(nbuckets),
  80.     _compare(func_strcasecmp), _hash(default_strhash)
  81. {
  82.     init();
  83. }
  84. Dict::Dict(int (*compare)(const char*, const char*),
  85.    unsigned int (*hash)(const char*), unsigned int nbuckets):
  86.     _count(0), _nbuckets(nbuckets),
  87.     _compare(compare), _hash(default_strhash)
  88. {
  89.     init();
  90. }
  91. Dict::~Dict()
  92. {
  93.     for (unsigned int i = 0; i < _nbuckets; i++)
  94.     {
  95. Dict_entry* nexte;
  96. for (Dict_entry* e = _table[i]; e != 0; e = nexte)
  97. {
  98.     nexte = e->next;
  99.     delete[] e->key;
  100.     delete e;
  101. }
  102.     }
  103.     delete[] _table;
  104. }
  105. Dict_entry*
  106. Dict::enter(Key key, void* obj)
  107. {
  108.     unsigned int h = _hash(key);
  109.     Dict_entry* e, *nexte;
  110.     for (e = _table[h%_nbuckets]; e != 0; e = e->next)
  111. if (_compare(key, e->key) == 0)
  112.     return e;
  113.     _count++;
  114.     // Grow the table if 66% full
  115.     unsigned int nb = _count*3;
  116.     if (nb > _nbuckets*2)
  117.     {
  118. Dict_entry** tab = new Dict_entry*[nb];
  119. unsigned int i;
  120. for (i = 0; i < nb; i++)
  121. {
  122.     tab[i] = 0;
  123. }
  124. #ifdef XXXAAK_AWAITING_CR
  125. memset(tab, 0, nb * sizeof(Dict_entry *));
  126. #endif
  127. for (i = 0; i < _nbuckets; i++)
  128. {
  129.     for (e = _table[i]; e != 0; e = nexte)
  130.     {
  131. nexte = e->next;
  132. e->next = tab[e->hash%nb];
  133. tab[e->hash%nb] = e;
  134.     }
  135. }
  136. delete[] _table;
  137. _table = tab;
  138. _nbuckets = nb;
  139.     }
  140.     e = new Dict_entry;
  141.     e->next = _table[h%_nbuckets];
  142.     e->key = new char[strlen(key)+1];
  143.     e->hash = h;
  144.     strcpy(e->key, key); /* Flawfinder: ignore */
  145.     e->obj = obj;
  146.     _table[h%_nbuckets] = e;
  147.     return e;
  148. }
  149. void*
  150. Dict::remove(Key key)
  151. {
  152.     Dict_entry* e, **ep;
  153.     unsigned int h = _hash(key);
  154.     int h_index = h%_nbuckets;
  155.     for (ep = &_table[h%_nbuckets]; (e = *ep) != 0; ep = &e->next)
  156.     {
  157. if (_compare(key, e->key) != 0)
  158.     continue;
  159. void* obj = e->obj;
  160. *ep = e->next;
  161. delete[] e->key;
  162. delete e;
  163. --_count;
  164. return obj;
  165.     }
  166.     return 0;       
  167. }
  168. Dict_entry*
  169. Dict::find(Key key)
  170. {
  171.     unsigned int h = _hash(key);
  172.     for (Dict_entry* e = _table[h%_nbuckets]; e != 0; e = e->next)
  173. if (strcasecmp(key, e->key) == 0)
  174.     return e;
  175.     return 0;
  176. }
  177. void
  178. Dict::next(unsigned int& h, Dict_entry*& e)
  179. {
  180.     e = e->next;
  181.     if (e)
  182. return;
  183.     for (unsigned int i = h+1; i < _nbuckets; i++)
  184.     {
  185. if (_table[i] == 0)
  186.     continue;
  187. e = _table[i];
  188. h = i;
  189. return;
  190.     }
  191.     e = 0;
  192. }
  193. #ifdef XXXAAK_AWAITING_CR
  194. Dict_entry*
  195. Dict::enter(Key key, void* obj, UINT32& hashId)
  196. {
  197.     unsigned int h = hashId =_hash(key);
  198.     Dict_entry* e, *nexte;
  199.     for (e = _table[h%_nbuckets]; e != 0; e = e->next)
  200. if (h == e->hash)
  201.     return e;
  202.     _count++;
  203.     // Grow the table if 66% full
  204.     unsigned int nb = _count*3;
  205.     if (nb > _nbuckets*2)
  206.     {
  207. Dict_entry** tab = new Dict_entry*[nb];
  208. unsigned int i;
  209. memset(tab, 0, nb * sizeof(Dict_entry *));
  210. for (i = 0; i < _nbuckets; i++)
  211. {
  212.     for (e = _table[i]; e != 0; e = nexte)
  213.     {
  214. nexte = e->next;
  215. e->next = tab[e->hash%nb];
  216. tab[e->hash%nb] = e;
  217.     }
  218. }
  219. delete[] _table;
  220. _table = tab;
  221. _nbuckets = nb;
  222.     }
  223.     e = new Dict_entry;
  224.     e->next = _table[h%_nbuckets];
  225.     e->key = new char[strlen(key)+1];
  226.     e->hash = h;
  227.     strcpy(e->key, key); /* Flawfinder: ignore */
  228.     e->obj = obj;
  229.     _table[h%_nbuckets] = e;
  230.     return e;
  231. }
  232. void*
  233. Dict::remove(UINT32 hashId)
  234. {
  235.     if (!hashId)
  236. return 0;
  237.     Dict_entry* e, **ep;
  238.     int h_index = hashId%_nbuckets;
  239.     for (ep = &_table[hashId%_nbuckets]; (e = *ep) != 0; ep = &e->next)
  240.     {
  241. if (hashId != e->hash)
  242.     continue;
  243. void* obj = e->obj;
  244. *ep = e->next;
  245. delete[] e->key;
  246. delete e;
  247. --_count;
  248. return obj;
  249.     }
  250.     return 0;       
  251. }
  252. Dict_entry*
  253. Dict::find(UINT32 hashId)
  254. {
  255.     if (!hashId)
  256. return 0;
  257.     for (Dict_entry* e = _table[hashId%_nbuckets]; e != 0; e = e->next)
  258. if (hashId == e->hash)
  259.     return e;
  260.     return 0;
  261. }
  262. #endif