aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/expr.c40
-rw-r--r--src/select.c2
-rw-r--r--src/sqliteInt.h3
3 files changed, 19 insertions, 26 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){
diff --git a/src/select.c b/src/select.c
index bb055c789..297b4d719 100644
--- a/src/select.c
+++ b/src/select.c
@@ -2900,7 +2900,7 @@ static int multiSelectOrderBy(
if( pNew==0 ) return SQLITE_NOMEM_BKPT;
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
- pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
+ p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
}
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 271ea9a3e..a0acec471 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2443,6 +2443,7 @@ struct Expr {
*/
struct ExprList {
int nExpr; /* Number of expressions on the list */
+ int nAlloc; /* Number of a[] slots allocated */
struct ExprList_item { /* For each expression in the list */
Expr *pExpr; /* The parse tree for this expression */
char *zName; /* Token associated with this expression */
@@ -2458,7 +2459,7 @@ struct ExprList {
} x;
int iConstExprReg; /* Register in which Expr value is cached */
} u;
- } *a; /* Alloc a power of two greater or equal to nExpr */
+ } a[1]; /* One slot for each expression in the list */
};
/*