1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Simplify the symbol hash table to use only a single key class. Other

changes to improve code coverage. (CVS 5794)

FossilOrigin-Name: ff50a8a7e5a15fac192939ff3206fa18d1c5a6dd
This commit is contained in:
drh
2008-10-10 17:41:28 +00:00
parent adfae6c68b
commit 1b67f3caf2
9 changed files with 66 additions and 195 deletions

View File

@@ -1,5 +1,5 @@
C Documentation\supdates.\s\sNo\schanges\sto\scode.\s(CVS\s5793)
D 2008-10-10T17:26:35
C Simplify\sthe\ssymbol\shash\stable\sto\suse\sonly\sa\ssingle\skey\sclass.\s\sOther\nchanges\sto\simprove\scode\scoverage.\s(CVS\s5794)
D 2008-10-10T17:41:29
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 7fc26e087207e7a4a7723583dbd7997477af3b13
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -103,7 +103,7 @@ F src/btree.c 3e686f899659df8d79f2587d0f34f51fdf6a6276
F src/btree.h 903682f2a88da37435f103da00cb915d63bc8015
F src/btreeInt.h e38e9b2b285f40f5bc0a6664f630d4a141622f16
F src/build.c 8714bd809583bbe07bf22d0e1808a3fc31abe330
F src/callback.c 7a40fd44da3eb89e7f6eff30aa6f940c45d73a97
F src/callback.c e970e5beddbdb23f89a6d05cb1a6419d9f755624
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
F src/date.c 1b1fc801df40aae891bff8b03f65313df192d677
F src/delete.c f72c98c5770c94f1a8b7bbdf7aeb49503a4927a4
@@ -111,14 +111,14 @@ F src/expr.c 0ceafeff3a4e0f460d6a7695a675ae12391e313d
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/func.c 8431b40a7843d1024145684d303c55b4ee087bbe
F src/global.c 20a3fe46c8287a01ba3a7442558f0eb70c66b19a
F src/hash.c eb64e48f3781100e5934f759fbe72a63a8fe78cb
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
F src/hash.c 582c00618efe2051785e66ba1b6430d5a129de3f
F src/hash.h 28f38ebb1006a5beedcb013bcdfe31befe7437ae
F src/hwtime.h 4a1d45f4cae1f402ea19686acf24acf4f0cb53cb
F src/insert.c 110cca7845ed5a66c08fdd413b02e706ae34455f
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
F src/legacy.c aac57bd984e666059011ea01ec4383892a253be3
F src/loadext.c cadd5df14bcda5ef0c26d815eb609a755861923e
F src/main.c fccd1a32306147aa751d4aaacec8fecfe4a34d1c
F src/main.c 6bdb35b22f061e076ffc98fa0df667b350236b0d
F src/malloc.c 31f4ca218f4b664dce45ef9c4f1fcd2929c67a42
F src/mem1.c 5a529ff121c55ab067be14de00f86f6dcc4f4fb9
F src/mem2.c f87e681d0d1ed8436870d089332ed0d27d885b5c
@@ -174,7 +174,7 @@ F src/test_devsym.c 802d10e65b4217208cb47059b84adf46318bcdf4
F src/test_func.c a55c4d5479ff2eb5c0a22d4d88e9528ab59c953b
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
F src/test_loadext.c 97dc8800e46a46ed002c2968572656f37e9c0dd9
F src/test_malloc.c 49abbf5d9c71fb06cf7a7cf96f9b9a799b77a421
F src/test_malloc.c c4e5e3ea12c81b67e7b5473a06e900bc9881e722
F src/test_md5.c 28209a4e2068711b5443c33104fe41f21d160071
F src/test_mutex.c d3422d9f60cc1330249d102e74b333f0d24a0cb6
F src/test_onefile.c 243157b10275251c5dc2d6619aee2ff9ae22379c
@@ -406,7 +406,7 @@ F test/lock2.test 018b846f6f3b3b695fad07e317b7988442b556f4
F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
F test/lock4.test 09d97d52cae18fadfe631552af9880dac6b3ae90
F test/lock5.test 904c20aec51d5dbff0a3aec6a4d35c5ae0257449
F test/lookaside.test 28f730199350f3912c122c23bab2f01910530c84
F test/lookaside.test 4a6a3336ef4259b0003d582330a901bc8d8d367a
F test/main.test 187a9a1b5248ed74a83838c581c15ec6023b555b
F test/malloc.test 2fa351108503f0da80e9183a8157fbd943c5d533
F test/malloc3.test 094f8195fe8e409bd4da0f1d769f7745faec62c8
@@ -457,7 +457,7 @@ F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a
F test/pagesize.test 0d9ff3fedfce6e5ffe8fa7aca9b6d3433a2e843b
F test/pcache.test 515b4c26e9f57660357dfff5b6b697acac1abc5f
F test/pcache2.test 2b4fa1bee5cfc338d8c04eb6ed7eaf41f478bf7c
F test/permutations.test ae19b5e644425d850e288b78d6f02c257c780fea
F test/permutations.test 2635ee42d1112ab7bfa0ec1da2b56afa256afed4
F test/pragma.test c86359a8e0b28abdcc0ff4936f7966c446d0479a
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 262a5acd3158f788e9bdf7f18d718f3af32ff6ef
@@ -645,7 +645,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 3de179630e812396ec29e77f7a06758472d0802f
R 469bda2a774246df2b2a212f34becf13
P 07b5f70317a0b2d32df86a01bdeec79ead00f68c
R 3bc893b2b397067aee1a13ef81efd34f
U drh
Z 4f5f403cd825b04b1721f4c2665a843f
Z b557b4a188b730c763fde4b73f663a4a

