From: dan Date: Wed, 14 Mar 2012 12:17:40 +0000 (+0000) Subject: Avoid allocating a large object on the stack in the incremental merge code. Use sqlit... X-Git-Tag: mountain-lion~3^2~9^2~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a2af0aecdb3ccf3dff03034b03cb00ea052dd2fe;p=thirdparty%2Fsqlite.git Avoid allocating a large object on the stack in the incremental merge code. Use sqlite3_malloc() instead. FossilOrigin-Name: 36ae510de45be44efd34cff242d02fb21b7419ac --- diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 3f033361e5..35da283df3 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -25,7 +25,7 @@ #include -#define FTS_MAX_APPENDABLE_HEIGHT 10 +#define FTS_MAX_APPENDABLE_HEIGHT 16 /* ** When full-text index nodes are loaded from disk, the buffer that they @@ -4164,17 +4164,15 @@ static int fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ while( rc==SQLITE_OK && nRem>0 ){ sqlite3_int64 iAbsLevel; /* Absolute level number to work on */ sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ - Fts3MultiSegReader csr; /* Cursor used to read input data */ - Fts3SegFilter filter; /* Filter used with cursor csr */ - IncrmergeWriter writer; /* Writer object */ - - memset(&writer, 0, sizeof(IncrmergeWriter)); + Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ + Fts3SegFilter *pFilter; /* Filter used with cursor pCsr */ + IncrmergeWriter *pWriter; /* Writer object */ + const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); /* Determine which level to merge segments from. Any level, from any ** prefix or language index may be selected. Stack variable iAbsLevel ** is set to the absolute level number of the level to merge from. */ rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); - if( rc!=SQLITE_OK ) return rc; sqlite3_bind_int(pFindLevel, 1, nMin); if( sqlite3_step(pFindLevel)!=SQLITE_ROW ){ return sqlite3_reset(pFindLevel); @@ -4183,35 +4181,41 @@ static int fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ rc = sqlite3_reset(pFindLevel); if( rc!=SQLITE_OK ) return rc; + /* Allocate space for the cursor, filter and writer objects */ + pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc); + if( !pWriter ) return SQLITE_NOMEM; + memset(pWriter, 0, nAlloc); + pFilter = (Fts3SegFilter *)&pWriter[1]; + pCsr = (Fts3MultiSegReader *)&pFilter[1]; + /* Open a cursor to iterate through the contents of indexes 0 and 1 of ** the selected absolute level. */ - rc = fts3IncrmergeCsr(p, iAbsLevel, &csr); - if( rc!=SQLITE_OK ) return rc; - memset(&filter, 0, sizeof(Fts3SegFilter)); - filter.flags = FTS3_SEGMENT_REQUIRE_POS; + pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; + rc = fts3IncrmergeCsr(p, iAbsLevel, pCsr); - rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); - assert( rc!=SQLITE_ABORT ); - if( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ - rc = fts3IncrmergeWriter(p, iAbsLevel, csr.zTerm, csr.nTerm, &writer); - if( rc==SQLITE_OK ){ - do { - rc = fts3IncrmergeAppend(p, &writer, &csr); - if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, &csr); - if( writer.nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; - }while( rc==SQLITE_ROW ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter); + if( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr)) ){ + rc = fts3IncrmergeWriter(p, iAbsLevel, pCsr->zTerm,pCsr->nTerm,pWriter); + if( rc==SQLITE_OK ){ + do { + rc = fts3IncrmergeAppend(p, pWriter, pCsr); + if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); + if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; + }while( rc==SQLITE_ROW ); + } } } - assert( rc!=SQLITE_ABORT ); - fts3IncrmergeRelease(p, &writer, &rc); - nRem -= (1 + writer.nWork); + fts3IncrmergeRelease(p, pWriter, &rc); + nRem -= (1 + pWriter->nWork); /* Update or delete the input segments */ if( rc==SQLITE_OK ){ - rc = fts3IncrmergeChomp(p, iAbsLevel, &csr); + rc = fts3IncrmergeChomp(p, iAbsLevel, pCsr); } - sqlite3Fts3SegReaderFinish(&csr); + sqlite3Fts3SegReaderFinish(pCsr); + sqlite3_free(pWriter); } return rc; diff --git a/manifest b/manifest index 321984d2ab..2ce91db0a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sbug\sin\sthe\sincremental\smerge\scode. -D 2012-03-14T11:51:31.020 +C Avoid\sallocating\sa\slarge\sobject\son\sthe\sstack\sin\sthe\sincremental\smerge\scode.\sUse\ssqlite3_malloc()\sinstead. +D 2012-03-14T12:17:40.405 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -78,7 +78,7 @@ F ext/fts3/fts3_test.c 6b7cc68aef4efb084e1449f7d20c4b20d3bdf6b4 F ext/fts3/fts3_tokenizer.c 3da7254a9881f7e270ab28e2004e0d22b3212bce F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68 F ext/fts3/fts3_tokenizer1.c 0dde8f307b8045565cf63797ba9acfaff1c50c68 -F ext/fts3/fts3_write.c 828b6395666e1e6fba0f762c14a3c5a3c074d7d1 +F ext/fts3/fts3_write.c 772b8c32b93c60b85b60c635de2ff5b3f49fd779 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9 @@ -993,7 +993,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P bff21683705a61b8b8672e0b44c287d1dc7c32a9 -R 9f60203a889705a2753ea10821ad5057 +P f97b12e0955c4c29f9c31a186d72d87f7407782e +R 86bb2bcb41aa5bde569f19117ae756eb U dan -Z 0463fff5f4e61a05ca6743e1edc364a0 +Z da9e601d088fda8ad57ce1fc3070902a diff --git a/manifest.uuid b/manifest.uuid index f29dd9b13a..137182d9b7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f97b12e0955c4c29f9c31a186d72d87f7407782e \ No newline at end of file +36ae510de45be44efd34cff242d02fb21b7419ac \ No newline at end of file