$(TOP)/src/insert.c \
$(TOP)/src/legacy.c \
$(TOP)/src/loadext.c \
+ $(TOP)/src/lookaside.c \
+ $(TOP)/src/lookaside.h \
$(TOP)/src/main.c \
$(TOP)/src/malloc.c \
$(TOP)/src/mem0.c \
$(TOP)/src/hash.h \
$(TOP)/src/hwtime.h \
keywordhash.h \
+ $(TOP)/src/lookaside.h \
$(TOP)/src/msvc.h \
$(TOP)/src/mutex.h \
opcodes.h \
loadext.lo: $(TOP)/src/loadext.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c
+lookaside.lo: $(TOP)/src/lookaside.c $(HDR)
+ $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/lookaside.c
+
main.lo: $(TOP)/src/main.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c
$(TOP)\src\insert.c \
$(TOP)\src\legacy.c \
$(TOP)\src\loadext.c \
+ $(TOP)\src\lookaside.c \
$(TOP)\src\main.c \
$(TOP)\src\malloc.c \
$(TOP)\src\mem0.c \
$(TOP)\src\btreeInt.h \
$(TOP)\src\hash.h \
$(TOP)\src\hwtime.h \
+ $(TOP)\src\lookaside.h \
$(TOP)\src\msvc.h \
$(TOP)\src\mutex.h \
$(TOP)\src\os.h \
$(TOP)\src\btreeInt.h \
$(TOP)\src\hash.h \
$(TOP)\src\hwtime.h \
+ $(TOP)\src\lookaside.h \
keywordhash.h \
$(TOP)\src\msvc.h \
$(TOP)\src\mutex.h \
loadext.lo: $(TOP)\src\loadext.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\loadext.c
+lookaside.lo: $(TOP)\src\lookaside.c $(HDR)
+ $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\lookaside.c
+
main.lo: $(TOP)\src\main.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\main.c
$(TOP)/src/insert.c \
$(TOP)/src/legacy.c \
$(TOP)/src/loadext.c \
+ $(TOP)/src/lookaside.c \
+ $(TOP)/src/lookaside.h \
$(TOP)/src/main.c \
$(TOP)/src/malloc.c \
$(TOP)/src/mem0.c \
$(TOP)/src/hash.h \
$(TOP)/src/hwtime.h \
keywordhash.h \
+ $(TOP)/src/lookaside.h \
$(TOP)/src/msvc.h \
$(TOP)/src/mutex.h \
opcodes.h \
-C Fix\sproblems\swith\susing\sthe\sfts5\s'rebuild'\scommand\sinside\sa\stransaction\sthat\scontains\sother\supdates\sof\sthe\ssame\stable.\sFix\sfor\s[e258f008].
-D 2019-10-08T13:34:24.536
+C An\salternative,\sexperimental\slookaside\smemory\sallocator\sthat\suses\stwo\ndifferent\sslot\ssizes.
+D 2019-10-09T17:06:38.567
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
-F Makefile.in 578f123620087ea459aa08fa872810a25ca7c0aaf16331de985bfcddb5f1e747
+F Makefile.in 97473628071905a0496a38e1b0721dda732829c89fa0b87675d877c26d95936a
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
-F Makefile.msc a463dca3c50d8a36094fe5c8c39077907f530b54edfc5388c66c85e2cfc8dc04
+F Makefile.msc 99a026807172f0e99c982d386a6470c445307a9fd0383aa4692406102ad7e7e4
F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a
F VERSION 4c516d84c2a5f26c477ed34c09ac4136630f71c68139631f2eb591b22eea7cf1
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
-F main.mk 09716d345766a55b25ed157b14786526cf67c761c61d99c53e117196fb3b391a
+F main.mk b939f7fa33486a28466c40dcbd6681b817a66de73aa9e121434e471b16ac731a
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 5773b28684a001dcab45adcefa3cbf5e846335c0c8fee0da8a3770cb0123bba8
-F src/analyze.c 481d9cf34a3c70631ef5c416be70033e8d4cd85eb5ad1b37286aed8b0e29e889
+F src/analyze.c 777b22900cfcbb1e87f73b09ac45986c91ed76beea0442cf55fce7eb2bba4228
F src/attach.c 3ca19504849c2d9be10fc5899d6811f9d6e848665d1a41ffb53df0cd6e7c13ed
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab
F src/btree.c fdc4389b271bca30138db27dc2dfb9f52c2a7baaa44845aaf31a3c54663d837f
F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89
F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
-F src/build.c 13de2fdabbabcf2e2aaf6443a049fb851d9d3170136c08345468e158ceea3dc6
+F src/build.c 804fd944dde39ae429a913541091785eede543ad6fdbef3eafbb3224c9c329d7
F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
F src/expr.c 1e9a6da29e3e13c14783891e867e19a54e2731c6a9b58d011cc4f3b4742a59e4
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
-F src/fkey.c 6271fda51794b569d736eba4097d28f13080cd0c9eb66d5fcecb4b77336fae50
+F src/fkey.c 48921db21c10b7857efe8a9f4dd9dbe7fe931df3eaea0913629e8512924fc8ef
F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
F src/global.c a1a8d698762ddd9a1543aac26c1e0029b20fcc3fcb56bfa41ec8cea2368f2798
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/insert.c 40557ebd69f4115e7a273f9304a8ab637a47ce44f3c6923396928f023967b5e8
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 4ddc65ae13c0d93db0ceedc8b14a28c8c260513448b0eb8c5a2ac375e3b6a85d
-F src/main.c 3e01f6a1c96643381b5f9d79e4ff7f2520bc5712197746fb0852283e78cccf66
-F src/malloc.c b7640bcf8992cf2e98447da0d27e372abdc4621a6760418bad6d1470f041ada9
+F src/lookaside.c 3d569191e4f177153524eb376ac18ada6ab49430c15c392291aed033bd7a3203
+F src/lookaside.h 088106f3dc9933f7e9f3570eff86ef29e762ba351027cac733c866a4a5b6244c
+F src/main.c 5771725469dcb97667c647ebd8192073c925d13efdd46f94a84738187fa0a0bb
+F src/malloc.c 7b36b39aae0da3a9253ae5c7396831e45b2afb342a9f22a4afa314fe7e492c9d
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b
F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3
-F src/parse.y 19c8b65c87a5bec5efcb7eaf44e3178d860bc77baab4b03d7b53b08369ac83bf
+F src/parse.y 916f6f75b929b13fe26b18023a80b9085893ef3f6483611489b5185d7df2d3bf
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848
F src/pragma.c b47bc7db02ab13d04c680aee424466b4e34f4ef5aa7b2e464876ec005806f98f
F src/pragma.h 40962d65b645bb3f08c1f4c456effd01c6e7f073f68ea25177e0c95e181cff75
-F src/prepare.c fc245d2049e5e9e76738cd403e63c9832ff61c706d19607d2b62a51f1747609c
+F src/prepare.c 5cd97fadcf1b98de8260fd5077abb666929433ec48c533fc6b4b222a64c99276
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c e021be0c1c4a2125fa38aabcd8dbb764bf5b2c889a948c30d3708430ec6ccd00
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
-F src/select.c f509982c96bb24ccf57a0155fbe1e6184e0b8fb8866a04397dc41baa400e5240
+F src/select.c fd56dee1f38362ba6a1c2b8f07ca4a73e2a195d5b16d562d4264a7cfa061ceeb
F src/shell.c.in d70bcf630c4073eaa994fa74be98886c781918e794cb8b562be8df10f018e274
F src/sqlite.h.in 5725a6b20190a1e8d662077a1c1c8ea889ad7be90dd803f914c2de226f5fe6ab
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
-F src/sqliteInt.h b70ac8e3e7e74838bc45dca1a3b2c3ef4b4e04a49036448bf462cfd657cc663f
+F src/sqliteInt.h 2ce2d769c4accccc58df69de32f935585086e205bb17730ea6f72c11f43dd938
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
-F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
+F src/status.c 364babdad7295c0219b398468e0a24374f6e1bf27906837be347ea0538148ce2
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290
F src/test1.c 17e1395cbddeb9226b756d723a7566b45b43b99a5f9f55afb4ff70888de6ad6f
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
-F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
-F tool/mksqlite3c.tcl 5fed3d75069d8f66f202d3b5200b0cea4aa7108481acd06732a06fdd42eb83a2
+F tool/mksqlite3c-noext.tcl ed9eee26b0a54d38b15e56a8dba7936369306b8b3b359fb13269cfd3bb8df764
+F tool/mksqlite3c.tcl bba4605f267e5884fc8213f1d0b49b4670c6a0852c8e5186bd0b39f8005c9c67
F tool/mksqlite3h.tcl 080873e3856eceb9d289a08a00c4b30f875ea3feadcbece796bd509b1532792c
-F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
+F tool/mksqlite3internalh.tcl dd425d58d29dedabe24246ed61dd6c0bfd7d9458ca05bb3b9acb46453a043947
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
F tool/omittest.tcl 27f9413c3343bac200a28d81e8234adb0f5e141c4771893cb19b40235a91f1e0
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 8ab0aebdb3c2d6fb3160b2c58ce6cc0495a6ddd960878a6395958c837f3d1b71
-R 74814f3b82ccc57c689e36d5b9ae7e28
-U dan
-Z 1ced3dbc55f7a754d800609f44681fb4
+P 238e0835714696aba0631f288fcc30ec5fddb43893d469c6bf017f386b3cddee
+R ff93c002380d3f08d9900baed24887de
+T *branch * 2-size-lookaside
+T *sym-2-size-lookaside *
+T -sym-trunk *
+U sperry
+Z f6212e7bc680bb8a80c6fe2ff4a2e853
-238e0835714696aba0631f288fcc30ec5fddb43893d469c6bf017f386b3cddee
\ No newline at end of file
+5ba8cee8f710eb2a6844d5de0d975c207e5645754e30211a4cb5a4869248b693
\ No newline at end of file
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"
+#include "lookaside.h"
#if defined(SQLITE_ENABLE_STAT4)
# define IsStat4 1
Index *pPrevIdx = 0; /* Previous index in the loop */
IndexSample *pSample; /* A slot in pIdx->aSample[] */
- assert( db->lookaside.bDisable );
+ assert( sqlite3LookasideDisabled(&db->lookaside) );
zSql = sqlite3MPrintf(db, zSql1, zDb);
if( !zSql ){
return SQLITE_NOMEM_BKPT;
static int loadStat4(sqlite3 *db, const char *zDb){
int rc = SQLITE_OK; /* Result codes from subroutines */
- assert( db->lookaside.bDisable );
+ assert( sqlite3LookasideDisabled(&db->lookaside) );
if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
rc = loadStatTbl(db,
"SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx",
/* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT4
if( rc==SQLITE_OK ){
- DisableLookaside;
+ sqlite3LookasideDisable(&db->lookaside);
rc = loadStat4(db, sInfo.zDatabase);
- EnableLookaside;
+ sqlite3LookasideEnable(&db->lookaside);
}
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
** ROLLBACK
*/
#include "sqliteInt.h"
+#include "lookaside.h"
#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** that no lookaside memory is used in this case either. */
int nLookaside = 0;
if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
- nLookaside = sqlite3LookasideUsed(db, 0);
+ nLookaside = sqlite3LookasideUsed(&db->lookaside, 0);
}
#endif
sqlite3DbFree(db, pTable);
/* Verify that no lookaside memory was used by schema tables */
- assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) );
+ assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(&db->lookaside,0) );
}
void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
/* Do not delete the table until the reference count reaches zero. */
** support to compiled SQL statements.
*/
#include "sqliteInt.h"
+#include "lookaside.h"
#ifndef SQLITE_OMIT_FOREIGN_KEY
#ifndef SQLITE_OMIT_TRIGGER
}
/* Disable lookaside memory allocation */
- DisableLookaside;
+ sqlite3LookasideDisable(&db->lookaside);
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
}
/* Re-enable the lookaside buffer, if it was disabled earlier. */
- EnableLookaside;
+ sqlite3LookasideEnable(&db->lookaside);
sqlite3ExprDelete(db, pWhere);
sqlite3ExprDelete(db, pWhen);
--- /dev/null
+/*
+** 2019-10-02
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** Lookaside memory allocation functions used throughout sqlite.
+*/
+
+#include "sqliteInt.h"
+#include "lookaside.h"
+
+/*
+** Return the number of LookasideSlot elements on the linked list
+*/
+static u32 countLookasideSlots(LookasideSlot *p){
+ u32 cnt = 0;
+ while( p ){
+ p = p->pNext;
+ cnt++;
+ }
+ return cnt;
+}
+
+/*
+** Count the number of slots of lookaside memory that are outstanding
+*/
+int sqlite3LookasideUsed(Lookaside *pLookaside, int *pHighwater){
+ u32 nInit = countLookasideSlots(pLookaside->pInit);
+ u32 nFree = countLookasideSlots(pLookaside->pFree);
+ if( pHighwater ) *pHighwater = pLookaside->nSlot - nInit;
+ return pLookaside->nSlot - (nInit+nFree);
+}
+
+void sqlite3LookasideResetUsed(Lookaside *pLookaside){
+ LookasideSlot *p = pLookaside->pFree;
+ if( p ){
+ while( p->pNext ) p = p->pNext;
+ p->pNext = pLookaside->pInit;
+ pLookaside->pInit = pLookaside->pFree;
+ pLookaside->pFree = 0;
+ }
+}
+
+#ifndef SQLITE_OMIT_LOOKASIDE
+
+static void *lookasideSlotAlloc(Lookaside *pLookaside, u64 n){
+ LookasideSlot *pBuf;
+ if( (pBuf = pLookaside->pFree)!=0 ){
+ pLookaside->pFree = pBuf->pNext;
+ pLookaside->anStat[0]++;
+ return (void*)pBuf;
+ }else if( (pBuf = pLookaside->pInit)!=0 ){
+ pLookaside->pInit = pBuf->pNext;
+ pLookaside->anStat[0]++;
+ return (void*)pBuf;
+ }else{
+ pLookaside->anStat[2]++;
+ return 0;
+ }
+}
+
+static void lookasideSlotFree(Lookaside *pLookaside, void *p){
+ LookasideSlot *pBuf = (LookasideSlot*)p;
+# ifdef SQLITE_DEBUG
+ /* Scribble over the content in the buffer being freed */
+ memset(p, 0xaa, pLookaside->szTrue);
+# endif
+ pBuf->pNext = pLookaside->pFree;
+ pLookaside->pFree = pBuf;
+}
+
+# ifndef SQLITE_OMIT_MINI_LOOKASIDE
+# ifndef SQLITE_MINI_LOOKASIDE_MIN_SLOT_SIZE
+# define SQLITE_MINI_LOOKASIDE_MIN_SLOT_SIZE 128
+# endif
+
+static void *miniLookasideAlloc(Lookaside *pLookaside, u16 n){
+ void *p = 0;
+ LookasideSlot *pSlot;
+ int iMiniSlot;
+
+ assert( n<=pLookaside->szMini );
+
+ if( !pLookaside->pMini ){
+ pSlot = lookasideSlotAlloc(pLookaside, pLookaside->szTrue);
+ if( !pSlot ){
+ return p;
+ }
+ bzero(pSlot, sizeof(LookasideSlot));
+ pLookaside->pMini = pSlot;
+ }else{
+ pSlot = pLookaside->pMini;
+ assert( pSlot->bMembership );
+ }
+
+ assert( pSlot->bMembership < (1<<pLookaside->nMini)-1 );
+
+ iMiniSlot = __builtin_ffs(~pSlot->bMembership) - 1;
+ assert(iMiniSlot < pLookaside->nMini);
+ assert( (pSlot->bMembership&(1<<iMiniSlot))==0 );
+ pSlot->bMembership |= 1<<iMiniSlot;
+
+ p = (char *)pSlot + sizeof(LookasideSlot) + (pLookaside->szMini * iMiniSlot);
+
+ /* Remove slot from pMini if it is full of sub-allocations */
+ if( pSlot->bMembership == (1<<pLookaside->nMini)-1 ){
+ /* Slot is full, dequeue from list */
+ if( pSlot->pNext ){
+ assert( pSlot->pNext->pPrev == pSlot );
+ pSlot->pNext->pPrev = pSlot->pPrev;
+ }
+ if( pSlot->pPrev ){
+ assert( pSlot->pPrev->pNext == pSlot );
+ pSlot->pPrev->pNext = pSlot->pNext;
+ }else{
+ assert( pLookaside->pMini == pSlot );
+ pLookaside->pMini = pSlot->pNext;
+ }
+ pSlot->pNext = pSlot->pPrev = 0;
+ }
+ return p;
+}
+
+static void miniLookasideFree(Lookaside *pLookaside, void *p){
+ int iSlotNum = ((u8*)p - (u8*)pLookaside->pStart) / pLookaside->szTrue;
+ LookasideSlot *pSlot = (LookasideSlot *)(iSlotNum * pLookaside->szTrue + (u8*)pLookaside->pStart);
+ int iMiniSlot = ((u8*)p - ((u8*)pSlot + sizeof(LookasideSlot))) / pLookaside->szMini;
+
+ assert( pSlot->bMembership );
+ assert( pSlot->bMembership < (1<<pLookaside->nMini) );
+ assert( iMiniSlot<pLookaside->nMini );
+
+ /* Return slot to pMini list if it was full */
+ if( pSlot->bMembership == (1<<pLookaside->nMini)-1 ){
+ assert( pSlot->pNext == pSlot->pPrev && pSlot->pPrev == 0 );
+ if( pLookaside->pMini ){
+ assert( !pLookaside->pMini->pPrev );
+ pSlot->pNext = pLookaside->pMini;
+ pSlot->pNext->pPrev = pSlot;
+ }
+ pLookaside->pMini = pSlot;
+ }
+
+ pSlot->bMembership &= ~(1<<iMiniSlot);
+#ifdef SQLITE_DEBUG
+ memset(p, 0xaa, pLookaside->szMini);
+#endif
+
+ /* Return slot to the lookaside pool if it is empty */
+ if( pSlot->bMembership == 0 ){
+ if( pSlot->pNext ){
+ assert( pSlot->pNext->pPrev == pSlot );
+ pSlot->pNext->pPrev = pSlot->pPrev;
+ }
+ if( pSlot->pPrev ){
+ assert( pSlot->pPrev->pNext == pSlot );
+ pSlot->pPrev->pNext = pSlot->pNext;
+ }else{
+ assert( pLookaside->pMini==pSlot );
+ pLookaside->pMini = pSlot->pNext;
+ }
+ lookasideSlotFree(pLookaside, pSlot);
+ }
+}
+
+# else
+# define miniLookasideAlloc(A, B) lookasideSlotAlloc(A, B)
+# define miniLookasideFree(A, B) lookasideSlowFree(A, B)
+# endif /* !SQLITE_OMIT_MINI_LOOKASIDE */
+
+int sqlite3LookasideOpen(void *pBuf, int sz, int cnt, Lookaside *pLookaside){
+ void *pStart;
+
+ if( sqlite3LookasideUsed(pLookaside,0)>0 ){
+ return SQLITE_BUSY;
+ }
+ /* Free any existing lookaside buffer for this handle before
+ ** allocating a new one so we don't have to have space for
+ ** both at the same time.
+ */
+ if( pLookaside->bMalloced ){
+ sqlite3_free(pLookaside->pStart);
+ }
+ /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
+ ** than sizeof(LookasideSlot) to be useful.
+ */
+ sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
+ if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
+ if( cnt<0 ) cnt = 0;
+ if( sz==0 || cnt==0 ){
+ sz = 0;
+ pStart = 0;
+ }else if( pBuf==0 ){
+ sqlite3BeginBenignMalloc();
+ pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt ); /* IMP: R-61949-35727 */
+ sqlite3EndBenignMalloc();
+ if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
+ }else{
+ pStart = pBuf;
+ }
+ pLookaside->pStart = pStart;
+ pLookaside->pInit = 0;
+ pLookaside->pFree = 0;
+ pLookaside->sz = (u16)sz;
+ pLookaside->szTrue = (u16)sz;
+#ifndef SQLITE_OMIT_MINILOOKASIDE
+ pLookaside->pMini = 0;
+ pLookaside->nMini = (sz - sizeof(LookasideSlot)) / SQLITE_MINI_LOOKASIDE_MIN_SLOT_SIZE;
+ if( pLookaside->nMini ){
+ pLookaside->szMini = ((sz - sizeof(LookasideSlot)) / pLookaside->nMini) & ~(sizeof(void *) - 1);
+ }else{
+ pLookaside->szMini = 0;
+ }
+#endif /* SQLITE_OMIT_MINILOOKASIDE */
+ if( pStart ){
+ int i;
+ LookasideSlot *p;
+ assert( sz > (int)sizeof(LookasideSlot*) );
+ pLookaside->nSlot = cnt;
+ p = (LookasideSlot*)pStart;
+ for(i=cnt-1; i>=0; i--){
+ p->pNext = pLookaside->pInit;
+ pLookaside->pInit = p;
+ p = (LookasideSlot*)&((u8*)p)[sz];
+ }
+ pLookaside->pEnd = p;
+ pLookaside->bDisable = 0;
+ pLookaside->bMalloced = pBuf==0 ?1:0;
+ }else{
+ pLookaside->pStart = 0;
+ pLookaside->pEnd = 0;
+ pLookaside->bDisable = 1;
+ pLookaside->bMalloced = 0;
+ pLookaside->nSlot = 0;
+ }
+ return SQLITE_OK;
+}
+
+void sqlite3LookasideClose(Lookaside *pLookaside){
+ assert( sqlite3LookasideUsed(pLookaside,0)==0 );
+ if( pLookaside->bMalloced ){
+ sqlite3_free(pLookaside->pStart);
+ }
+}
+
+int sqlite3IsLookaside(Lookaside *pLookaside, void *p){
+ return SQLITE_WITHIN(p, pLookaside->pStart, pLookaside->pEnd);
+}
+
+/*
+** Returns a pointer to a region at least n bytes in size, or NULL if the
+** lookaside allocator has exhausted its available memory.
+*/
+void *sqlite3LookasideAlloc(Lookaside *pLookaside, u64 n){
+ if( n>pLookaside->sz ){
+ if( !pLookaside->bDisable ){
+ pLookaside->anStat[1]++;
+ }
+ return 0;
+ }
+ if( n<=pLookaside->szMini && pLookaside->nMini > 1 ){
+ return miniLookasideAlloc(pLookaside, n);
+ }
+ return lookasideSlotAlloc(pLookaside, n);
+}
+
+/*
+** Free memory previously obtained from sqlite3LookasideAlloc().
+*/
+void sqlite3LookasideFree(Lookaside *pLookaside, void *p){
+ assert( sqlite3IsLookaside(pLookaside, p) );
+ if( ((u8*)p - (u8*)pLookaside->pStart) % pLookaside->szTrue == 0 ){
+ lookasideSlotFree(pLookaside, p);
+ }else{
+ miniLookasideFree(pLookaside, p);
+ }
+}
+
+/*
+** Return the size of a memory allocation previously obtained from
+** sqlite3LookasideAlloc().
+*/
+int sqlite3LookasideSize(Lookaside *pLookaside, void *p){
+ assert(sqlite3IsLookaside(pLookaside, p));
+
+# ifndef SQLITE_OMIT_MINI_LOOKASIDE
+ if( ((u8*)p - (u8*)pLookaside->pStart) % pLookaside->szTrue != 0 ){
+ return pLookaside->szMini;
+ }else
+#endif /* SQLITE_OMIT_MINI_LOOKASIDE */
+ {
+ return pLookaside->szTrue;
+ }
+}
+
+#endif /* !SQLITE_OMIT_LOOKASIDE */
--- /dev/null
+/*
+** 2019-10-02
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Header file for the lookaside allocator
+**
+** This header defines the interface to the lookaside allocator.
+** The lookaside allocator implements a two-size memory allocator using a
+** buffer provided at initialization-time to exploit the fact that 75% of
+** SQLite's allocations are <=128B.
+*/
+#ifndef SQLITE_LOOKASIDE_H
+#define SQLITE_LOOKASIDE_H
+
+/*
+** Count the number of slots of lookaside memory that are outstanding
+*/
+int sqlite3LookasideUsed(Lookaside *pLookaside, int *pHighwater);
+
+void sqlite3LookasideResetUsed(Lookaside *pLookaside);
+
+#define sqlite3LookasideDisable(pLookaside) do{(pLookaside)->bDisable++;\
+ (pLookaside)->sz=0;}while(0)
+#define sqlite3LookasideEnable(pLookaside) do{(pLookaside)->bDisable--;\
+ (pLookaside)->sz=(pLookaside)->bDisable?0:(pLookaside)->szTrue;} while(0)
+#define sqlite3LookasideEnableCnt(pLookaside, CNT) do{(pLookaside)->bDisable -= (CNT);\
+ (pLookaside)->sz=(pLookaside)->bDisable?0:(pLookaside)->szTrue;} while(0)
+#define sqlite3LookasideDisabled(pLookaside) ((pLookaside)->bDisable)
+
+# ifndef SQLITE_OMIT_LOOKASIDE
+
+/*
+** Set up a lookaside allocator.
+** Returns SQLITE_OK on success.
+** If lookaside is already active, return SQLITE_BUSY.
+**
+** If pStart is NULL the space for the lookaside memory is obtained from
+** sqlite3_malloc(). If pStart is not NULL then it is sz*cnt bytes of memory
+** to use for the lookaside memory.
+*/
+int sqlite3LookasideOpen(
+ void *pBuf, /* NULL or sz*cnt bytes of memory */
+ int sz, /* Number of bytes in each lookaside slot */
+ int cnt, /* Number of slots */
+ Lookaside *pLookaside /* Preallocated space for the Lookaside */
+);
+
+/* Reset and close the lookaside object */
+void sqlite3LookasideClose(Lookaside *pLookaside);
+
+/*
+** Returns TRUE if p is a lookaside memory allocation from db
+*/
+int sqlite3IsLookaside(Lookaside *pLookaside, void *p);
+
+/*
+** Returns a pointer to a region at least n bytes in size, or NULL if the
+** lookaside allocator has exhausted its available memory.
+*/
+void *sqlite3LookasideAlloc(Lookaside *pLookaside, u64 n);
+
+/*
+** Free memory previously obtained from sqlite3LookasideAlloc().
+*/
+void sqlite3LookasideFree(Lookaside *pLookaside, void *p);
+
+/*
+** Return the size of a memory allocation previously obtained from
+** sqlite3LookasideAlloc().
+*/
+int sqlite3LookasideSize(Lookaside *pLookaside, void *p);
+
+# else
+# define sqlite3LookasideOpen(A, B, C, D) SQLITE_OK
+# define sqlite3LookasideClose(A)
+# define sqlite3IsLookaside(A, B) 0
+# define sqlite3LookasideAlloc(A, B) 0
+# define sqlite3LookasideFree(A, B) assert(0);
+# define sqlite3LookasideSize(A, B) -1
+# endif
+
+#endif /* SQLITE_LOOKASIDE_H */
** accessed by users of the library.
*/
#include "sqliteInt.h"
+#include "lookaside.h"
#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
return rc;
}
-/*
-** Set up the lookaside buffers for a database connection.
-** Return SQLITE_OK on success.
-** If lookaside is already active, return SQLITE_BUSY.
-**
-** The sz parameter is the number of bytes in each lookaside slot.
-** The cnt parameter is the number of slots. If pStart is NULL the
-** space for the lookaside memory is obtained from sqlite3_malloc().
-** If pStart is not NULL then it is sz*cnt bytes of memory to use for
-** the lookaside memory.
-*/
-static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
-#ifndef SQLITE_OMIT_LOOKASIDE
- void *pStart;
-
- if( sqlite3LookasideUsed(db,0)>0 ){
- return SQLITE_BUSY;
- }
- /* Free any existing lookaside buffer for this handle before
- ** allocating a new one so we don't have to have space for
- ** both at the same time.
- */
- if( db->lookaside.bMalloced ){
- sqlite3_free(db->lookaside.pStart);
- }
- /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
- ** than a pointer to be useful.
- */
- sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
- if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
- if( cnt<0 ) cnt = 0;
- if( sz==0 || cnt==0 ){
- sz = 0;
- pStart = 0;
- }else if( pBuf==0 ){
- sqlite3BeginBenignMalloc();
- pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt ); /* IMP: R-61949-35727 */
- sqlite3EndBenignMalloc();
- if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
- }else{
- pStart = pBuf;
- }
- db->lookaside.pStart = pStart;
- db->lookaside.pInit = 0;
- db->lookaside.pFree = 0;
- db->lookaside.sz = (u16)sz;
- db->lookaside.szTrue = (u16)sz;
- if( pStart ){
- int i;
- LookasideSlot *p;
- assert( sz > (int)sizeof(LookasideSlot*) );
- db->lookaside.nSlot = cnt;
- p = (LookasideSlot*)pStart;
- for(i=cnt-1; i>=0; i--){
- p->pNext = db->lookaside.pInit;
- db->lookaside.pInit = p;
- p = (LookasideSlot*)&((u8*)p)[sz];
- }
- db->lookaside.pEnd = p;
- db->lookaside.bDisable = 0;
- db->lookaside.bMalloced = pBuf==0 ?1:0;
- }else{
- db->lookaside.pStart = db;
- db->lookaside.pEnd = db;
- db->lookaside.bDisable = 1;
- db->lookaside.sz = 0;
- db->lookaside.bMalloced = 0;
- db->lookaside.nSlot = 0;
- }
-#endif /* SQLITE_OMIT_LOOKASIDE */
- return SQLITE_OK;
-}
-
/*
** Return the mutex associated with a database connection.
*/
void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
- rc = setupLookaside(db, pBuf, sz, cnt);
+ rc = sqlite3LookasideOpen(pBuf, sz, cnt, &db->lookaside);
break;
}
default: {
sqlite3_mutex_leave(db->mutex);
db->magic = SQLITE_MAGIC_CLOSED;
sqlite3_mutex_free(db->mutex);
- assert( sqlite3LookasideUsed(db,0)==0 );
- if( db->lookaside.bMalloced ){
- sqlite3_free(db->lookaside.pStart);
- }
+ sqlite3LookasideClose(&db->lookaside);
sqlite3_free(db);
}
db->nDb = 2;
db->magic = SQLITE_MAGIC_BUSY;
db->aDb = db->aDbStatic;
- db->lookaside.bDisable = 1;
- db->lookaside.sz = 0;
+ sqlite3LookasideDisable(&db->lookaside);
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
if( rc ) sqlite3Error(db, rc);
/* Enable the lookaside-malloc subsystem */
- setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
- sqlite3GlobalConfig.nLookaside);
+ sqlite3LookasideOpen(0, sqlite3GlobalConfig.szLookaside,
+ sqlite3GlobalConfig.nLookaside, &db->lookaside);
sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);
** Memory allocation functions used throughout sqlite.
*/
#include "sqliteInt.h"
+#include "lookaside.h"
#include <stdarg.h>
/*
return sqlite3Malloc(n);
}
-/*
-** TRUE if p is a lookaside memory allocation from db
-*/
-#ifndef SQLITE_OMIT_LOOKASIDE
-static int isLookaside(sqlite3 *db, void *p){
- return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
-}
-#else
-#define isLookaside(A,B) 0
-#endif
-
/*
** Return the size of a memory allocation previously obtained from
** sqlite3Malloc() or sqlite3_malloc().
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
assert( p!=0 );
- if( db==0 || !isLookaside(db,p) ){
+ if( db==0 || !sqlite3IsLookaside(&db->lookaside,p) ){
#ifdef SQLITE_DEBUG
if( db==0 ){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
return sqlite3GlobalConfig.m.xSize(p);
}else{
assert( sqlite3_mutex_held(db->mutex) );
- return db->lookaside.szTrue;
+ return sqlite3LookasideSize(&db->lookaside, p);
}
}
sqlite3_uint64 sqlite3_msize(void *p){
measureAllocationSize(db, p);
return;
}
- if( isLookaside(db, p) ){
- LookasideSlot *pBuf = (LookasideSlot*)p;
-#ifdef SQLITE_DEBUG
- /* Trash all content in the buffer being freed */
- memset(p, 0xaa, db->lookaside.szTrue);
-#endif
- pBuf->pNext = db->lookaside.pFree;
- db->lookaside.pFree = pBuf;
+ if( sqlite3IsLookaside(&db->lookaside, p) ){
+ sqlite3LookasideFree(&db->lookaside, p);
return;
}
}
static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){
void *p;
assert( db!=0 );
+ if( db->mallocFailed ){ return 0; }
p = sqlite3Malloc(n);
if( !p ) sqlite3OomFault(db);
sqlite3MemdebugSetType(p,
- (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
+ sqlite3LookasideDisabled(&db->lookaside) ? MEMTYPE_HEAP : MEMTYPE_LOOKASIDE);
return p;
}
return p;
}
void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
-#ifndef SQLITE_OMIT_LOOKASIDE
- LookasideSlot *pBuf;
assert( db!=0 );
assert( sqlite3_mutex_held(db->mutex) );
assert( db->pnBytesFreed==0 );
- if( n>db->lookaside.sz ){
- if( db->lookaside.bDisable ){
- return db->mallocFailed ? 0 : dbMallocRawFinish(db, n);
- }
- db->lookaside.anStat[1]++;
- }else if( (pBuf = db->lookaside.pFree)!=0 ){
- db->lookaside.pFree = pBuf->pNext;
- db->lookaside.anStat[0]++;
- return (void*)pBuf;
- }else if( (pBuf = db->lookaside.pInit)!=0 ){
- db->lookaside.pInit = pBuf->pNext;
- db->lookaside.anStat[0]++;
- return (void*)pBuf;
- }else{
- db->lookaside.anStat[2]++;
- }
+#ifndef SQLITE_OMIT_LOOKASIDE
+ return sqlite3LookasideAlloc(&db->lookaside, n) ?: dbMallocRawFinish(db, n);
#else
assert( db!=0 );
assert( sqlite3_mutex_held(db->mutex) );
if( db->mallocFailed ){
return 0;
}
-#endif
return dbMallocRawFinish(db, n);
+#endif
}
/* Forward declaration */
assert( db!=0 );
if( p==0 ) return sqlite3DbMallocRawNN(db, n);
assert( sqlite3_mutex_held(db->mutex) );
- if( isLookaside(db,p) && n<=db->lookaside.szTrue ) return p;
+ if( sqlite3IsLookaside(&db->lookaside,p) && n<=sqlite3LookasideSize(&db->lookaside, p) ) return p;
return dbReallocFinish(db, p, n);
}
static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
assert( db!=0 );
assert( p!=0 );
if( db->mallocFailed==0 ){
- if( isLookaside(db, p) ){
+ if( sqlite3IsLookaside(&db->lookaside,p) ){
pNew = sqlite3DbMallocRawNN(db, n);
if( pNew ){
- memcpy(pNew, p, db->lookaside.szTrue);
+ memcpy(pNew, p, sqlite3LookasideSize(&db->lookaside, p));
sqlite3DbFree(db, p);
}
}else{
if( !pNew ){
sqlite3OomFault(db);
}
- sqlite3MemdebugSetType(pNew,
- (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
+ sqlite3MemdebugSetType(p,
+ sqlite3LookasideDisabled(&db->lookaside) ? MEMTYPE_HEAP : MEMTYPE_LOOKASIDE);
}
}
return pNew;
/*
** Call this routine to record the fact that an OOM (out-of-memory) error
-** has happened. This routine will set db->mallocFailed, and also
-** temporarily disable the lookaside memory allocator and interrupt
+** has happened. This routine will set db->mallocFailed and interrupt
** any running VDBEs.
*/
void sqlite3OomFault(sqlite3 *db){
if( db->nVdbeExec>0 ){
db->u1.isInterrupted = 1;
}
- DisableLookaside;
+ sqlite3LookasideDisable(&db->lookaside);;
if( db->pParse ){
db->pParse->rc = SQLITE_NOMEM_BKPT;
}
if( db->mallocFailed && db->nVdbeExec==0 ){
db->mallocFailed = 0;
db->u1.isInterrupted = 0;
- assert( db->lookaside.bDisable>0 );
+ assert( sqlite3LookasideDisabled(&db->lookaside) );
EnableLookaside;
}
}
//
%include {
#include "sqliteInt.h"
+#include "lookaside.h"
/*
** Disable all error recovery processing in the parser push-down
static void disableLookaside(Parse *pParse){
sqlite3 *db = pParse->db;
pParse->disableLookaside++;
- DisableLookaside;
+ sqlite3LookasideDisable(&db->lookaside);
}
} // end %include
** from disk.
*/
#include "sqliteInt.h"
+#include "lookaside.h"
/*
** Fill the InitData structure with an error message that indicates
sqlite3DbFree(db, pParse->aLabel);
sqlite3ExprListDelete(db, pParse->pConstExpr);
if( db ){
- assert( db->lookaside.bDisable >= pParse->disableLookaside );
- db->lookaside.bDisable -= pParse->disableLookaside;
- db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
+ assert( sqlite3LookasideDisabled(&db->lookaside) >= pParse->disableLookaside );
+ sqlite3LookasideEnableCnt(&db->lookaside, pParse->disableLookaside);
}
pParse->disableLookaside = 0;
}
*/
if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
sParse.disableLookaside++;
- DisableLookaside;
+ sqlite3LookasideDisable(&db->lookaside);
}
sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;
** to handle SELECT statements in SQLite.
*/
#include "sqliteInt.h"
+#include "lookaside.h"
/*
** Trace output macros
LookasideSlot *pFree; /* List of available buffers */
void *pStart; /* First byte of available memory space */
void *pEnd; /* First byte past end of available space */
+#ifndef SQLITE_OMIT_MINILOOKASIDE
+ LookasideSlot *pMini; /* List of buffers used by mini allocator */
+ u16 szMini; /* Size of each mini-allocator buffer in bytes */
+ u16 nMini; /* Number of mini-allocator buffers per slot */
+#endif /* SQLITE_OMIT_MINILOOKASIDE */
};
struct LookasideSlot {
- LookasideSlot *pNext; /* Next buffer in the list of free buffers */
+ LookasideSlot *pNext; /* Next buffer in the list of buffers */
+#ifndef SQLITE_OMIT_MINILOOKASIDE
+ /* The members below are only valid for slots inside the mini-allocator */
+ LookasideSlot *pPrev; /* Previous partially-used buffer in the list */
+ int bMembership; /* Bitfield tracking sub-allocations within slot */
+#endif /* SQLITE_OMIT_MINILOOKASIDE */
};
#define DisableLookaside db->lookaside.bDisable++;db->lookaside.sz=0
void sqlite3StatusUp(int, int);
void sqlite3StatusDown(int, int);
void sqlite3StatusHighwater(int, int);
-int sqlite3LookasideUsed(sqlite3*,int*);
/* Access to mutexes used by sqlite3_status() */
sqlite3_mutex *sqlite3Pcache1Mutex(void);
** functionality.
*/
#include "sqliteInt.h"
+#include "lookaside.h"
#include "vdbeInt.h"
/*
return rc;
}
-/*
-** Return the number of LookasideSlot elements on the linked list
-*/
-static u32 countLookasideSlots(LookasideSlot *p){
- u32 cnt = 0;
- while( p ){
- p = p->pNext;
- cnt++;
- }
- return cnt;
-}
-
-/*
-** Count the number of slots of lookaside memory that are outstanding
-*/
-int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
- u32 nInit = countLookasideSlots(db->lookaside.pInit);
- u32 nFree = countLookasideSlots(db->lookaside.pFree);
- if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit;
- return db->lookaside.nSlot - (nInit+nFree);
-}
-
/*
** Query status information for a single database connection
*/
sqlite3_mutex_enter(db->mutex);
switch( op ){
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
- *pCurrent = sqlite3LookasideUsed(db, pHighwater);
+ *pCurrent = sqlite3LookasideUsed(&db->lookaside, pHighwater);
if( resetFlag ){
- LookasideSlot *p = db->lookaside.pFree;
- if( p ){
- while( p->pNext ) p = p->pNext;
- p->pNext = db->lookaside.pInit;
- db->lookaside.pInit = db->lookaside.pFree;
- db->lookaside.pFree = 0;
- }
+ sqlite3LookasideResetUsed(&db->lookaside);
}
break;
}
hash.h
hwtime.h
keywordhash.h
+ lookaside.h
msvc.h
mutex.h
opcodes.h
os.c
fault.c
+ lookaside.c
mem0.c
mem1.c
mem2.c
hash.h
hwtime.h
keywordhash.h
+ lookaside.h
msvc.h
mutex.h
opcodes.h
os.c
fault.c
+ lookaside.c
mem0.c
mem1.c
mem2.c
hash.h
hwtime.h
keywordhash.h
+ lookaside.h
msvc.h
opcodes.h
os_common.h