1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Make the implementation of the sqlite3_aggregate_context() interface faster

for second an subsequent invocations.  This helps all aggregate functions to
perform better.

FossilOrigin-Name: 802148f3110462eac939d53ce08eb9a2f6aac739
This commit is contained in:
drh
2014-08-23 18:17:19 +00:00
parent f1a89ede4a
commit 9de4a17185
3 changed files with 33 additions and 23 deletions

View File

@@ -606,32 +606,42 @@ void sqlite3InvalidFunction(
sqlite3_free(zErr);
}
/*
** Create a new aggregate context for p and return a pointer to
** its pMem->z element.
*/
static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
Mem *pMem = p->pMem;
assert( (pMem->flags & MEM_Agg)==0 );
if( nByte<=0 ){
sqlite3VdbeMemReleaseExternal(pMem);
pMem->flags = MEM_Null;
pMem->z = 0;
}else{
sqlite3VdbeMemGrow(pMem, nByte, 0);
pMem->flags = MEM_Agg;
pMem->u.pDef = p->pFunc;
if( pMem->z ){
memset(pMem->z, 0, nByte);
}
}
return (void*)pMem->z;
}
/*
** Allocate or return the aggregate context for a user function. A new
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
*/
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
Mem *pMem;
assert( p && p->pFunc && p->pFunc->xStep );
assert( sqlite3_mutex_held(p->s.db->mutex) );
pMem = p->pMem;
testcase( nByte<0 );
if( (pMem->flags & MEM_Agg)==0 ){
if( nByte<=0 ){
sqlite3VdbeMemReleaseExternal(pMem);
pMem->flags = MEM_Null;
pMem->z = 0;
}else{
sqlite3VdbeMemGrow(pMem, nByte, 0);
pMem->flags = MEM_Agg;
pMem->u.pDef = p->pFunc;
if( pMem->z ){
memset(pMem->z, 0, nByte);
}
}
if( (p->pMem->flags & MEM_Agg)==0 ){
return createAggContext(p, nByte);
}else{
return (void*)p->pMem->z;
}
return (void*)pMem->z;
}
/*