aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c83
1 files changed, 74 insertions, 9 deletions
diff --git a/src/main.c b/src/main.c
index cf5587839..92e259fc7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.482 2008/07/25 08:49:00 danielk1977 Exp $
+** $Id: main.c,v 1.483 2008/07/28 19:34:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -275,6 +275,12 @@ int sqlite3_config(int op, ...){
}
#endif
+ case SQLITE_CONFIG_LOOKASIDE: {
+ sqlite3Config.szLookaside = va_arg(ap, int);
+ sqlite3Config.nLookaside = va_arg(ap, int);
+ break;
+ }
+
default: {
rc = SQLITE_ERROR;
break;
@@ -285,6 +291,60 @@ int sqlite3_config(int op, ...){
}
/*
+** Set up the lookaside buffers for a database connection.
+** Return SQLITE_OK on success.
+** If lookaside is already active, return SQLITE_BUSY.
+*/
+static int setupLookaside(sqlite3 *db, int sz, int cnt){
+ void *pStart;
+ if( db->lookaside.nOut ){
+ return SQLITE_BUSY;
+ }
+ if( sz<0 ) sz = 0;
+ if( cnt<0 ) cnt = 0;
+ sz = (sz+7)&~7;
+ sqlite3BeginBenignMalloc();
+ pStart = sqlite3Malloc( sz*cnt );
+ sqlite3EndBenignMalloc();
+ if( pStart ){
+ int i;
+ LookasideSlot *p;
+ sqlite3_free(db->lookaside.pStart);
+ db->lookaside.pFree = 0;
+ db->lookaside.pStart = pStart;
+ p = (LookasideSlot*)pStart;
+ for(i=cnt-1; i>=0; i--){
+ p->pNext = db->lookaside.pFree;
+ db->lookaside.pFree = p;
+ p = (LookasideSlot*)&((u8*)p)[sz];
+ }
+ db->lookaside.pEnd = p;
+ db->lookaside.bEnabled = 1;
+ db->lookaside.sz = sz;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Configuration settings for an individual database connection
+*/
+int sqlite3_db_config(sqlite3 *db, int op, ...){
+ va_list ap;
+ int rc = SQLITE_OK;
+ va_start(ap, op);
+ switch( op ){
+ case SQLITE_CONFIG_LOOKASIDE: {
+ int sz = va_arg(ap, int);
+ int cnt = va_arg(ap, int);
+ rc = setupLookaside(db, sz, cnt);
+ break;
+ }
+ }
+ va_end(ap);
+ return rc;
+}
+
+/*
** Routine needed to support the testcase() macro.
*/
#ifdef SQLITE_COVERAGE_TEST
@@ -433,7 +493,7 @@ int sqlite3_close(sqlite3 *db){
FuncDef *pFunc, *pNext;
for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
pNext = pFunc->pNext;
- sqlite3_free(pFunc);
+ sqlite3DbFree(db, pFunc);
}
}
@@ -445,7 +505,7 @@ int sqlite3_close(sqlite3 *db){
pColl[j].xDel(pColl[j].pUser);
}
}
- sqlite3_free(pColl);
+ sqlite3DbFree(db, pColl);
}
sqlite3HashClear(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -454,7 +514,7 @@ int sqlite3_close(sqlite3 *db){
if( pMod->xDestroy ){
pMod->xDestroy(pMod->pAux);
}
- sqlite3_free(pMod);
+ sqlite3DbFree(db, pMod);
}
sqlite3HashClear(&db->aModule);
#endif
@@ -474,10 +534,11 @@ int sqlite3_close(sqlite3 *db){
** the same sqliteMalloc() as the one that allocates the database
** structure?
*/
- sqlite3_free(db->aDb[1].pSchema);
+ sqlite3DbFree(db, db->aDb[1].pSchema);
sqlite3_mutex_leave(db->mutex);
db->magic = SQLITE_MAGIC_CLOSED;
sqlite3_mutex_free(db->mutex);
+ sqlite3_free(db->lookaside.pStart);
sqlite3_free(db);
return SQLITE_OK;
}
@@ -807,7 +868,7 @@ int sqlite3_create_function16(
assert( !db->mallocFailed );
zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1);
rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
- sqlite3_free(zFunc8);
+ sqlite3DbFree(db, zFunc8);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -1312,6 +1373,7 @@ static int openDatabase(
db->nDb = 2;
db->magic = SQLITE_MAGIC_BUSY;
db->aDb = db->aDbStatic;
+
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
db->autoCommit = 1;
@@ -1453,6 +1515,9 @@ static int openDatabase(
SQLITE_DEFAULT_LOCKING_MODE);
#endif
+ /* Enable the lookaside-malloc subsystem */
+ setupLookaside(db, sqlite3Config.szLookaside, sqlite3Config.nLookaside);
+
opendb_out:
if( db ){
assert( db->mutex!=0 || isThreadsafe==0 || sqlite3Config.bFullMutex==0 );
@@ -1580,7 +1645,7 @@ int sqlite3_create_collation16(
zName8 = sqlite3Utf16to8(db, zName, -1);
if( zName8 ){
rc = createCollation(db, zName8, enc, pCtx, xCompare, 0);
- sqlite3_free(zName8);
+ sqlite3DbFree(db, zName8);
}
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -1769,13 +1834,13 @@ error_out:
if( pAutoinc ) *pAutoinc = autoinc;
if( SQLITE_OK==rc && !pTab ){
- sqlite3_free(zErrMsg);
+ sqlite3DbFree(db, zErrMsg);
zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
zColumnName);
rc = SQLITE_ERROR;
}
sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
- sqlite3_free(zErrMsg);
+ sqlite3DbFree(db, zErrMsg);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;