WMap.cpp
上传用户:hmc_gdtv
上传日期:2013-08-04
资源大小:798k
文件大小:4k
源码类别:

Windows Mobile

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 2001,2002,2003 Mike Matsnev.  All Rights Reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice immediately at the beginning of the file, without modification,
  10.  *    this list of conditions, and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. Absolutely no warranty of function or purpose is made by the author
  15.  *    Mike Matsnev.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  * 
  28.  * $Id: WMap.cpp,v 1.2.2.1 2003/04/12 22:52:34 mike Exp $
  29.  * 
  30.  */
  31. #include <afx.h>
  32. #include "FastArray.h"
  33. #include "StrBuf.h"
  34. #include "WMap.h"
  35. WMap::WMap(HANDLE heap,bool freemem) : m_hepool(heap,freemem),
  36.   m_strbuf(heap,freemem), m_heap(heap), m_freemem(freemem),
  37.   m_cursize(STARTSIZE), m_curmask(STARTSIZE-1), m_numkeys(0)
  38. {
  39.   m_array=(HE**)HeapAlloc(m_heap,HEAP_NO_SERIALIZE|HEAP_ZERO_MEMORY,
  40.   m_cursize*sizeof(HE*));
  41.   if (!m_array)
  42.     AfxThrowMemoryException();
  43. }
  44. WMap::~WMap() {
  45.   if (m_freemem)
  46.     HeapFree(m_heap,HEAP_NO_SERIALIZE,m_array);
  47. }
  48. // Hash algorithm is One-at-a-Time by Bob Jenkins,
  49. // http://burtleburtle.net/bob/hash/evahash.html
  50. // microsoft's arm compiler from evt3 really sucks here, because it does
  51. // not realize that x+x*2^n can be very efficientlly computed
  52. // in one instruction using builtin shifter on ARM cpus, it
  53. // generates three instructions instead, like this pseudocode:
  54. //   tmp=2^n
  55. //   tmp|=1
  56. //   x*tmp
  57. unsigned int WMap::Hash(const wchar_t *data) {
  58.   unsigned int hash;
  59.   if (!*data) // shortcut
  60.     return 0;
  61.   hash=0;
  62.   do { 
  63.     hash+=*data++;
  64.     hash+=hash<<10;
  65.     hash^=hash>>6;
  66.   } while (*data);
  67.   hash+=hash<<3;
  68.   hash^=hash>>11;
  69.   hash+=hash<<15;
  70.   return hash;
  71. }
  72. WMap::HE  *WMap::RealLookup(const wchar_t *key,bool add,bool copykey) {
  73.   UINT   hash=Hash(key);
  74.   UINT   bucket=hash&m_curmask;
  75.   HE   *he;
  76.   for (he=m_array[bucket];he;he=he->next)
  77.     if (!wcscmp(key,he->key))
  78.       return he;
  79.   if (!add)
  80.     return NULL;
  81.   he=m_hepool.Get();
  82.   he->key=copykey ? m_strbuf.Append(key,wcslen(key)+1) : key;
  83.   he->hash=hash;
  84.   he->next=m_array[bucket];
  85.   m_array[bucket]=he;
  86.   if (++m_numkeys*FILLFACTOR>m_cursize)
  87.     Extend();
  88.   return he;
  89. }
  90. bool WMap::Lookup(const wchar_t *key,void*& value) {
  91.   HE *he=RealLookup(key,false,false);
  92.   if (he) {
  93.     value=he->value;
  94.     return true;
  95.   }
  96.   return false;
  97. }
  98. void WMap::RemoveAll() {
  99.   m_hepool.RemoveAll();
  100.   m_strbuf.RemoveAll();
  101.   m_numkeys=0;
  102. }
  103. void WMap::Extend() {
  104.   int newsize=m_cursize<<1;
  105.   HE **na=(HE**)HeapReAlloc(m_heap,HEAP_NO_SERIALIZE,m_array,newsize*sizeof(HE*));
  106.   if (!na)
  107.     AfxThrowMemoryException();
  108.   memset(na+m_cursize,0,m_cursize*sizeof(HE**));
  109.   for (int i=0;i<m_cursize;++i) {
  110.     HE   **prev=&na[i],*cur=na[i];
  111.     while (cur) {
  112.       if (cur->hash & m_cursize) {
  113. *prev=cur->next;
  114. cur->next=na[i+m_cursize];
  115. na[i+m_cursize]=cur;
  116. cur=*prev;
  117.       } else {
  118. prev=&cur->next;
  119. cur=cur->next;
  120.       }
  121.     }
  122.   }
  123.   m_cursize=newsize;
  124.   m_curmask=m_cursize-1;
  125.   m_array=na;
  126. }