1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-03 16:53:36 +03:00

Reference count the KeyInfo object. Cache a copy of an appropriate KeyInfo

for each index in the Index object, and reuse that one copy as much as possible.

FossilOrigin-Name: defd5205a7cc3543cdd18f906f568e943b8b3a2c
This commit is contained in:
drh
2013-11-06 19:59:23 +00:00
parent 93889d9335
commit 2ec2fb2269
16 changed files with 175 additions and 161 deletions

View File

@@ -637,12 +637,14 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
case P4_KEYINFO:
case P4_INTARRAY:
case P4_KEYINFO_HANDOFF: {
case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
}
case P4_KEYINFO: {
if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
break;
}
case P4_MPRINTF: {
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break;
@@ -721,14 +723,6 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
** the string is made into memory obtained from sqlite3_malloc().
** A value of n==0 means copy bytes of zP4 up to and including the
** first null byte. If n>0 then copy n+1 bytes of zP4.
**
** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
** A copy is made of the KeyInfo structure into memory obtained from
** sqlite3_malloc, to be freed when the Vdbe is finalized.
** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
** stored in memory that the caller has obtained from sqlite3_malloc. The
** caller should not free the allocation, it will be freed when the Vdbe is
** finalized.
**
** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
** to a string or structure that is guaranteed to exist for the lifetime of
@@ -743,7 +737,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
db = p->db;
assert( p->magic==VDBE_MAGIC_INIT );
if( p->aOp==0 || db->mallocFailed ){
if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
if( n!=P4_VTAB ){
freeP4(db, n, (void*)*(char**)&zP4);
}
return;
@@ -766,21 +760,6 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
pOp->p4.p = 0;
pOp->p4type = P4_NOTUSED;
}else if( n==P4_KEYINFO ){
KeyInfo *pOrig, *pNew;
pOrig = (KeyInfo*)zP4;
pNew = sqlite3KeyInfoAlloc(db, pOrig->nField, pOrig->nXField);
pOp->p4.pKeyInfo = pNew;
if( pNew ){
int n = pOrig->nField+pOrig->nXField;
memcpy(pNew->aColl, pOrig->aColl, n*sizeof(pNew->aColl[0]));
memcpy(pNew->aSortOrder, pOrig->aSortOrder, n);
pOp->p4type = P4_KEYINFO;
}else{
p->db->mallocFailed = 1;
pOp->p4type = P4_NOTUSED;
}
}else if( n==P4_KEYINFO_HANDOFF ){
pOp->p4.p = (void*)zP4;
pOp->p4type = P4_KEYINFO;
}else if( n==P4_VTAB ){
@@ -798,6 +777,18 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
}
}
/*
** Set the P4 on the most recently added opcode to the KeyInfo for the
** index given.
*/
void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
assert( pIdx!=0 );
sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx),
P4_KEYINFO);
}
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
** Change the comment on the most recently coded instruction. Or
@@ -958,7 +949,6 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
char *zP4 = zTemp;
assert( nTemp>=20 );
switch( pOp->p4type ){
case P4_KEYINFO_STATIC:
case P4_KEYINFO: {
int i, j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;