From: drh <> Date: Tue, 23 Mar 2021 14:27:35 +0000 (+0000) Subject: Add the ExprList.nAlloc column and use it to make the sqlite3ExprListAppend() X-Git-Tag: version-3.36.0~298 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=50e43c5094c6bc4940d60efe637f58e4a2ad5866;p=thirdparty%2Fsqlite.git Add the ExprList.nAlloc column and use it to make the sqlite3ExprListAppend() routine much faster. FossilOrigin-Name: 1d3c4662c2f522ac695d97441324069f3fc65f3fa0b87194c7094dfb8cd549f2 --- diff --git a/manifest b/manifest index 7c280e82c5..d66dbe7bb3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sEXPLAIN\sQUERY\sPLAN\soutput\sto\suse\ssymbolic\snames\sto\sdescribe\nsubqueries,\swhere\spossible,\sinstead\sof\scryptic\ssubquery\sindex\snumbers.\nAnd\sin\sother\sways,\smake\sthe\sEQP\soutput\scleaner\sand\seasier\sto\sread.\s\sLittle\ncode\sis\schanged,\sbut\smany\sof\sthe\stest\sresults\shad\sto\sbe\stweaked\sto\salign\nwith\sthe\snew\soutput\sformat. -D 2021-03-23T01:06:02.016 +C Add\sthe\sExprList.nAlloc\scolumn\sand\suse\sit\sto\smake\sthe\ssqlite3ExprListAppend()\nroutine\smuch\sfaster. +D 2021-03-23T14:27:35.868 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,7 +494,7 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8 -F src/expr.c d681f0b48b1e16173ad8e1e8f7323cda120a0c517cb7a3d5b329c4e2c57f18bd +F src/expr.c 030391f7a19e74e10ce9f2791f26158b34ee303c13993add67dff87501673d49 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c 479f6929be027eb0210cbdde9d3529c012facf082d64a6b854a9415940761e5e @@ -547,7 +547,7 @@ F src/shell.c.in dcce260883836c9b58847505fbccce8d5546af925046f7dacd9443e922ece03 F src/sqlite.h.in 3426a080ea1f222a73e3bd91e7eacbd30570a0117c03d42c6dde606f33e5e318 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 0f81c7eb3a40dda0b74d0acdc8f3b134346b40be780b1fe5cc24dd294a928d1a +F src/sqliteInt.h ff7d50a5426b3c95009878c5999eb4a5f1e6c7b253f5078c3220e721ebce59ee F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1910,8 +1910,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5cee689d647087a5e796da2acb247a4f469a8b39b54f59bb4ad2386647cef1bd 4a343698b4ec3364b0eecb7fa074512ecac8b586aff1f977ca77f215e96e0ce5 -R 48f6135c13bc2817f3ef8d214e2b8cca -T +closed 4a343698b4ec3364b0eecb7fa074512ecac8b586aff1f977ca77f215e96e0ce5 +P f8e28308fdb45fbdef30003320d653410d69bb8ec92eef35c4245a99e2d0603b +R 1cbc2c59a37c000c5e08f004024699d7 U drh -Z e5cc6839eb4d695ea4294201dffd3a86 +Z 02264e1fe3d1242b0fb1e324e35ad2ff diff --git a/manifest.uuid b/manifest.uuid index ee290880e5..86935cb2f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f8e28308fdb45fbdef30003320d653410d69bb8ec92eef35c4245a99e2d0603b \ No newline at end of file +1d3c4662c2f522ac695d97441324069f3fc65f3fa0b87194c7094dfb8cd549f2 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index bd12ad9f0c..e3d28f4d43 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1478,6 +1478,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p)); if( pNew==0 ) return 0; pNew->nExpr = p->nExpr; + pNew->nAlloc = p->nAlloc; pItem = pNew->a; pOldItem = p->a; for(i=0; inExpr; i++, pItem++, pOldItem++){ @@ -1650,41 +1651,64 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ ** NULL is returned. If non-NULL is returned, then it is guaranteed ** that the new entry was successfully appended. */ +static const struct ExprList_item zeroItem; +SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew( + sqlite3 *db, /* Database handle. Used for memory allocation */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + ExprList *pList; + + pList = sqlite3DbMallocRawNN(db, sizeof(ExprList)+sizeof(pList->a[0])*4 ); + if( pList==0 ){ + sqlite3ExprDelete(db, pExpr); + return 0; + } + pList->nAlloc = 4; + pList->nExpr = 1; + pItem = &pList->a[0]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} +SQLITE_NOINLINE ExprList *sqlite3ExprListAppendGrow( + sqlite3 *db, /* Database handle. Used for memory allocation */ + ExprList *pList, /* List to which to append. Might be NULL */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + ExprList *pNew; + pList->nAlloc *= 2; + pNew = sqlite3DbRealloc(db, pList, + sizeof(*pList)+(pList->nAlloc-1)*sizeof(pList->a[0])); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pList); + sqlite3ExprDelete(db, pExpr); + return 0; + }else{ + pList = pNew; + } + pItem = &pList->a[pList->nExpr++]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} ExprList *sqlite3ExprListAppend( Parse *pParse, /* Parsing context */ 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 ){ - pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) ); - if( pList==0 ){ - goto no_mem; - } - pList->nExpr = 0; - }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ - ExprList *pNew; - pNew = sqlite3DbRealloc(db, pList, - sizeof(*pList)+(2*(sqlite3_int64)pList->nExpr-1)*sizeof(pList->a[0])); - if( pNew==0 ){ - goto no_mem; - } - pList = pNew; + return sqlite3ExprListAppendNew(pParse->db,pExpr); + } + if( pList->nAllocnExpr+1 ){ + return sqlite3ExprListAppendGrow(pParse->db,pList,pExpr); } pItem = &pList->a[pList->nExpr++]; - assert( offsetof(struct ExprList_item,zEName)==sizeof(pItem->pExpr) ); - assert( offsetof(struct ExprList_item,pExpr)==0 ); - memset(&pItem->zEName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zEName)); + *pItem = zeroItem; pItem->pExpr = pExpr; return pList; - -no_mem: - /* Avoid leaking memory if malloc has failed. */ - sqlite3ExprDelete(db, pExpr); - sqlite3ExprListDelete(db, pList); - return 0; } /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6bd53d20f8..69740248f4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2878,6 +2878,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 *zEName; /* Token associated with this expression */