View File

@@ -1 +1 @@
07b5f70317a0b2d32df86a01bdeec79ead00f68c
ff50a8a7e5a15fac192939ff3206fa18d1c5a6dd

View File

@@ -13,7 +13,7 @@
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.31 2008/09/09 12:31:34 drh Exp $
** $Id: callback.c,v 1.32 2008/10/10 17:41:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -410,14 +410,14 @@ void sqlite3SchemaFree(void *p){
temp1 = pSchema->tblHash;
temp2 = pSchema->trigHash;
sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&pSchema->trigHash, 0);
sqlite3HashClear(&pSchema->aFKey);
sqlite3HashClear(&pSchema->idxHash);
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
}
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&pSchema->tblHash, 0);
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
Table *pTab = sqliteHashData(pElem);
sqlite3DeleteTable(pTab);
@@ -441,10 +441,10 @@ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
if( !p ){
db->mallocFailed = 1;
}else if ( 0==p->file_format ){
sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1);
sqlite3HashInit(&p->tblHash, 0);
sqlite3HashInit(&p->idxHash, 0);
sqlite3HashInit(&p->trigHash, 0);
sqlite3HashInit(&p->aFKey, 1);
p->enc = SQLITE_UTF8;
}
return p;

View File

@@ -12,7 +12,7 @@
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.30 2008/06/20 14:59:51 danielk1977 Exp $
** $Id: hash.c,v 1.31 2008/10/10 17:41:29 drh Exp $
*/
#include "sqliteInt.h"
#include <assert.h>
@@ -21,22 +21,12 @@
** fields of the Hash structure.
**
** "pNew" is a pointer to the hash table that is to be initialized.
** keyClass is one of the constants SQLITE_HASH_INT, SQLITE_HASH_POINTER,
** SQLITE_HASH_BINARY, or SQLITE_HASH_STRING. The value of keyClass
** determines what kind of key the hash table will use. "copyKey" is
** true if the hash table should make its own private copy of keys and
** false if it should just use the supplied pointer. CopyKey only makes
** sense for SQLITE_HASH_STRING and SQLITE_HASH_BINARY and is ignored
** for other key classes.
** "copyKey" is true if the hash table should make its own private
** copy of keys and false if it should just use the supplied pointer.
*/
void sqlite3HashInit(Hash *pNew, int keyClass, int copyKey){
void sqlite3HashInit(Hash *pNew, int copyKey){
assert( pNew!=0 );
assert( keyClass>=SQLITE_HASH_STRING && keyClass<=SQLITE_HASH_BINARY );
pNew->keyClass = keyClass;
#if 0
if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0;
#endif
pNew->copyKey = copyKey;
pNew->copyKey = copyKey!=0;
pNew->first = 0;
pNew->count = 0;
pNew->htsize = 0;
@@ -67,33 +57,6 @@ void sqlite3HashClear(Hash *pH){
pH->count = 0;
}
#if 0 /* NOT USED */
/*
** Hash and comparison functions when the mode is SQLITE_HASH_INT
*/
static int intHash(const void *pKey, int nKey){
return nKey ^ (nKey<<8) ^ (nKey>>8);
}
static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
return n2 - n1;
}
#endif
#if 0 /* NOT USED */
/*
** Hash and comparison functions when the mode is SQLITE_HASH_POINTER
*/
static int ptrHash(const void *pKey, int nKey){
uptr x = Addr(pKey);
return x ^ (x<<8) ^ (x>>8);
}
static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
if( pKey1==pKey2 ) return 0;
if( pKey1<pKey2 ) return -1;
return 1;
}
#endif
/*
** Hash and comparison functions when the mode is SQLITE_HASH_STRING
*/
@@ -112,79 +75,6 @@ static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
return sqlite3StrNICmp((const char*)pKey1,(const char*)pKey2,n1);
}
/*
** Hash and comparison functions when the mode is SQLITE_HASH_BINARY
*/
static int binHash(const void *pKey, int nKey){
int h = 0;
const char *z = (const char *)pKey;
while( nKey-- > 0 ){
h = (h<<3) ^ h ^ *(z++);
}
return h & 0x7fffffff;
}
static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
if( n1!=n2 ) return 1;
return memcmp(pKey1,pKey2,n1);
}
/*
** Return a pointer to the appropriate hash function given the key class.
**
** The C syntax in this function definition may be unfamilar to some
** programmers, so we provide the following additional explanation:
**
** The name of the function is "hashFunction". The function takes a
** single parameter "keyClass". The return value of hashFunction()
** is a pointer to another function. Specifically, the return value
** of hashFunction() is a pointer to a function that takes two parameters
** 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;
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
}
/*
** Return a pointer to the appropriate hash function given the key class.
**
** For help in interpreted the obscure C code in the function definition,
** 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;
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
*/
@@ -219,7 +109,6 @@ static void insertElement(
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 */
int (*xHash)(const void*,int); /* The hash function */
#ifdef SQLITE_MALLOC_SOFT_LIMIT
if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){
@@ -241,9 +130,8 @@ static void rehash(Hash *pH, int new_size){
sqlite3_free(pH->ht);
pH->ht = new_ht;
pH->htsize = new_size;
xHash = hashFunction(pH->keyClass);
for(elem=pH->first, pH->first=0; elem; elem = next_elem){
int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
int h = strHash(elem->pKey, elem->nKey) & (new_size-1);
next_elem = elem->next;
insertElement(pH, &new_ht[h], elem);
}
@@ -261,15 +149,13 @@ static HashElem *findElementGivenHash(
){
HashElem *elem; /* Used to loop thru the element list */
int count; /* Number of elements left to test */
int (*xCompare)(const void*,int,const void*,int); /* comparison function */
if( pH->ht ){
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 ){
if( strCompare(elem->pKey,elem->nKey,pKey,nKey)==0 ){
return elem;
}
elem = elem->next;
@@ -323,12 +209,9 @@ static void removeElementGivenHash(
HashElem *sqlite3HashFindElem(const Hash *pH, const void *pKey, int nKey){
int h; /* A hash on key */
HashElem *elem; /* The element that matches key */
int (*xHash)(const void*,int); /* The hash function */
if( pH==0 || pH->ht==0 ) return 0;
xHash = hashFunction(pH->keyClass);
assert( xHash!=0 );
h = (*xHash)(pKey,nKey);
h = strHash(pKey,nKey);
elem = findElementGivenHash(pH,pKey,nKey, h % pH->htsize);
return elem;
}
@@ -363,12 +246,9 @@ void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
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 */
int (*xHash)(const void*,int); /* The hash function */
assert( pH!=0 );
xHash = hashFunction(pH->keyClass);
assert( xHash!=0 );
hraw = (*xHash)(pKey, nKey);
hraw = strHash(pKey, nKey);
if( pH->htsize ){
h = hraw % pH->htsize;
elem = findElementGivenHash(pH,pKey,nKey,h);

View File

@@ -12,7 +12,7 @@
** This is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.11 2007/09/04 14:31:47 danielk1977 Exp $
** $Id: hash.h,v 1.12 2008/10/10 17:41:29 drh Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_
@@ -30,10 +30,9 @@ typedef struct HashElem HashElem;
** this structure opaque.
*/
struct Hash {
char keyClass; /* SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */
char copyKey; /* True if copy of key made on insert */
int count; /* Number of entries in this table */
int htsize; /* Number of buckets in the hash table */
unsigned int copyKey: 1; /* True if copy of key made on insert */
unsigned int htsize : 31; /* Number of buckets in the hash table */
unsigned int count; /* Number of entries in this table */
HashElem *first; /* The first element of the array */
struct _ht { /* the hash table */
int count; /* Number of entries with this hash */
@@ -53,32 +52,10 @@ struct HashElem {
void *pKey; int nKey; /* Key associated with this element */
};
/*
** There are 4 different modes of operation for a hash table:
**
** SQLITE_HASH_INT nKey is used as the key and pKey is ignored.
**
** SQLITE_HASH_POINTER pKey is used as the key and nKey is ignored.
**
** SQLITE_HASH_STRING pKey points to a string that is nKey bytes long
** (including the null-terminator, if any). Case
** is ignored in comparisons.
**
** SQLITE_HASH_BINARY pKey points to binary data nKey bytes long.
** memcmp() is used to compare keys.
**
** A copy of the key is made for SQLITE_HASH_STRING and SQLITE_HASH_BINARY
** if the copyKey parameter to HashInit is 1.
*/
/* #define SQLITE_HASH_INT 1 // NOT USED */
/* #define SQLITE_HASH_POINTER 2 // NOT USED */
#define SQLITE_HASH_STRING 3
#define SQLITE_HASH_BINARY 4
/*
** Access routines. To delete, insert a NULL pointer.
*/
void sqlite3HashInit(Hash*, int keytype, int copyKey);
void sqlite3HashInit(Hash*, int copyKey);
void *sqlite3HashInsert(Hash*, const void *pKey, int nKey, void *pData);
void *sqlite3HashFind(const Hash*, const void *pKey, int nKey);
HashElem *sqlite3HashFindElem(const Hash*, const void *pKey, int nKey);

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.504 2008/10/07 19:53:14 drh Exp $
** $Id: main.c,v 1.505 2008/10/10 17:41:29 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -216,12 +216,10 @@ int sqlite3_shutdown(void){
if( sqlite3GlobalConfig.isInit ){
sqlite3_os_end();
}
if( sqlite3GlobalConfig.m.xShutdown ){
assert( sqlite3GlobalConfig.m.xShutdown!=0 );
sqlite3MallocEnd();
}
if( sqlite3GlobalConfig.mutex.xMutexEnd ){
assert( sqlite3GlobalConfig.mutex.xMutexEnd!=0 );
sqlite3MutexEnd();
}
sqlite3GlobalConfig.isInit = 0;
return SQLITE_OK;
}
@@ -1500,9 +1498,9 @@ static int openDatabase(
| SQLITE_LoadExtension
#endif
;
sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&db->aCollSeq, 0);
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3HashInit(&db->aModule, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&db->aModule, 0);
#endif
db->pVfs = sqlite3_vfs_find(zVfs);
@@ -1627,7 +1625,8 @@ static int openDatabase(
#endif
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside);
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
opendb_out:
if( db ){

View File

@@ -13,7 +13,7 @@
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.47 2008/08/05 17:53:24 drh Exp $
** $Id: test_malloc.c,v 1.48 2008/10/10 17:41:29 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -204,7 +204,16 @@ static int faultsimInstall(int install){
faultsimBeginBenign, faultsimEndBenign
);
}else{
sqlite3_mem_methods m;
assert(memfault.m.xMalloc);
/* One should be able to reset the default memory allocator by storing
** a zeroed allocator then calling GETMALLOC. */
memset(&m, 0, sizeof(m));
sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m);
assert( memcmp(&m, &memfault.m, sizeof(m))==0 );
rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);
}

View File

@@ -11,7 +11,7 @@
#
# Tests for the lookaside memory allocator.
#
# $Id: lookaside.test,v 1.6 2008/09/30 00:31:38 drh Exp $
# $Id: lookaside.test,v 1.7 2008/10/10 17:41:29 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -77,6 +77,12 @@ do_test lookaside-2.4 {
db cache flush
sqlite3_db_config_lookaside db 0 50 50
} {0} ;# SQLITE_OK
do_test lookaside-2.5 {
sqlite3_db_config_lookaside db 0 -1 50
} {0} ;# SQLITE_OK
do_test lookaside-2.6 {
sqlite3_db_config_lookaside db 0 50 -1
} {0} ;# SQLITE_OK
# sqlite3_db_status() with an invalid verb returns an error.
#

View File

@@ -9,7 +9,7 @@
#
#***********************************************************************
#
# $Id: permutations.test,v 1.33 2008/10/07 15:00:09 danielk1977 Exp $
# $Id: permutations.test,v 1.34 2008/10/10 17:41:30 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -39,7 +39,7 @@ if {$::perm::testmode eq "all" || $::perm::testmode eq ""} {
set ::perm::testmode {
memsubsys1 memsubsys2 singlethread multithread onefile utf16 exclusive
persistent_journal persistent_journal_error no_journal no_journal_error
autovacuum_ioerr no_mutex_try
autovacuum_ioerr no_mutex_try fullmutex
}
}
if {$::perm::testmode eq "targets"} {