-C Enhance\slemon\sso\sthat\sa\s@X\sinstead\sof\sjust\sX\sin\sthe\scode\sexpands\sto\sthe\nmajor\stoken\svalue\srather\sthan\sthe\sminor\stoken\svalue.\s\sUse\sthis\sto\smake\nthe\sparser\sa\sfew\shundred\sbytes\ssmaller.\s(CVS\s1895)
-D 2004-08-19T15:12:26
+C Optimizations\sin\sthe\shash\stable\smodule.\s(CVS\s1896)
+D 2004-08-20T14:08:51
F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
F src/expr.c f11a1e5c489bc8f5cc83b10aa80f21e85f48141e
F src/func.c 7e2eeebe219aa612ce7a04c74ae6d57379c6656b
-F src/hash.c f0a2f22c2a7052d67053b5f4690ea3010bb3fb9f
-F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
+F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
+F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c bedcba371401395033a1a1c578d8fdc3fec87bec
F src/legacy.c 2f3617c61bcdcd1d776154a9cfebf99facda8ad8
F src/main.c a779422c5402df92c390e233ac32ab718fc4436b
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 25fe7a42ec2e06e659d7a0a6664789114c007e17
-R 0379dd9278368974892dd5434039fab5
+P 28215096e0748b5b02776ddb4c964e0161bc0f16
+R 5607576f6316ac80134bcd33d2f77b9e
U drh
-Z ddb5c020240eaf2ea91499a31fc16aa6
+Z d2ae7348c29545bbd90048ea25e77c25
** This is the implementation of generic hash-tables
** used in SQLite.
**
-** $Id: hash.c,v 1.14 2004/06/30 22:43:22 drh Exp $
+** $Id: hash.c,v 1.15 2004/08/20 14:08:51 drh Exp $
*/
#include "sqliteInt.h"
#include <assert.h>
*/
void sqlite3HashInit(Hash *pNew, int keyClass, int copyKey){
assert( pNew!=0 );
- assert( keyClass>=SQLITE_HASH_INT && keyClass<=SQLITE_HASH_BINARY );
+ assert( keyClass>=SQLITE_HASH_STRING && keyClass<=SQLITE_HASH_BINARY );
pNew->keyClass = keyClass;
- pNew->copyKey = copyKey &&
- (keyClass==SQLITE_HASH_STRING || keyClass==SQLITE_HASH_BINARY);
+#if 0
+ if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0;
+#endif
+ pNew->copyKey = copyKey;
pNew->first = 0;
pNew->count = 0;
pNew->htsize = 0;
return sqlite3HashNoCase((const char*)pKey, nKey);
}
static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- if( n1!=n2 ) return n2-n1;
+ if( n1!=n2 ) return 1;
return sqlite3StrNICmp((const char*)pKey1,(const char*)pKey2,n1);
}
return h & 0x7fffffff;
}
static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- if( n1!=n2 ) return n2-n1;
+ if( n1!=n2 ) return 1;
return memcmp(pKey1,pKey2,n1);
}
** with types "const void*" and "int" and returns an "int".
*/
static int (*hashFunction(int keyClass))(const void*,int){
+#if 0 /* HASH_INT and HASH_POINTER are never used */
switch( keyClass ){
- /* case SQLITE_HASH_INT: return &intHash; // NOT USED */
- /* case SQLITE_HASH_POINTER: return &ptrHash; // NOT USED */
+ case SQLITE_HASH_INT: return &intHash;
+ case SQLITE_HASH_POINTER: return &ptrHash;
case SQLITE_HASH_STRING: return &strHash;
case SQLITE_HASH_BINARY: return &binHash;;
default: break;
}
return 0;
+#else
+ if( keyClass==SQLITE_HASH_STRING ){
+ return &strHash;
+ }else{
+ assert( keyClass==SQLITE_HASH_BINARY );
+ return &binHash;
+ }
+#endif
}
/*
** see the header comment on the previous function.
*/
static int (*compareFunction(int keyClass))(const void*,int,const void*,int){
+#if 0 /* HASH_INT and HASH_POINTER are never used */
switch( keyClass ){
- /* case SQLITE_HASH_INT: return &intCompare; // NOT USED */
- /* case SQLITE_HASH_POINTER: return &ptrCompare; // NOT USED */
+ case SQLITE_HASH_INT: return &intCompare;
+ case SQLITE_HASH_POINTER: return &ptrCompare;
case SQLITE_HASH_STRING: return &strCompare;
case SQLITE_HASH_BINARY: return &binCompare;
default: break;
}
return 0;
+#else
+ if( keyClass==SQLITE_HASH_STRING ){
+ return &strCompare;
+ }else{
+ assert( keyClass==SQLITE_HASH_BINARY );
+ return &binCompare;
+ }
+#endif
+}
+
+/* Link an element into the hash table
+*/
+static void insertElement(
+ Hash *pH, /* The complete hash table */
+ struct _ht *pEntry, /* The entry into which pNew is inserted */
+ HashElem *pNew /* The element to be inserted */
+){
+ HashElem *pHead; /* First element already in pEntry */
+ pHead = pEntry->chain;
+ if( pHead ){
+ pNew->next = pHead;
+ pNew->prev = pHead->prev;
+ if( pHead->prev ){ pHead->prev->next = pNew; }
+ else { pH->first = pNew; }
+ pHead->prev = pNew;
+ }else{
+ pNew->next = pH->first;
+ if( pH->first ){ pH->first->prev = pNew; }
+ pNew->prev = 0;
+ pH->first = pNew;
+ }
+ pEntry->count++;
+ pEntry->chain = pNew;
}
static void rehash(Hash *pH, int new_size){
struct _ht *new_ht; /* The new hash table */
HashElem *elem, *next_elem; /* For looping over existing elements */
- HashElem *x; /* Element being copied to new hash table */
int (*xHash)(const void*,int); /* The hash function */
assert( (new_size & (new_size-1))==0 );
for(elem=pH->first, pH->first=0; elem; elem = next_elem){
int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
next_elem = elem->next;
- x = new_ht[h].chain;
- if( x ){
- elem->next = x;
- elem->prev = x->prev;
- if( x->prev ) x->prev->next = elem;
- else pH->first = elem;
- x->prev = elem;
- }else{
- elem->next = pH->first;
- if( pH->first ) pH->first->prev = elem;
- elem->prev = 0;
- pH->first = elem;
- }
- new_ht[h].chain = elem;
- new_ht[h].count++;
+ insertElement(pH, &new_ht[h], elem);
}
}
int (*xCompare)(const void*,int,const void*,int); /* comparison function */
if( pH->ht ){
- elem = pH->ht[h].chain;
- count = pH->ht[h].count;
+ struct _ht *pEntry = &pH->ht[h];
+ elem = pEntry->chain;
+ count = pEntry->count;
xCompare = compareFunction(pH->keyClass);
while( count-- && elem ){
if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){
HashElem* elem, /* The element to be removed from the pH */
int h /* Hash value for the element */
){
+ struct _ht *pEntry;
if( elem->prev ){
elem->prev->next = elem->next;
}else{
if( elem->next ){
elem->next->prev = elem->prev;
}
- if( pH->ht[h].chain==elem ){
- pH->ht[h].chain = elem->next;
+ pEntry = &pH->ht[h];
+ if( pEntry->chain==elem ){
+ pEntry->chain = elem->next;
}
- pH->ht[h].count--;
- if( pH->ht[h].count<=0 ){
- pH->ht[h].chain = 0;
+ pEntry->count--;
+ if( pEntry->count<=0 ){
+ pEntry->chain = 0;
}
if( pH->copyKey && elem->pKey ){
sqliteFree(elem->pKey);
}
new_elem->nKey = nKey;
pH->count++;
- if( pH->htsize==0 ) rehash(pH,8);
if( pH->htsize==0 ){
- pH->count = 0;
- sqliteFree(new_elem);
- return data;
+ rehash(pH,8);
+ if( pH->htsize==0 ){
+ pH->count = 0;
+ sqliteFree(new_elem);
+ return data;
+ }
}
if( pH->count > pH->htsize ){
rehash(pH,pH->htsize*2);
}
+ assert( pH->htsize>0 );
assert( (pH->htsize & (pH->htsize-1))==0 );
h = hraw & (pH->htsize-1);
- elem = pH->ht[h].chain;
- if( elem ){
- new_elem->next = elem;
- new_elem->prev = elem->prev;
- if( elem->prev ){ elem->prev->next = new_elem; }
- else { pH->first = new_elem; }
- elem->prev = new_elem;
- }else{
- new_elem->next = pH->first;
- new_elem->prev = 0;
- if( pH->first ){ pH->first->prev = new_elem; }
- pH->first = new_elem;
- }
- pH->ht[h].count++;
- pH->ht[h].chain = new_elem;
+ insertElement(pH, &pH->ht[h], new_elem);
new_elem->data = data;
return 0;
}