| Index: third_party/sqlite/src/src/hash.c
|
| diff --git a/third_party/sqlite/src/src/hash.c b/third_party/sqlite/src/src/hash.c
|
| index d4daf92a6ff30625cdbfca484dc84d755d6de6e9..b5886e064152b8face140874a447ec596c11832d 100644
|
| --- a/third_party/sqlite/src/src/hash.c
|
| +++ b/third_party/sqlite/src/src/hash.c
|
| @@ -52,12 +52,11 @@ void sqlite3HashClear(Hash *pH){
|
| /*
|
| ** The hashing function.
|
| */
|
| -static unsigned int strHash(const char *z, int nKey){
|
| - int h = 0;
|
| - assert( nKey>=0 );
|
| - while( nKey > 0 ){
|
| - h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
|
| - nKey--;
|
| +static unsigned int strHash(const char *z){
|
| + unsigned int h = 0;
|
| + unsigned char c;
|
| + while( (c = (unsigned char)*z++)!=0 ){
|
| + h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
|
| }
|
| return h;
|
| }
|
| @@ -113,7 +112,11 @@ static int rehash(Hash *pH, unsigned int new_size){
|
|
|
| /* The inability to allocates space for a larger hash table is
|
| ** a performance hit but it is not a fatal error. So mark the
|
| - ** allocation as a benign.
|
| + ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of
|
| + ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero()
|
| + ** only zeroes the requested number of bytes whereas this module will
|
| + ** use the actual amount of space allocated for the hash table (which
|
| + ** may be larger than the requested amount).
|
| */
|
| sqlite3BeginBenignMalloc();
|
| new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
|
| @@ -125,7 +128,7 @@ static int rehash(Hash *pH, unsigned int new_size){
|
| pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
|
| memset(new_ht, 0, new_size*sizeof(struct _ht));
|
| for(elem=pH->first, pH->first=0; elem; elem = next_elem){
|
| - unsigned int h = strHash(elem->pKey, elem->nKey) % new_size;
|
| + unsigned int h = strHash(elem->pKey) % new_size;
|
| next_elem = elem->next;
|
| insertElement(pH, &new_ht[h], elem);
|
| }
|
| @@ -133,28 +136,33 @@ static int rehash(Hash *pH, unsigned int new_size){
|
| }
|
|
|
| /* This function (for internal use only) locates an element in an
|
| -** hash table that matches the given key. The hash for this key has
|
| -** already been computed and is passed as the 4th parameter.
|
| +** hash table that matches the given key. The hash for this key is
|
| +** also computed and returned in the *pH parameter.
|
| */
|
| -static HashElem *findElementGivenHash(
|
| +static HashElem *findElementWithHash(
|
| const Hash *pH, /* The pH to be searched */
|
| const char *pKey, /* The key we are searching for */
|
| - int nKey, /* Bytes in key (not counting zero terminator) */
|
| - unsigned int h /* The hash for this key. */
|
| + unsigned int *pHash /* Write the hash value here */
|
| ){
|
| HashElem *elem; /* Used to loop thru the element list */
|
| int count; /* Number of elements left to test */
|
| + unsigned int h; /* The computed hash */
|
|
|
| if( pH->ht ){
|
| - struct _ht *pEntry = &pH->ht[h];
|
| + struct _ht *pEntry;
|
| + h = strHash(pKey) % pH->htsize;
|
| + pEntry = &pH->ht[h];
|
| elem = pEntry->chain;
|
| count = pEntry->count;
|
| }else{
|
| + h = 0;
|
| elem = pH->first;
|
| count = pH->count;
|
| }
|
| - while( count-- && ALWAYS(elem) ){
|
| - if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
|
| + *pHash = h;
|
| + while( count-- ){
|
| + assert( elem!=0 );
|
| + if( sqlite3StrICmp(elem->pKey,pKey)==0 ){
|
| return elem;
|
| }
|
| elem = elem->next;
|
| @@ -189,7 +197,7 @@ static void removeElementGivenHash(
|
| }
|
| sqlite3_free( elem );
|
| pH->count--;
|
| - if( pH->count<=0 ){
|
| + if( pH->count==0 ){
|
| assert( pH->first==0 );
|
| assert( pH->count==0 );
|
| sqlite3HashClear(pH);
|
| @@ -197,26 +205,20 @@ static void removeElementGivenHash(
|
| }
|
|
|
| /* Attempt to locate an element of the hash table pH with a key
|
| -** that matches pKey,nKey. Return the data for this element if it is
|
| +** that matches pKey. Return the data for this element if it is
|
| ** found, or NULL if there is no match.
|
| */
|
| -void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){
|
| +void *sqlite3HashFind(const Hash *pH, const char *pKey){
|
| HashElem *elem; /* The element that matches key */
|
| unsigned int h; /* A hash on key */
|
|
|
| assert( pH!=0 );
|
| assert( pKey!=0 );
|
| - assert( nKey>=0 );
|
| - if( pH->ht ){
|
| - h = strHash(pKey, nKey) % pH->htsize;
|
| - }else{
|
| - h = 0;
|
| - }
|
| - elem = findElementGivenHash(pH, pKey, nKey, h);
|
| + elem = findElementWithHash(pH, pKey, &h);
|
| return elem ? elem->data : 0;
|
| }
|
|
|
| -/* Insert an element into the hash table pH. The key is pKey,nKey
|
| +/* Insert an element into the hash table pH. The key is pKey
|
| ** and the data is "data".
|
| **
|
| ** If no element exists with a matching key, then a new
|
| @@ -230,20 +232,14 @@ void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){
|
| ** If the "data" parameter to this function is NULL, then the
|
| ** element corresponding to "key" is removed from the hash table.
|
| */
|
| -void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){
|
| +void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
|
| unsigned int h; /* the hash of the key modulo hash table size */
|
| HashElem *elem; /* Used to loop thru the element list */
|
| HashElem *new_elem; /* New element added to the pH */
|
|
|
| assert( pH!=0 );
|
| assert( pKey!=0 );
|
| - assert( nKey>=0 );
|
| - if( pH->htsize ){
|
| - h = strHash(pKey, nKey) % pH->htsize;
|
| - }else{
|
| - h = 0;
|
| - }
|
| - elem = findElementGivenHash(pH,pKey,nKey,h);
|
| + elem = findElementWithHash(pH,pKey,&h);
|
| if( elem ){
|
| void *old_data = elem->data;
|
| if( data==0 ){
|
| @@ -251,7 +247,6 @@ void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){
|
| }else{
|
| elem->data = data;
|
| elem->pKey = pKey;
|
| - assert(nKey==elem->nKey);
|
| }
|
| return old_data;
|
| }
|
| @@ -259,19 +254,14 @@ void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){
|
| new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
|
| if( new_elem==0 ) return data;
|
| new_elem->pKey = pKey;
|
| - new_elem->nKey = nKey;
|
| new_elem->data = data;
|
| pH->count++;
|
| if( pH->count>=10 && pH->count > 2*pH->htsize ){
|
| if( rehash(pH, pH->count*2) ){
|
| assert( pH->htsize>0 );
|
| - h = strHash(pKey, nKey) % pH->htsize;
|
| + h = strHash(pKey) % pH->htsize;
|
| }
|
| }
|
| - if( pH->ht ){
|
| - insertElement(pH, &pH->ht[h], new_elem);
|
| - }else{
|
| - insertElement(pH, 0, new_elem);
|
| - }
|
| + insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem);
|
| return 0;
|
| }
|
|
|