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

Reduce the size of the VdbeCursor object from 144 to 120 bytes.

FossilOrigin-Name: 5f9d50688508affd0bc8e4d52e21dacfacdbb5ce
This commit is contained in:
drh
2013-11-20 21:51:33 +00:00
parent 380d685133
commit 14da87f8c5
5 changed files with 40 additions and 50 deletions

View File

@@ -1,5 +1,5 @@
C Improved\scomments\son\sthe\sOP_Column\schanges.\s\sOptimize\sout\sloading\sof\soverflow\npages\sfor\scontent\swith\szero\slength.\s\sAdd\stest\scases\sfor\sthe\slatter. C Reduce\sthe\ssize\sof\sthe\sVdbeCursor\sobject\sfrom\s144\sto\s120\sbytes.
D 2013-11-20T20:58:00.360 D 2013-11-20T21:51:33.976
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -280,12 +280,12 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 987f375b8ba5b5c3d0ded64191f72706221f76f9 F src/vdbe.c b55581dbd26eee6a03a7c673e9080db306fb8113
F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644
F src/vdbeInt.h fbae1c449049a1a26ebbdf44e1beb08344072b72 F src/vdbeInt.h fc6a1ca59e679cb27f55fd2bc7d91cfb963251dd
F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
F src/vdbeaux.c c592609996435944837b8906fbbcfcfac0714c90 F src/vdbeaux.c c592609996435944837b8906fbbcfcfac0714c90
F src/vdbeblob.c d883398f7260725147dbf5b40c2b61332aee47f9 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde
F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
@@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 0e3f5df695216a27602a53eed5d25231b055adc8 P 0e05679db7aa302a49e087a81f85203844b98cbe
R 7b4a6a3b4e08d369fabb1ea696a3ba02 R 25fcd0453526b0fb55425cafc8bedd31
U drh U drh
Z a02194f256e2495862011254263d6e91 Z 51316cd0cd8c72b5a20c8e69a256a48d

View File

@@ -1 +1 @@
0e05679db7aa302a49e087a81f85203844b98cbe 5f9d50688508affd0bc8e4d52e21dacfacdbb5ce

View File

