extensions/sqlite/sqlite-source/hash.c
changeset 3594 0a382baff180
parent 3593 f04de1a697bd
child 3595 09c38814fe7b
     1.1 --- a/extensions/sqlite/sqlite-source/hash.c	Fri Aug 03 07:56:31 2012 -0400
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,418 +0,0 @@
     1.4 -/*
     1.5 -** 2001 September 22
     1.6 -**
     1.7 -** The author disclaims copyright to this source code.  In place of
     1.8 -** a legal notice, here is a blessing:
     1.9 -**
    1.10 -**    May you do good and not evil.
    1.11 -**    May you find forgiveness for yourself and forgive others.
    1.12 -**    May you share freely, never taking more than you give.
    1.13 -**
    1.14 -*************************************************************************
    1.15 -** This is the implementation of generic hash-tables
    1.16 -** used in SQLite.
    1.17 -**
    1.18 -** $Id$
    1.19 -*/
    1.20 -#include "sqliteInt.h"
    1.21 -#include <assert.h>
    1.22 -
    1.23 -/* Turn bulk memory into a hash table object by initializing the
    1.24 -** fields of the Hash structure.
    1.25 -**
    1.26 -** "pNew" is a pointer to the hash table that is to be initialized.
    1.27 -** keyClass is one of the constants SQLITE_HASH_INT, SQLITE_HASH_POINTER,
    1.28 -** SQLITE_HASH_BINARY, or SQLITE_HASH_STRING.  The value of keyClass 
    1.29 -** determines what kind of key the hash table will use.  "copyKey" is
    1.30 -** true if the hash table should make its own private copy of keys and
    1.31 -** false if it should just use the supplied pointer.  CopyKey only makes
    1.32 -** sense for SQLITE_HASH_STRING and SQLITE_HASH_BINARY and is ignored
    1.33 -** for other key classes.
    1.34 -*/
    1.35 -void sqlite3HashInit(Hash *pNew, int keyClass, int copyKey){
    1.36 -  assert( pNew!=0 );
    1.37 -  assert( keyClass>=SQLITE_HASH_STRING && keyClass<=SQLITE_HASH_BINARY );
    1.38 -  pNew->keyClass = keyClass;
    1.39 -#if 0
    1.40 -  if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0;
    1.41 -#endif
    1.42 -  pNew->copyKey = copyKey;
    1.43 -  pNew->first = 0;
    1.44 -  pNew->count = 0;
    1.45 -  pNew->htsize = 0;
    1.46 -  pNew->ht = 0;
    1.47 -}
    1.48 -
    1.49 -/* Remove all entries from a hash table.  Reclaim all memory.
    1.50 -** Call this routine to delete a hash table or to reset a hash table
    1.51 -** to the empty state.
    1.52 -*/
    1.53 -void sqlite3HashClear(Hash *pH){
    1.54 -  HashElem *elem;         /* For looping over all elements of the table */
    1.55 -
    1.56 -  assert( pH!=0 );
    1.57 -  elem = pH->first;
    1.58 -  pH->first = 0;
    1.59 -  if( pH->ht ) sqlite3_free(pH->ht);
    1.60 -  pH->ht = 0;
    1.61 -  pH->htsize = 0;
    1.62 -  while( elem ){
    1.63 -    HashElem *next_elem = elem->next;
    1.64 -    if( pH->copyKey && elem->pKey ){
    1.65 -      sqlite3_free(elem->pKey);
    1.66 -    }
    1.67 -    sqlite3_free(elem);
    1.68 -    elem = next_elem;
    1.69 -  }
    1.70 -  pH->count = 0;
    1.71 -}
    1.72 -
    1.73 -#if 0 /* NOT USED */
    1.74 -/*
    1.75 -** Hash and comparison functions when the mode is SQLITE_HASH_INT
    1.76 -*/
    1.77 -static int intHash(const void *pKey, int nKey){
    1.78 -  return nKey ^ (nKey<<8) ^ (nKey>>8);
    1.79 -}
    1.80 -static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
    1.81 -  return n2 - n1;
    1.82 -}
    1.83 -#endif
    1.84 -
    1.85 -#if 0 /* NOT USED */
    1.86 -/*
    1.87 -** Hash and comparison functions when the mode is SQLITE_HASH_POINTER
    1.88 -*/
    1.89 -static int ptrHash(const void *pKey, int nKey){
    1.90 -  uptr x = Addr(pKey);
    1.91 -  return x ^ (x<<8) ^ (x>>8);
    1.92 -}
    1.93 -static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
    1.94 -  if( pKey1==pKey2 ) return 0;
    1.95 -  if( pKey1<pKey2 ) return -1;
    1.96 -  return 1;
    1.97 -}
    1.98 -#endif
    1.99 -
   1.100 -/*
   1.101 -** Hash and comparison functions when the mode is SQLITE_HASH_STRING
   1.102 -*/
   1.103 -static int strHash(const void *pKey, int nKey){
   1.104 -  const char *z = (const char *)pKey;
   1.105 -  int h = 0;
   1.106 -  if( nKey<=0 ) nKey = strlen(z);
   1.107 -  while( nKey > 0  ){
   1.108 -    h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
   1.109 -    nKey--;
   1.110 -  }
   1.111 -  return h & 0x7fffffff;
   1.112 -}
   1.113 -static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
   1.114 -  if( n1!=n2 ) return 1;
   1.115 -  return sqlite3StrNICmp((const char*)pKey1,(const char*)pKey2,n1);
   1.116 -}
   1.117 -
   1.118 -/*
   1.119 -** Hash and comparison functions when the mode is SQLITE_HASH_BINARY
   1.120 -*/
   1.121 -static int binHash(const void *pKey, int nKey){
   1.122 -  int h = 0;
   1.123 -  const char *z = (const char *)pKey;
   1.124 -  while( nKey-- > 0 ){
   1.125 -    h = (h<<3) ^ h ^ *(z++);
   1.126 -  }
   1.127 -  return h & 0x7fffffff;
   1.128 -}
   1.129 -static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
   1.130 -  if( n1!=n2 ) return 1;
   1.131 -  return memcmp(pKey1,pKey2,n1);
   1.132 -}
   1.133 -
   1.134 -/*
   1.135 -** Return a pointer to the appropriate hash function given the key class.
   1.136 -**
   1.137 -** The C syntax in this function definition may be unfamilar to some 
   1.138 -** programmers, so we provide the following additional explanation:
   1.139 -**
   1.140 -** The name of the function is "hashFunction".  The function takes a
   1.141 -** single parameter "keyClass".  The return value of hashFunction()
   1.142 -** is a pointer to another function.  Specifically, the return value
   1.143 -** of hashFunction() is a pointer to a function that takes two parameters
   1.144 -** with types "const void*" and "int" and returns an "int".
   1.145 -*/
   1.146 -static int (*hashFunction(int keyClass))(const void*,int){
   1.147 -#if 0  /* HASH_INT and HASH_POINTER are never used */
   1.148 -  switch( keyClass ){
   1.149 -    case SQLITE_HASH_INT:     return &intHash;
   1.150 -    case SQLITE_HASH_POINTER: return &ptrHash;
   1.151 -    case SQLITE_HASH_STRING:  return &strHash;
   1.152 -    case SQLITE_HASH_BINARY:  return &binHash;;
   1.153 -    default: break;
   1.154 -  }
   1.155 -  return 0;
   1.156 -#else
   1.157 -  if( keyClass==SQLITE_HASH_STRING ){
   1.158 -    return &strHash;
   1.159 -  }else{
   1.160 -    assert( keyClass==SQLITE_HASH_BINARY );
   1.161 -    return &binHash;
   1.162 -  }
   1.163 -#endif
   1.164 -}
   1.165 -
   1.166 -/*
   1.167 -** Return a pointer to the appropriate hash function given the key class.
   1.168 -**
   1.169 -** For help in interpreted the obscure C code in the function definition,
   1.170 -** see the header comment on the previous function.
   1.171 -*/
   1.172 -static int (*compareFunction(int keyClass))(const void*,int,const void*,int){
   1.173 -#if 0 /* HASH_INT and HASH_POINTER are never used */
   1.174 -  switch( keyClass ){
   1.175 -    case SQLITE_HASH_INT:     return &intCompare;
   1.176 -    case SQLITE_HASH_POINTER: return &ptrCompare;
   1.177 -    case SQLITE_HASH_STRING:  return &strCompare;
   1.178 -    case SQLITE_HASH_BINARY:  return &binCompare;
   1.179 -    default: break;
   1.180 -  }
   1.181 -  return 0;
   1.182 -#else
   1.183 -  if( keyClass==SQLITE_HASH_STRING ){
   1.184 -    return &strCompare;
   1.185 -  }else{
   1.186 -    assert( keyClass==SQLITE_HASH_BINARY );
   1.187 -    return &binCompare;
   1.188 -  }
   1.189 -#endif
   1.190 -}
   1.191 -
   1.192 -/* Link an element into the hash table
   1.193 -*/
   1.194 -static void insertElement(
   1.195 -  Hash *pH,              /* The complete hash table */
   1.196 -  struct _ht *pEntry,    /* The entry into which pNew is inserted */
   1.197 -  HashElem *pNew         /* The element to be inserted */
   1.198 -){
   1.199 -  HashElem *pHead;       /* First element already in pEntry */
   1.200 -  pHead = pEntry->chain;
   1.201 -  if( pHead ){
   1.202 -    pNew->next = pHead;
   1.203 -    pNew->prev = pHead->prev;
   1.204 -    if( pHead->prev ){ pHead->prev->next = pNew; }
   1.205 -    else             { pH->first = pNew; }
   1.206 -    pHead->prev = pNew;
   1.207 -  }else{
   1.208 -    pNew->next = pH->first;
   1.209 -    if( pH->first ){ pH->first->prev = pNew; }
   1.210 -    pNew->prev = 0;
   1.211 -    pH->first = pNew;
   1.212 -  }
   1.213 -  pEntry->count++;
   1.214 -  pEntry->chain = pNew;
   1.215 -}
   1.216 -
   1.217 -
   1.218 -/* Resize the hash table so that it cantains "new_size" buckets.
   1.219 -** "new_size" must be a power of 2.  The hash table might fail 
   1.220 -** to resize if sqlite3_malloc() fails.
   1.221 -*/
   1.222 -static void rehash(Hash *pH, int new_size){
   1.223 -  struct _ht *new_ht;            /* The new hash table */
   1.224 -  HashElem *elem, *next_elem;    /* For looping over existing elements */
   1.225 -  int (*xHash)(const void*,int); /* The hash function */
   1.226 -
   1.227 -  assert( (new_size & (new_size-1))==0 );
   1.228 -
   1.229 -  /* There is a call to sqlite3_malloc() inside rehash(). If there is
   1.230 -  ** already an allocation at pH->ht, then if this malloc() fails it
   1.231 -  ** is benign (since failing to resize a hash table is a performance
   1.232 -  ** hit only, not a fatal error).
   1.233 -  */
   1.234 -  sqlite3MallocBenignFailure(pH->htsize>0);
   1.235 -
   1.236 -  new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) );
   1.237 -  if( new_ht==0 ) return;
   1.238 -  if( pH->ht ) sqlite3_free(pH->ht);
   1.239 -  pH->ht = new_ht;
   1.240 -  pH->htsize = new_size;
   1.241 -  xHash = hashFunction(pH->keyClass);
   1.242 -  for(elem=pH->first, pH->first=0; elem; elem = next_elem){
   1.243 -    int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
   1.244 -    next_elem = elem->next;
   1.245 -    insertElement(pH, &new_ht[h], elem);
   1.246 -  }
   1.247 -}
   1.248 -
   1.249 -/* This function (for internal use only) locates an element in an
   1.250 -** hash table that matches the given key.  The hash for this key has
   1.251 -** already been computed and is passed as the 4th parameter.
   1.252 -*/
   1.253 -static HashElem *findElementGivenHash(
   1.254 -  const Hash *pH,     /* The pH to be searched */
   1.255 -  const void *pKey,   /* The key we are searching for */
   1.256 -  int nKey,
   1.257 -  int h               /* The hash for this key. */
   1.258 -){
   1.259 -  HashElem *elem;                /* Used to loop thru the element list */
   1.260 -  int count;                     /* Number of elements left to test */
   1.261 -  int (*xCompare)(const void*,int,const void*,int);  /* comparison function */
   1.262 -
   1.263 -  if( pH->ht ){
   1.264 -    struct _ht *pEntry = &pH->ht[h];
   1.265 -    elem = pEntry->chain;
   1.266 -    count = pEntry->count;
   1.267 -    xCompare = compareFunction(pH->keyClass);
   1.268 -    while( count-- && elem ){
   1.269 -      if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ 
   1.270 -        return elem;
   1.271 -      }
   1.272 -      elem = elem->next;
   1.273 -    }
   1.274 -  }
   1.275 -  return 0;
   1.276 -}
   1.277 -
   1.278 -/* Remove a single entry from the hash table given a pointer to that
   1.279 -** element and a hash on the element's key.
   1.280 -*/
   1.281 -static void removeElementGivenHash(
   1.282 -  Hash *pH,         /* The pH containing "elem" */
   1.283 -  HashElem* elem,   /* The element to be removed from the pH */
   1.284 -  int h             /* Hash value for the element */
   1.285 -){
   1.286 -  struct _ht *pEntry;
   1.287 -  if( elem->prev ){
   1.288 -    elem->prev->next = elem->next; 
   1.289 -  }else{
   1.290 -    pH->first = elem->next;
   1.291 -  }
   1.292 -  if( elem->next ){
   1.293 -    elem->next->prev = elem->prev;
   1.294 -  }
   1.295 -  pEntry = &pH->ht[h];
   1.296 -  if( pEntry->chain==elem ){
   1.297 -    pEntry->chain = elem->next;
   1.298 -  }
   1.299 -  pEntry->count--;
   1.300 -  if( pEntry->count<=0 ){
   1.301 -    pEntry->chain = 0;
   1.302 -  }
   1.303 -  if( pH->copyKey ){
   1.304 -    sqlite3_free(elem->pKey);
   1.305 -  }
   1.306 -  sqlite3_free( elem );
   1.307 -  pH->count--;
   1.308 -  if( pH->count<=0 ){
   1.309 -    assert( pH->first==0 );
   1.310 -    assert( pH->count==0 );
   1.311 -    sqlite3HashClear(pH);
   1.312 -  }
   1.313 -}
   1.314 -
   1.315 -/* Attempt to locate an element of the hash table pH with a key
   1.316 -** that matches pKey,nKey.  Return a pointer to the corresponding 
   1.317 -** HashElem structure for this element if it is found, or NULL
   1.318 -** otherwise.
   1.319 -*/
   1.320 -HashElem *sqlite3HashFindElem(const Hash *pH, const void *pKey, int nKey){
   1.321 -  int h;             /* A hash on key */
   1.322 -  HashElem *elem;    /* The element that matches key */
   1.323 -  int (*xHash)(const void*,int);  /* The hash function */
   1.324 -
   1.325 -  if( pH==0 || pH->ht==0 ) return 0;
   1.326 -  xHash = hashFunction(pH->keyClass);
   1.327 -  assert( xHash!=0 );
   1.328 -  h = (*xHash)(pKey,nKey);
   1.329 -  assert( (pH->htsize & (pH->htsize-1))==0 );
   1.330 -  elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1));
   1.331 -  return elem;
   1.332 -}
   1.333 -
   1.334 -/* Attempt to locate an element of the hash table pH with a key
   1.335 -** that matches pKey,nKey.  Return the data for this element if it is
   1.336 -** found, or NULL if there is no match.
   1.337 -*/
   1.338 -void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
   1.339 -  HashElem *elem;    /* The element that matches key */
   1.340 -  elem = sqlite3HashFindElem(pH, pKey, nKey);
   1.341 -  return elem ? elem->data : 0;
   1.342 -}
   1.343 -
   1.344 -/* Insert an element into the hash table pH.  The key is pKey,nKey
   1.345 -** and the data is "data".
   1.346 -**
   1.347 -** If no element exists with a matching key, then a new
   1.348 -** element is created.  A copy of the key is made if the copyKey
   1.349 -** flag is set.  NULL is returned.
   1.350 -**
   1.351 -** If another element already exists with the same key, then the
   1.352 -** new data replaces the old data and the old data is returned.
   1.353 -** The key is not copied in this instance.  If a malloc fails, then
   1.354 -** the new data is returned and the hash table is unchanged.
   1.355 -**
   1.356 -** If the "data" parameter to this function is NULL, then the
   1.357 -** element corresponding to "key" is removed from the hash table.
   1.358 -*/
   1.359 -void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
   1.360 -  int hraw;             /* Raw hash value of the key */
   1.361 -  int h;                /* the hash of the key modulo hash table size */
   1.362 -  HashElem *elem;       /* Used to loop thru the element list */
   1.363 -  HashElem *new_elem;   /* New element added to the pH */
   1.364 -  int (*xHash)(const void*,int);  /* The hash function */
   1.365 -
   1.366 -  assert( pH!=0 );
   1.367 -  xHash = hashFunction(pH->keyClass);
   1.368 -  assert( xHash!=0 );
   1.369 -  hraw = (*xHash)(pKey, nKey);
   1.370 -  assert( (pH->htsize & (pH->htsize-1))==0 );
   1.371 -  h = hraw & (pH->htsize-1);
   1.372 -  elem = findElementGivenHash(pH,pKey,nKey,h);
   1.373 -  if( elem ){
   1.374 -    void *old_data = elem->data;
   1.375 -    if( data==0 ){
   1.376 -      removeElementGivenHash(pH,elem,h);
   1.377 -    }else{
   1.378 -      elem->data = data;
   1.379 -      if( !pH->copyKey ){
   1.380 -        elem->pKey = (void *)pKey;
   1.381 -      }
   1.382 -      assert(nKey==elem->nKey);
   1.383 -    }
   1.384 -    return old_data;
   1.385 -  }
   1.386 -  if( data==0 ) return 0;
   1.387 -  new_elem = (HashElem*)sqlite3_malloc( sizeof(HashElem) );
   1.388 -  if( new_elem==0 ) return data;
   1.389 -  if( pH->copyKey && pKey!=0 ){
   1.390 -    new_elem->pKey = sqlite3_malloc( nKey );
   1.391 -    if( new_elem->pKey==0 ){
   1.392 -      sqlite3_free(new_elem);
   1.393 -      return data;
   1.394 -    }
   1.395 -    memcpy((void*)new_elem->pKey, pKey, nKey);
   1.396 -  }else{
   1.397 -    new_elem->pKey = (void*)pKey;
   1.398 -  }
   1.399 -  new_elem->nKey = nKey;
   1.400 -  pH->count++;
   1.401 -  if( pH->htsize==0 ){
   1.402 -    rehash(pH,8);
   1.403 -    if( pH->htsize==0 ){
   1.404 -      pH->count = 0;
   1.405 -      if( pH->copyKey ){
   1.406 -        sqlite3_free(new_elem->pKey);
   1.407 -      }
   1.408 -      sqlite3_free(new_elem);
   1.409 -      return data;
   1.410 -    }
   1.411 -  }
   1.412 -  if( pH->count > pH->htsize ){
   1.413 -    rehash(pH,pH->htsize*2);
   1.414 -  }
   1.415 -  assert( pH->htsize>0 );
   1.416 -  assert( (pH->htsize & (pH->htsize-1))==0 );
   1.417 -  h = hraw & (pH->htsize-1);
   1.418 -  insertElement(pH, &pH->ht[h], new_elem);
   1.419 -  new_elem->data = data;
   1.420 -  return 0;
   1.421 -}