diff options
author | dan <dan@noemail.net> | 2011-10-08 14:57:07 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2011-10-08 14:57:07 +0000 |
commit | f4ba1093568851a1320a84ce195b1dc08e8964c1 (patch) | |
tree | b5f9d8ead01e28d393e847dafef0559911847c01 /src | |
parent | 08ccfaa1b183a7b365f0576d1aac0a5d8f66d755 (diff) | |
download | sqlite-f4ba1093568851a1320a84ce195b1dc08e8964c1.tar.gz sqlite-f4ba1093568851a1320a84ce195b1dc08e8964c1.zip |
Add the SQLITE_DIRECT_OVERFLOW_READ compile time option.
FossilOrigin-Name: 2ab14a846727857175eac7961b7338c4d3b417ca
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 58 | ||||
-rw-r--r-- | src/test_config.c | 6 |
2 files changed, 52 insertions, 12 deletions
diff --git a/src/btree.c b/src/btree.c index 7e6e02f14..72d61cc26 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3938,21 +3938,55 @@ static int accessPayload( /* Need to read this page properly. It contains some of the ** range of data that is being read (eOp==0) or written (eOp!=0). */ - DbPage *pDbPage; +#ifdef SQLITE_DIRECT_OVERFLOW_READ + sqlite3_file *fd; +#endif int a = amt; - rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage); - if( rc==SQLITE_OK ){ - aPayload = sqlite3PagerGetData(pDbPage); - nextPage = get4byte(aPayload); - if( a + offset > ovflSize ){ - a = ovflSize - offset; + if( a + offset > ovflSize ){ + a = ovflSize - offset; + } + +#ifdef SQLITE_DIRECT_OVERFLOW_READ + /* If all the following are true: + ** + ** 1) this is a read operation, and + ** 2) data is required from the start of this overflow page, and + ** 3) the database is file-backed, and + ** 4) there is no open write-transaction, and + ** 5) the database is not a WAL database, + ** + ** then data can be read directly from the database file into the + ** output buffer, bypassing the page-cache altogether. This speeds + ** up loading large records that span many overflow pages. + */ + if( eOp==0 /* (1) */ + && offset==0 /* (2) */ + && pBt->inTransaction==TRANS_READ /* (4) */ + && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ + && pBt->pPage1->aData[19]==0x01 /* (5) */ + ){ + u8 aSave[4]; + u8 *aWrite = &pBuf[-4]; + memcpy(aSave, aWrite, 4); + rc = sqlite3OsRead(fd, aWrite, a+4, pBt->pageSize * (nextPage-1)); + nextPage = get4byte(aWrite); + memcpy(aWrite, aSave, 4); + }else +#endif + + { + DbPage *pDbPage; + rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage); + if( rc==SQLITE_OK ){ + aPayload = sqlite3PagerGetData(pDbPage); + nextPage = get4byte(aPayload); + rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); + sqlite3PagerUnref(pDbPage); + offset = 0; } - rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); - sqlite3PagerUnref(pDbPage); - offset = 0; - amt -= a; - pBuf += a; } + amt -= a; + pBuf += a; } } } diff --git a/src/test_config.c b/src/test_config.c index 4c4dfa3d8..b0efe2324 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -55,6 +55,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "debug", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_DIRECT_OVERFLOW_READ + Tcl_SetVar2(interp, "sqlite_options", "direct_read", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "direct_read", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_DISABLE_DIRSYNC Tcl_SetVar2(interp, "sqlite_options", "dirsync", "0", TCL_GLOBAL_ONLY); #else |