@@ -228,7 +228,6 @@ static VdbeCursor *allocateCursor(
pCx->nField = nField; pCx->nField = nField;
if( nField ){ if( nField ){
pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))]; pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))];
pCx->aOffset = pCx->aType + nField;
} }
if( isBtreeCursor ){ if( isBtreeCursor ){
pCx->pCursor = (BtCursor*) pCx->pCursor = (BtCursor*)
@@ -2282,7 +2281,7 @@ case OP_Column: {
assert( pC!=0 ); assert( pC!=0 );
assert( p2<pC->nField ); assert( p2<pC->nField );
aType = pC->aType; aType = pC->aType;
aOffset = pC->aOffset; aOffset = aType + pC->nField;
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
#endif #endif
@@ -2313,7 +2312,7 @@ case OP_Column: {
} }
}else{ }else{
assert( pCrsr ); assert( pCrsr );
if( pC->isIndex ){ if( pC->isTable==0 ){
assert( sqlite3BtreeCursorIsValid(pCrsr) ); assert( sqlite3BtreeCursorIsValid(pCrsr) );
VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -2378,8 +2377,8 @@ case OP_Column: {
/* Make sure zData points to enough of the record to cover the header. */ /* Make sure zData points to enough of the record to cover the header. */
if( pC->aRow==0 ){ if( pC->aRow==0 ){
memset(&sMem, 0, sizeof(sMem)); memset(&sMem, 0, sizeof(sMem));
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, pC->aOffset[0], pC->isIndex, rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
&sMem); !pC->isTable, &sMem);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto op_column_error; goto op_column_error;
} }
@@ -2476,7 +2475,7 @@ case OP_Column: {
}else{ }else{
memset(&sMem, 0, sizeof(sMem)); memset(&sMem, 0, sizeof(sMem));
sqlite3VdbeMemMove(&sMem, pDest); sqlite3VdbeMemMove(&sMem, pDest);
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
&sMem); &sMem);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto op_column_error; goto op_column_error;
@@ -3273,12 +3272,11 @@ case OP_OpenWrite: {
** sqlite3BtreeCursor() may return is SQLITE_OK. */ ** sqlite3BtreeCursor() may return is SQLITE_OK. */
assert( rc==SQLITE_OK ); assert( rc==SQLITE_OK );
/* Set the VdbeCursor.isTable and isIndex variables. Previous versions of /* Set the VdbeCursor.isTable variable. Previous versions of
** SQLite used to check if the root-page flags were sane at this point ** SQLite used to check if the root-page flags were sane at this point
** and report database corruption if they were not, but this check has ** and report database corruption if they were not, but this check has
** since moved into the btree layer. */ ** since moved into the btree layer. */
pCur->isTable = pOp->p4type!=P4_KEYINFO; pCur->isTable = pOp->p4type!=P4_KEYINFO;
pCur->isIndex = !pCur->isTable;
break; break;
} }
@@ -3353,7 +3351,6 @@ case OP_OpenEphemeral: {
} }
} }
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
pCx->isIndex = !pCx->isTable;
break; break;
} }
@@ -3373,7 +3370,6 @@ case OP_SorterOpen: {
pCx->pKeyInfo = pOp->p4.pKeyInfo; pCx->pKeyInfo = pOp->p4.pKeyInfo;
assert( pCx->pKeyInfo->db==db ); assert( pCx->pKeyInfo->db==db );
assert( pCx->pKeyInfo->enc==ENC(db) ); assert( pCx->pKeyInfo->enc==ENC(db) );
pCx->isSorter = 1;
rc = sqlite3VdbeSorterInit(db, pCx); rc = sqlite3VdbeSorterInit(db, pCx);
break; break;
} }
@@ -3405,7 +3401,6 @@ case OP_OpenPseudo: {
pCx->nullRow = 1; pCx->nullRow = 1;
pCx->pseudoTableReg = pOp->p2; pCx->pseudoTableReg = pOp->p2;
pCx->isTable = 1; pCx->isTable = 1;
pCx->isIndex = 0;
pCx->multiPseudo = pOp->p5; pCx->multiPseudo = pOp->p5;
break; break;
} }
@@ -3764,7 +3759,7 @@ case OP_Found: { /* jump, in3 */
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
break; break;
} }
pC->seekResult = res; pC->seekResult = res==0 ? 0 : res<0 ? -1 : +1;
alreadyExists = (res==0); alreadyExists = (res==0);
pC->nullRow = 1-alreadyExists; pC->nullRow = 1-alreadyExists;
pC->deferredMoveto = 0; pC->deferredMoveto = 0;
@@ -3818,7 +3813,7 @@ case OP_NotExists: { /* jump, in3 */
pc = pOp->p2 - 1; pc = pOp->p2 - 1;
assert( pC->rowidIsValid==0 ); assert( pC->rowidIsValid==0 );
} }
pC->seekResult = res; pC->seekResult = res==0 ? 0 : res<0 ? -1 : +1;
break; break;
} }
@@ -4041,7 +4036,7 @@ case OP_InsertInt: {
i64 iKey; /* The integer ROWID or key for the record to be inserted */ i64 iKey; /* The integer ROWID or key for the record to be inserted */
VdbeCursor *pC; /* Cursor to table into which insert is written */ VdbeCursor *pC; /* Cursor to table into which insert is written */
int nZero; /* Number of zero-bytes to append */ int nZero; /* Number of zero-bytes to append */
int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ i8 seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
const char *zDb; /* database name - used by the update hook */ const char *zDb; /* database name - used by the update hook */
const char *zTbl; /* Table name - used by the opdate hook */ const char *zTbl; /* Table name - used by the opdate hook */
int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
@@ -4221,7 +4216,7 @@ case OP_SorterData: {
pOut = &aMem[pOp->p2]; pOut = &aMem[pOp->p2];
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC->isSorter ); assert( isSorter(pC) );
rc = sqlite3VdbeSorterRowkey(pC, pOut); rc = sqlite3VdbeSorterRowkey(pC, pOut);
break; break;
} }
@@ -4261,9 +4256,9 @@ case OP_RowData: {
/* Note that RowKey and RowData are really exactly the same instruction */ /* Note that RowKey and RowData are really exactly the same instruction */
assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC->isSorter==0 ); assert( isSorter(pC)==0 );
assert( pC->isTable || pOp->opcode!=OP_RowData ); assert( pC->isTable || pOp->opcode!=OP_RowData );
assert( pC->isIndex || pOp->opcode==OP_RowData ); assert( pC->isTable==0 || pOp->opcode==OP_RowData );
assert( pC!=0 ); assert( pC!=0 );
assert( pC->nullRow==0 ); assert( pC->nullRow==0 );
assert( pC->pseudoTableReg==0 ); assert( pC->pseudoTableReg==0 );
@@ -4280,7 +4275,7 @@ case OP_RowData: {
rc = sqlite3VdbeCursorMoveto(pC); rc = sqlite3VdbeCursorMoveto(pC);
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
if( pC->isIndex ){ if( pC->isTable==0 ){
assert( !pC->isTable ); assert( !pC->isTable );
VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -4300,7 +4295,7 @@ case OP_RowData: {
} }
pOut->n = n; pOut->n = n;
MemSetTypeFlag(pOut, MEM_Blob); MemSetTypeFlag(pOut, MEM_Blob);
if( pC->isIndex ){ if( pC->isTable==0 ){
rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
}else{ }else{
rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z); rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
@@ -4449,7 +4444,7 @@ case OP_Rewind: { /* jump */
assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC!=0 ); assert( pC!=0 );
assert( pC->isSorter==(pOp->opcode==OP_SorterSort) ); assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
res = 1; res = 1;
if( isSorter(pC) ){ if( isSorter(pC) ){
rc = sqlite3VdbeSorterRewind(db, pC, &res); rc = sqlite3VdbeSorterRewind(db, pC, &res);
@@ -4513,7 +4508,7 @@ case OP_Next: { /* jump */
if( pC==0 ){ if( pC==0 ){
break; /* See ticket #2273 */ break; /* See ticket #2273 */
} }
assert( pC->isSorter==(pOp->opcode==OP_SorterNext) ); assert( isSorter(pC)==(pOp->opcode==OP_SorterNext) );
if( isSorter(pC) ){ if( isSorter(pC) ){
assert( pOp->opcode==OP_SorterNext ); assert( pOp->opcode==OP_SorterNext );
rc = sqlite3VdbeSorterNext(db, pC, &res); rc = sqlite3VdbeSorterNext(db, pC, &res);
@@ -4561,7 +4556,7 @@ case OP_IdxInsert: { /* in2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC!=0 ); assert( pC!=0 );
assert( pC->isSorter==(pOp->opcode==OP_SorterInsert) ); assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
pIn2 = &aMem[pOp->p2]; pIn2 = &aMem[pOp->p2];
assert( pIn2->flags & MEM_Blob ); assert( pIn2->flags & MEM_Blob );
pCrsr = pC->pCursor; pCrsr = pC->pCursor;

View File

@@ -36,7 +36,7 @@ typedef struct VdbeOp Op;
/* /*
** Boolean values ** Boolean values
*/ */
typedef unsigned char Bool; typedef unsigned Bool;
/* Opaque type used by code in vdbesort.c */ /* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter; typedef struct VdbeSorter VdbeSorter;
@@ -63,16 +63,16 @@ struct VdbeCursor {
KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
int pseudoTableReg; /* Register holding pseudotable content. */ int pseudoTableReg; /* Register holding pseudotable content. */
i16 nField; /* Number of fields in the header */ i16 nField; /* Number of fields in the header */
u16 nHdrParsed; /* Number of header fields parsed so far */
i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
Bool rowidIsValid; /* True if lastRowid is valid */ i8 seekResult; /* Result of previous sqlite3BtreeMoveto() */
Bool useRandomRowid; /* Generate new record numbers semi-randomly */ Bool nullRow:1; /* True if pointing to a row with no data */
Bool nullRow; /* True if pointing to a row with no data */ Bool rowidIsValid :1; /* True if lastRowid is valid */
Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
Bool isTable; /* True if a table requiring integer keys */ Bool deferredMoveto:1;/* A call to sqlite3BtreeMoveto() is needed */
Bool isIndex; /* True if an index containing keys only - no data */ Bool isTable:1; /* True if a table requiring integer keys */
Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
Bool isSorter; /* True if a new-style sorter */ Bool multiPseudo:1; /* Multi-register pseudo-cursor */
Bool multiPseudo; /* Multi-register pseudo-cursor */
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ const sqlite3_module *pModule; /* Module for cursor pVtabCursor */
i64 seqCount; /* Sequence counter */ i64 seqCount; /* Sequence counter */
@@ -80,9 +80,6 @@ struct VdbeCursor {
i64 lastRowid; /* Rowid being deleted by OP_Delete */ i64 lastRowid; /* Rowid being deleted by OP_Delete */
VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
/* Result of last sqlite3BtreeMoveto() done by an OP_NotExists */
int seekResult;
/* Cached information about the header for the data record that the /* Cached information about the header for the data record that the
** cursor is currently pointing to. Only valid if cacheStatus matches ** cursor is currently pointing to. Only valid if cacheStatus matches
** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -94,12 +91,9 @@ struct VdbeCursor {
*/ */
u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
u32 payloadSize; /* Total number of bytes in the record */ u32 payloadSize; /* Total number of bytes in the record */
u16 nHdrParsed; /* Number of header fields parsed so far */
u16 nFieldPresent; /* Number of fields in the record */
u32 szRow; /* Byte available in aRow */ u32 szRow; /* Byte available in aRow */
u32 iHdrOffset; /* Offset to next unparsed byte of the header */ u32 iHdrOffset; /* Offset to next unparsed byte of the header */
u32 *aType; /* Type values for all entries in the record */ u32 *aType; /* Type values for all entries in the record */
u32 *aOffset; /* Cached offsets to the start of each columns data */
const u8 *aRow; /* Data for the current row, if all on one page */ const u8 *aRow; /* Data for the current row, if all on one page */
}; };
typedef struct VdbeCursor VdbeCursor; typedef struct VdbeCursor VdbeCursor;

View File

@@ -64,7 +64,8 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
rc = sqlite3_step(p->pStmt); rc = sqlite3_step(p->pStmt);
if( rc==SQLITE_ROW ){ if( rc==SQLITE_ROW ){
u32 type = v->apCsr[0]->aType[p->iCol]; VdbeCursor *pC = v->apCsr[0];
u32 type = pC->aType[p->iCol];
if( type<12 ){ if( type<12 ){
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
type==0?"null": type==7?"real": "integer" type==0?"null": type==7?"real": "integer"
@@ -73,9 +74,9 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
sqlite3_finalize(p->pStmt); sqlite3_finalize(p->pStmt);
p->pStmt = 0; p->pStmt = 0;
}else{ }else{
p->iOffset = v->apCsr[0]->aOffset[p->iCol]; p->iOffset = pC->aType[p->iCol + pC->nField];
p->nByte = sqlite3VdbeSerialTypeLen(type); p->nByte = sqlite3VdbeSerialTypeLen(type);
p->pCsr = v->apCsr[0]->pCursor; p->pCsr = pC->pCursor;
sqlite3BtreeEnterCursor(p->pCsr); sqlite3BtreeEnterCursor(p->pCsr);
sqlite3BtreeCacheOverflow(p->pCsr); sqlite3BtreeCacheOverflow(p->pCsr);
sqlite3BtreeLeaveCursor(p->pCsr); sqlite3BtreeLeaveCursor(p->pCsr);