Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | A few more optimizations to the VDBE. (CVS 1204) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
06e7ff4cb8c73fd690c6d5b5f530a30d |
User & Date: | drh 2004-01-31 20:20:30.000 |
Context
2004-01-31
| ||
20:40 | Fix a bug introduced by the previous check-in. (CVS 1205) (check-in: 04cf22785e user: drh tags: trunk) | |
20:20 | A few more optimizations to the VDBE. (CVS 1204) (check-in: 06e7ff4cb8 user: drh tags: trunk) | |
19:22 | Rework internal data structures to make the VDBE about 15% smaller. (CVS 1203) (check-in: 8273c74bd0 user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.254 2004/01/31 20:20:30 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | ** has focus. ** ** Return 0 on success and 1 if memory is exhausted. */ static int AggInsert(Agg *p, char *zKey, int nKey){ AggElem *pElem, *pOld; int i; pElem = sqliteMalloc( sizeof(AggElem) + nKey + (p->nMem-1)*sizeof(pElem->aMem[0]) ); if( pElem==0 ) return 1; pElem->zKey = (char*)&pElem->aMem[p->nMem]; memcpy(pElem->zKey, zKey, nKey); pElem->nKey = nKey; pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem); if( pOld!=0 ){ assert( pOld==pElem ); /* Malloc failed on insert */ sqliteFree(pOld); return 0; } | > | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | ** has focus. ** ** Return 0 on success and 1 if memory is exhausted. */ static int AggInsert(Agg *p, char *zKey, int nKey){ AggElem *pElem, *pOld; int i; Mem *pMem; pElem = sqliteMalloc( sizeof(AggElem) + nKey + (p->nMem-1)*sizeof(pElem->aMem[0]) ); if( pElem==0 ) return 1; pElem->zKey = (char*)&pElem->aMem[p->nMem]; memcpy(pElem->zKey, zKey, nKey); pElem->nKey = nKey; pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem); if( pOld!=0 ){ assert( pOld==pElem ); /* Malloc failed on insert */ sqliteFree(pOld); return 0; } for(i=0, pMem=pElem->aMem; i<p->nMem; i++, pMem++){ pMem->flags = MEM_Null; } p->pCurrent = pElem; return 0; } /* ** Get the AggElem currently in focus |
︙ | ︙ | |||
764 765 766 767 768 769 770 | ** See also the Dup instruction. */ case OP_Pull: { Mem *pFrom = &pTos[-pOp->p1]; int i; Mem ts; | < < < < | 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 | ** See also the Dup instruction. */ case OP_Pull: { Mem *pFrom = &pTos[-pOp->p1]; int i; Mem ts; ts = *pFrom; Deephemeralize(pTos); for(i=0; i<pOp->p1; i++, pFrom++){ Deephemeralize(&pFrom[1]); *pFrom = pFrom[1]; assert( (pFrom->flags & MEM_Ephem)==0 ); if( pFrom->flags & MEM_Short ){ assert( pFrom->flags & MEM_Str ); assert( pFrom->z==pFrom[1].zShort ); pFrom->z = pFrom->zShort; } } *pTos = ts; if( pTos->flags & MEM_Short ){ assert( pTos->flags & MEM_Str ); assert( pTos->z==pTos[-pOp->p1].zShort ); pTos->z = pTos->zShort; } break; } /* Opcode: Push P1 * * ** |
︙ | ︙ | |||
4249 4250 4251 4252 4253 4254 4255 | ** ** After the data is stored in the memory location, the ** stack is popped once if P2 is 1. If P2 is zero, then ** the original data remains on the stack. */ case OP_MemStore: { int i = pOp->p1; | < < > < < | < < < < | < | < | 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 | ** ** After the data is stored in the memory location, the ** stack is popped once if P2 is 1. If P2 is zero, then ** the original data remains on the stack. */ case OP_MemStore: { int i = pOp->p1; Mem *pMem; assert( pTos>=p->aStack ); if( i>=p->nMem ){ int nOld = p->nMem; Mem *aMem; p->nMem = i + 5; aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0])); if( aMem==0 ) goto no_mem; if( aMem!=p->aMem ){ int j; for(j=0; j<nOld; j++){ if( aMem[j].flags & MEM_Short ){ aMem[j].z = aMem[j].zShort; } } } p->aMem = aMem; if( nOld<p->nMem ){ memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld)); } } Deephemeralize(pTos); pMem = &p->aMem[i]; Release(pMem); *pMem = *pTos; if( pMem->flags & MEM_Dyn ){ if( pOp->p2 ){ pTos->flags = MEM_Null; }else{ pMem->z = sqliteMallocRaw( pMem->n ); if( pMem->z==0 ) goto no_mem; memcpy(pMem->z, pTos->z, pMem->n); } }else if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; } if( pOp->p2 ){ Release(pTos); pTos--; } break; } |
︙ | ︙ | |||
4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 | /* Opcode: AggSet * P2 * ** ** Move the top of the stack into the P2-th field of the current ** aggregate. String values are duplicated into new memory. */ case OP_AggSet: { AggElem *pFocus = AggInFocus(p->agg); int i = pOp->p2; assert( pTos>=p->aStack ); if( pFocus==0 ) goto no_mem; | > | < | | < < | < < < < | | | | | < < > | < < | | | | < | 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 | /* Opcode: AggSet * P2 * ** ** Move the top of the stack into the P2-th field of the current ** aggregate. String values are duplicated into new memory. */ case OP_AggSet: { AggElem *pFocus = AggInFocus(p->agg); Mem *pMem; int i = pOp->p2; assert( pTos>=p->aStack ); if( pFocus==0 ) goto no_mem; assert( i>=0 && i<p->agg.nMem ); Deephemeralize(pTos); pMem = &pFocus->aMem[i]; Release(pMem); *pMem = *pTos; if( pMem->flags & MEM_Dyn ){ pTos->flags = MEM_Null; }else if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; } Release(pTos); pTos--; break; } /* Opcode: AggGet * P2 * ** ** Push a new entry onto the stack which is a copy of the P2-th field ** of the current aggregate. Strings are not duplicated so ** string values will be ephemeral. */ case OP_AggGet: { AggElem *pFocus = AggInFocus(p->agg); Mem *pMem; int i = pOp->p2; if( pFocus==0 ) goto no_mem; assert( i>=0 && i<p->agg.nMem ); pTos++; pMem = &pFocus->aMem[i]; *pTos = *pMem; pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short); pTos->flags |= MEM_Ephem; break; } /* Opcode: AggNext * P2 * ** ** Make the next aggregate value the current aggregate. The prior ** aggregate is deleted. If all aggregate values have been consumed, |
︙ | ︙ |