mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Combine the ExprList_item objects and the ExprList wrapper into a single
memory allocation, for improved performance and reduced footprint. FossilOrigin-Name: 2b6560ad88b92820c383bcdc1e30c06f8b081ef7c6d9b1af71d2bb76c83e35cd
This commit is contained in:
40
src/expr.c
40
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){
|
||||
|
||||
Reference in New Issue
Block a user