Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Use heap instead of stack for large buffers in the pager. Fix for #2262. (CVS 3673) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
dfe1dffa4515ed6494055887d351863f |
User & Date: | danielk1977 2007-03-06 13:46:00.000 |
Context
2007-03-06
| ||
15:53 | Fixes to the overflow-chain optization of (3672). (CVS 3674) (check-in: d6986d1e7c user: drh tags: trunk) | |
13:46 | Use heap instead of stack for large buffers in the pager. Fix for #2262. (CVS 3673) (check-in: dfe1dffa45 user: danielk1977 tags: trunk) | |
11:42 | Do not read the last page of a overflow chain when deleting that chain. Just add the page to the freelist. This reduces I/O. (CVS 3672) (check-in: 6db945f7a7 user: drh tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.286 2007/03/06 13:46:00 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
280 281 282 283 284 285 286 287 288 289 290 291 292 293 | void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ void *pCodecArg; /* First argument to xCodec() */ int nHash; /* Size of the pager hash table */ PgHdr **aHash; /* Hash table to map page number to PgHdr */ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT Pager *pNext; /* Linked list of pagers in this thread */ #endif }; /* ** If SQLITE_TEST is defined then increment the variable given in ** the argument */ #ifdef SQLITE_TEST | > | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ void *pCodecArg; /* First argument to xCodec() */ int nHash; /* Size of the pager hash table */ PgHdr **aHash; /* Hash table to map page number to PgHdr */ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT Pager *pNext; /* Linked list of pagers in this thread */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ }; /* ** If SQLITE_TEST is defined then increment the variable given in ** the argument */ #ifdef SQLITE_TEST |
︙ | ︙ | |||
994 995 996 997 998 999 1000 | ** need to survive power failures. */ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ int rc; PgHdr *pPg; /* An existing page in the cache */ Pgno pgno; /* The page number of a page in journal */ u32 cksum; /* Checksum used for sanity checking */ | | | | | 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | ** need to survive power failures. */ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ int rc; PgHdr *pPg; /* An existing page in the cache */ Pgno pgno; /* The page number of a page in journal */ u32 cksum; /* Checksum used for sanity checking */ u8 *aData = (u8 *)pPager->pTmpSpace; /* Temp storage for a page */ /* useCksum should be true for the main journal and false for ** statement journals. Verify that this is always the case */ assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) ); assert( aData ); rc = read32bits(jfd, &pgno); if( rc!=SQLITE_OK ) return rc; rc = sqlite3OsRead(jfd, aData, pPager->pageSize); if( rc!=SQLITE_OK ) return rc; pPager->journalOff += pPager->pageSize + 4; /* Sanity checking on the page. This is more important that I originally ** thought. If a power failure occurs while the journal is being written, ** it could cause invalid data to be written into the journal. We need to ** detect this invalid data (with high probability) and ignore it. |
︙ | ︙ | |||
1183 1184 1185 1186 1187 1188 1189 | ** cache content and the easiest way to do that is to reread the old content ** back from the disk. */ static int pager_reload_cache(Pager *pPager){ PgHdr *pPg; int rc = SQLITE_OK; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ | | | 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 | ** cache content and the easiest way to do that is to reread the old content ** back from the disk. */ static int pager_reload_cache(Pager *pPager){ PgHdr *pPg; int rc = SQLITE_OK; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ char *zBuf = pPager->pTmpSpace; /* Temp storage for one page */ if( !pPg->dirty ) continue; if( (int)pPg->pgno <= pPager->origDbSize ){ rc = sqlite3OsSeek(pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1)); if( rc==SQLITE_OK ){ rc = sqlite3OsRead(pPager->fd, zBuf, pPager->pageSize); } TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno); |
︙ | ︙ | |||
1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 | /* Allocate the Pager structure. As part of the same allocation, allocate ** space for the full paths of the file, directory and journal ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal). */ if( zFullPathname ){ nameLen = strlen(zFullPathname); pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 ); } /* If an error occured in either of the blocks above, free the memory ** pointed to by zFullPathname, free the Pager structure and close the ** file. Since the pager is not allocated there is no need to set ** any Pager.errMask variables. */ | > > > > | | 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 | /* Allocate the Pager structure. As part of the same allocation, allocate ** space for the full paths of the file, directory and journal ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal). */ if( zFullPathname ){ nameLen = strlen(zFullPathname); pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 ); if( pPager && rc==SQLITE_OK ){ pPager->pTmpSpace = (char *)sqliteMallocRaw(SQLITE_DEFAULT_PAGE_SIZE); } } /* If an error occured in either of the blocks above, free the memory ** pointed to by zFullPathname, free the Pager structure and close the ** file. Since the pager is not allocated there is no need to set ** any Pager.errMask variables. */ if( !pPager || !zFullPathname || !pPager->pTmpSpace || rc!=SQLITE_OK ){ sqlite3OsClose(&fd); sqliteFree(zFullPathname); sqliteFree(pPager); return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc); } TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname); |
︙ | ︙ | |||
1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 | ** size is inappropriate, then an alternative page size is selected ** and returned. */ int sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ); if( !pPager->memDb ){ pPager->pageSize = pageSize; } return pPager->pageSize; } /* ** The following set of routines are used to disable the simulated ** I/O error mechanism. These routines are used to avoid simulated | > | 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 | ** size is inappropriate, then an alternative page size is selected ** and returned. */ int sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ); if( !pPager->memDb ){ pPager->pageSize = pageSize; sqlite3ReallocOrFree((void **)&pPager->pTmpSpace, pageSize); } return pPager->pageSize; } /* ** The following set of routines are used to disable the simulated ** I/O error mechanism. These routines are used to avoid simulated |
︙ | ︙ | |||
2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 | }else{ Pager *pTmp; for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext){} pTmp->pNext = pPager->pNext; } #endif sqliteFree(pPager->aHash); sqliteFree(pPager); return SQLITE_OK; } /* ** Return the page number for the given page data. */ | > | 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 | }else{ Pager *pTmp; for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext){} pTmp->pNext = pPager->pNext; } #endif sqliteFree(pPager->aHash); sqliteFree(pPager->pTmpSpace); sqliteFree(pPager); return SQLITE_OK; } /* ** Return the page number for the given page data. */ |
︙ | ︙ |