aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2017-04-05 11:32:13 +0000
committerdrh <drh@noemail.net>2017-04-05 11:32:13 +0000
commit43606175e2e8fae94fa98f18353a3c335c708eb1 (patch)
tree72c2167727340160faf1ec49b78f48d13aef1430 /src/expr.c
parent32d0eba4c2250059f0dcef0612f0a6b3ab5679f6 (diff)
downloadsqlite-43606175e2e8fae94fa98f18353a3c335c708eb1.tar.gz
sqlite-43606175e2e8fae94fa98f18353a3c335c708eb1.zip
Combine the ExprList_item objects and the ExprList wrapper into a single
memory allocation, for improved performance and reduced footprint. FossilOrigin-Name: 2b6560ad88b92820c383bcdc1e30c06f8b081ef7c6d9b1af71d2bb76c83e35cd
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c40
1 files changed, 16 insertions, 24 deletions
diff --git a/src/expr.c b/src/expr.c
index ce948be69..8d935764a 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1305,15 +1305,11 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
Expr *pPriorSelectCol = 0;
assert( db!=0 );
if( p==0 ) return 0;
- pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
+ pNew = sqlite3DbMallocRawNN(db,
+ sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) );
if( pNew==0 ) return 0;
- pNew->nExpr = i = p->nExpr;
- if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){}
- pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) );
- if( pItem==0 ){
- sqlite3DbFree(db, pNew);
- return 0;
- }
+ pNew->nAlloc = pNew->nExpr = p->nExpr;
+ pItem = pNew->a;
pOldItem = p->a;
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
Expr *pOldExpr = pOldItem->pExpr;
@@ -1475,6 +1471,7 @@ ExprList *sqlite3ExprListAppend(
ExprList *pList, /* List to which to append. Might be NULL */
Expr *pExpr /* Expression to be appended. Might be NULL */
){
+ struct ExprList_item *pItem;
sqlite3 *db = pParse->db;
assert( db!=0 );
if( pList==0 ){
@@ -1483,23 +1480,20 @@ ExprList *sqlite3ExprListAppend(
goto no_mem;
}
pList->nExpr = 0;
- pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0]));
- if( pList->a==0 ) goto no_mem;
- }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
- struct ExprList_item *a;
- assert( pList->nExpr>0 );
- a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
- if( a==0 ){
+ pList->nAlloc = 1;
+ }else if( pList->nExpr==pList->nAlloc ){
+ ExprList *pNew;
+ pNew = sqlite3DbRealloc(db, pList,
+ sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0]));
+ if( pNew==0 ){
goto no_mem;
}
- pList->a = a;
- }
- assert( pList->a!=0 );
- if( 1 ){
- struct ExprList_item *pItem = &pList->a[pList->nExpr++];
- memset(pItem, 0, sizeof(*pItem));
- pItem->pExpr = pExpr;
+ pList = pNew;
+ pList->nAlloc *= 2;
}
+ pItem = &pList->a[pList->nExpr++];
+ memset(pItem, 0, sizeof(*pItem));
+ pItem->pExpr = pExpr;
return pList;
no_mem:
@@ -1665,13 +1659,11 @@ void sqlite3ExprListCheckLength(
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
int i;
struct ExprList_item *pItem;
- assert( pList->a!=0 || pList->nExpr==0 );
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
sqlite3ExprDelete(db, pItem->pExpr);
sqlite3DbFree(db, pItem->zName);
sqlite3DbFree(db, pItem->zSpan);
}
- sqlite3DbFree(db, pList->a);
sqlite3DbFree(db, pList);
}
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){