Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Consolidate two blocks of similar code in btreeFixUnlocked(). |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | begin-concurrent |
Files: | files | file ages | folders |
SHA1: |
701302b4bd62ca7aefe643eac096a0ee |
User & Date: | dan 2015-08-24 10:05:03.012 |
Context
2015-08-24
| ||
16:00 | Fix compilation without SQLITE_ENABLE_UNLOCKED. Also other code organization issues. (check-in: 0411355754 user: dan tags: begin-concurrent) | |
10:05 | Consolidate two blocks of similar code in btreeFixUnlocked(). (check-in: 701302b4bd user: dan tags: begin-concurrent) | |
06:44 | Merge trunk changes with this branch. (check-in: 876810c28b user: dan tags: begin-concurrent) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 | } #else /* ifndef SQLITE_OMIT_AUTOVACUUM */ # define setChildPtrmaps(x) SQLITE_OK #endif #ifdef SQLITE_ENABLE_UNLOCKED /* ** The b-tree handle passed as the only argument is about to commit an ** UNLOCKED transaction. At this point it is guaranteed that this is ** possible - the wal WRITER lock is held and it is known that there are ** no conflicts with committed transactions. */ static int btreeFixUnlocked(Btree *p){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 | } #else /* ifndef SQLITE_OMIT_AUTOVACUUM */ # define setChildPtrmaps(x) SQLITE_OK #endif #ifdef SQLITE_ENABLE_UNLOCKED /* ** This function is called as part of merging an UNLOCKED transaction with ** the snapshot at the head of the wal file. It relocates all pages in the ** range iFirst..iLast, inclusive. It is assumed that the BtreePtrmap ** structure at BtShared.pMap contains the location of the pointers to each ** page in the range. ** ** If pnCurrent is NULL, then all pages in the range are moved to currently ** free locations (i.e. free-list entries) within the database file before page ** iFirst. ** ** Or, if pnCurrent is not NULL, then it points to a value containing the ** current size of the database file in pages. In this case, all pages are ** relocated to the end of the database file - page iFirst is relocated to ** page (*pnCurrent+1), page iFirst+1 to page (*pnCurrent+2), and so on. ** Value *pnCurrent is set to the new size of the database before this ** function returns. ** ** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error code. */ static int btreeRelocateRange( BtShared *pBt, /* B-tree handle */ Pgno iFirst, /* First page to relocate */ Pgno iLast, /* Last page to relocate */ Pgno *pnCurrent /* If not NULL, IN/OUT: Database size */ ){ int rc = SQLITE_OK; BtreePtrmap *pMap = pBt->pMap; Pgno iPg; for(iPg=iFirst; iPg<=iLast && rc==SQLITE_OK; iPg++){ MemPage *pFree = 0; /* Page allocated from free-list */ MemPage *pPg = 0; Pgno iNew; /* New page number for pPg */ PtrmapEntry *pEntry; /* Pointer map entry for page iPg */ if( iPg==PENDING_BYTE_PAGE(pBt) ) continue; pEntry = &pMap->aPtr[iPg - pMap->iFirst]; if( pEntry->eType==PTRMAP_FREEPAGE ){ Pgno dummy; rc = allocateBtreePage(pBt, &pFree, &dummy, iPg, BTALLOC_EXACT); releasePage(pFree); assert( rc!=SQLITE_OK || dummy==iPg ); }else if( pnCurrent ){ btreeGetPage(pBt, iPg, &pPg, 0); assert( sqlite3PagerIswriteable(pPg->pDbPage) ); assert( sqlite3PagerPageRefcount(pPg->pDbPage)==1 ); iNew = ++(*pnCurrent); if( iNew==PENDING_BYTE_PAGE(pBt) ) iNew = ++(*pnCurrent); rc = relocatePage(pBt, pPg, pEntry->eType, pEntry->parent, iNew, 1); releasePageNotNull(pPg); }else{ rc = allocateBtreePage(pBt, &pFree, &iNew, iFirst-1, BTALLOC_LE); assert( rc!=SQLITE_OK || iNew<iFirst ); releasePage(pFree); if( rc==SQLITE_OK ){ MemPage *pPg = 0; btreeGetPage(pBt, iPg, &pPg, 0); rc = relocatePage(pBt, pPg, pEntry->eType, pEntry->parent,iNew,1); releasePage(pPg); } } } return rc; } /* ** The b-tree handle passed as the only argument is about to commit an ** UNLOCKED transaction. At this point it is guaranteed that this is ** possible - the wal WRITER lock is held and it is known that there are ** no conflicts with committed transactions. */ static int btreeFixUnlocked(Btree *p){ |
︙ | ︙ | |||
3871 3872 3873 3874 3875 3876 3877 | assert( sqlite3PagerIsUnlocked(pPager) ); assert( pBt->pMap ); rc = sqlite3PagerUpgradeSnapshot(pPager, pPage1->pDbPage); assert( p1==pPage1->aData ); if( rc==SQLITE_OK ){ Pgno nHPage = get4byte(&p1[28]); | | | 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 | assert( sqlite3PagerIsUnlocked(pPager) ); assert( pBt->pMap ); rc = sqlite3PagerUpgradeSnapshot(pPager, pPage1->pDbPage); assert( p1==pPage1->aData ); if( rc==SQLITE_OK ){ Pgno nHPage = get4byte(&p1[28]); Pgno nFin = nHPage; /* Size of db after transaction merge */ if( sqlite3PagerIswriteable(pPage1->pDbPage) ){ Pgno iHTrunk = get4byte(&p1[32]); u32 nHFree = get4byte(&p1[36]); /* Attach the head database free list to the end of the current ** transactions free-list (if any). */ |
︙ | ︙ | |||
3903 3904 3905 3906 3907 3908 3909 | ** not have shrunk since the transaction was opened. Therefore nHPage ** should be set to (pMap->iFirst-1) or greater. */ rc = SQLITE_CORRUPT_BKPT; }else{ /* The current transaction allocated pages pMap->iFirst through ** nPage (inclusive) at the end of the database file. Meanwhile, ** other transactions have allocated (iFirst..nHPage). So move | | < < > < | | | | | < < < < < < | < < < < < < < < < < < | | | | | | | | < < < < | < < < < < < < < < < < < < < | < < | | | 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 | ** not have shrunk since the transaction was opened. Therefore nHPage ** should be set to (pMap->iFirst-1) or greater. */ rc = SQLITE_CORRUPT_BKPT; }else{ /* The current transaction allocated pages pMap->iFirst through ** nPage (inclusive) at the end of the database file. Meanwhile, ** other transactions have allocated (iFirst..nHPage). So move ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). */ Pgno iLast = MIN(nPage, nHPage); /* Last page to move */ Pgno nCurrent; /* Current size of db */ nCurrent = MAX(nPage, nHPage); rc = btreeRelocateRange(pBt, pMap->iFirst, iLast, &nCurrent); /* There are now no collisions with the snapshot at the head of the ** database file. So at this point it would be possible to write ** the transaction out to disk. Before doing so though, attempt to ** relocate some of the new pages to free locations within the body ** of the database file (i.e. free-list entries). */ if( rc==SQLITE_OK ){ assert( nCurrent!=PENDING_BYTE_PAGE(pBt) ); sqlite3PagerSetDbsize(pBt->pPager, nCurrent); nFree = get4byte(&p1[36]); nFin = MAX(nCurrent-nFree, nHPage); if( nCurrent>PENDING_BYTE_PAGE(pBt) && nFin<=PENDING_BYTE_PAGE(pBt) ){ nFin--; } rc = btreeRelocateRange(pBt, nFin+1, nCurrent, 0); } put4byte(&p1[28], nFin); } } sqlite3PagerSetDbsize(pPager, nFin); } return rc; } #endif /* |
︙ | ︙ |
Changes to test/unlocked3.test.
︙ | ︙ | |||
80 81 82 83 84 85 86 | } set DBLIST {db1 db2 db3 db4} create_schema foreach {tn oplist} { | | | | | | | | | | | | > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | } set DBLIST {db1 db2 db3 db4} create_schema foreach {tn oplist} { 1 {1i 2i 3i 4i} 2 {1iii 2iii 3iii 4iii} 3 {1d 2d 3d 4d} . ----------------------- 4 {1i} 5 {1d 2i} . ----------------------- 6 {1iii 2iii 3iii 4iii} 7 {1di 2id 3iii 4ddd} 8 {1iii 2iii 3iii 4iii} 9 {1D 2II} 10 {1I 2D 3I 4D} 11 {1III 3dddddd 4III} } { if {[string range $oplist 0 0]=="-"} { reset_db create_schema continue } foreach db $DBLIST { sqlite3 $db test.db } |
︙ | ︙ |