-C Reinsert\scode\sdeleted\sby\s(1998)\sthat\swe\sthought\swas\sunused\sbut\swas\sin\sfact\r\nneeded.\s\sFix\sfor\sticket\s#966.\s(CVS\s2025)
-D 2004-10-19T16:40:59
+C Fix\salignment\sproblems\sin\sbtree\sand\spager\sand\sallow\spage\ssizes\sthat\sare\nnot\sa\smultiple\sof\s8.\s(CVS\s2026)
+D 2004-10-22T16:22:58
F Makefile.in 52c1cc106cad9148d4b7cb387b458e82dc86b339
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
-F src/btree.c bb3f8cadf65cc0752d07e219733a496c1aebe020
+F src/btree.c d8426846c0db61c97a0e3e11531781be7a96f1bc
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
F src/build.c cb0232e0f239d7cea8598d982039b99259074f64
F src/date.c 34bdb0082db7ec2a83ef00063f7b44e61ee19dad
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c dc0ffab9941393b072e0b1f1f3de54830727cec9
+F src/pager.c cc2e7fb3d7913862d7b1170f923d2dcfdbac3bed
F src/pager.h 774d1973acbda341827d21b0da0150575d69f7d9
F src/parse.y 8d97a91cba7e35b5eaac064c9f6e597dc6442b29
F src/pragma.c 3134201e4d47be04b9fcd437e01eab682ad3a096
F test/pager.test 394455707a079804e8a4e431d12edce831a065f0
F test/pager2.test c7e731ac56a2984a605b032ffd19b9deee820377
F test/pager3.test 16f546293bb751b8151dc17df613fca938bbec8b
-F test/pagesize.test f8b46ec46b9fe9f708a8d757dda232588dfb7217
+F test/pagesize.test 56d11f4d6df9949d646bf87da1d6d995ed37cd78
F test/pragma.test 66a66b7f3b273b93325c9a5794acb418f52fdcbf
F test/printf.test 92ba4c510b4fc61120ffa4a01820446ed917ae57
F test/progress.test 5ddba78cb6011fba36093973cfb3ac473b8fb96a x
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
-P 55b03c560d2f66c55d64c3e9f9577e33f8c63195
-R 462557c854f7b30b37ca39ec9dc0db3d
+P 370ca539506a431dbe77dcb644215886760f34e9
+R 3144c4632ba02236b46866a5c5939839
U drh
-Z e8f25bd39be0085dd77f02f0608ae8de
+Z fbdbb4c36ca4011ce6bdf20082c190a3
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.192 2004/10/05 02:41:42 drh Exp $
+** $Id: btree.c,v 1.193 2004/10/22 16:22:58 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
#include "os.h"
#include <assert.h>
+/*
+** This macro rounds values up so that if the value is an address it
+** is guaranteed to be an address that is aligned to an 8-byte boundary.
+*/
+#define FORCE_ALIGNMENT(X) (((X)+7)&~7)
/* The following value is the maximum cell size assuming a maximum page
** size give above.
u8 minLeafFrac; /* Minimum leaf payload as % of total page size */
u8 pageSizeFixed; /* True if the page size can no longer be changed */
u16 pageSize; /* Total number of bytes on a page */
+ u16 psAligned; /* pageSize rounded up to a multiple of 8 */
u16 usableSize; /* Number of usable bytes on each page */
int maxLocal; /* Maximum local payload in non-LEAFDATA tables */
int minLocal; /* Minimum local payload in non-LEAFDATA tables */
used = sqliteMallocRaw( pPage->pBt->pageSize );
if( used==0 ) return;
usableSize = pPage->pBt->usableSize;
- assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] );
+ assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->psAligned] );
hdr = pPage->hdrOffset;
assert( hdr==(pPage->pgno==1 ? 100 : 0) );
assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
assert( pBt!=0 );
assert( pParent==0 || pParent->pBt==pBt );
assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
- assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] );
+ assert( pPage->aData == &((unsigned char*)pPage)[-pBt->psAligned] );
if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
/* The parent page should never change unless the file is corrupt */
return SQLITE_CORRUPT; /* bkpt-CORRUPT */
int first;
assert( sqlite3pager_pagenumber(data)==pPage->pgno );
- assert( &data[pBt->pageSize] == (unsigned char*)pPage );
+ assert( &data[pBt->psAligned] == (unsigned char*)pPage );
assert( sqlite3pager_iswriteable(data) );
memset(&data[hdr], 0, pBt->usableSize - hdr);
data[hdr] = flags;
MemPage *pPage;
rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData);
if( rc ) return rc;
- pPage = (MemPage*)&aData[pBt->pageSize];
+ pPage = (MemPage*)&aData[pBt->psAligned];
pPage->aData = aData;
pPage->pBt = pBt;
pPage->pgno = pgno;
if( pPage ){
assert( pPage->aData );
assert( pPage->pBt );
- assert( &pPage->aData[pPage->pBt->pageSize]==(unsigned char*)pPage );
+ assert( &pPage->aData[pPage->pBt->psAligned]==(unsigned char*)pPage );
sqlite3pager_unref(pPage->aData);
}
}
** happens.
*/
static void pageDestructor(void *pData, int pageSize){
- MemPage *pPage = (MemPage*)&((char*)pData)[pageSize];
+ MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)];
if( pPage->pParent ){
MemPage *pParent = pPage->pParent;
pPage->pParent = 0;
** page to agree with the restored data.
*/
static void pageReinit(void *pData, int pageSize){
- MemPage *pPage = (MemPage*)&((char*)pData)[pageSize];
+ MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)];
if( pPage->isInit ){
pPage->isInit = 0;
initPage(pPage, pPage->pParent);
pBt->pageSizeFixed = 1;
}
pBt->usableSize = pBt->pageSize - nReserve;
+ pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize);
sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);
*ppBtree = pBt;
return SQLITE_OK;
}
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ){
pBt->pageSize = pageSize;
+ pBt->psAligned = FORCE_ALIGNMENT(pageSize);
sqlite3pager_set_pagesize(pBt->pPager, pageSize);
}
pBt->usableSize = pBt->pageSize - nReserve;
if( pBt->usableSize<500 ){
goto page1_init_failed;
}
+ pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize);
pBt->maxEmbedFrac = page1[21];
pBt->minEmbedFrac = page1[22];
pBt->minLeafFrac = page1[23];
if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
if( pBt->pPage1->aData==0 ){
MemPage *pPage = pBt->pPage1;
- pPage->aData = &((char*)pPage)[-pBt->pageSize];
+ pPage->aData = &((char*)pPage)[-pBt->psAligned];
pPage->pBt = pBt;
pPage->pgno = 1;
}
assert( pBt->pPager!=0 );
aData = sqlite3pager_lookup(pBt->pPager, pgno);
if( aData ){
- pThis = (MemPage*)&aData[pBt->pageSize];
+ pThis = (MemPage*)&aData[pBt->psAligned];
assert( pThis->aData==aData );
if( pThis->isInit ){
if( pThis->pParent!=pNewParent ){
apCell = sqliteMallocRaw(
(mxCellPerPage+2)*NB*(sizeof(u8*)+sizeof(int))
+ sizeof(MemPage)*NB
- + pBt->pageSize*(5+NB)
+ + pBt->psAligned*(5+NB)
);
if( apCell==0 ){
return SQLITE_NOMEM;
szCell = (int*)&apCell[(mxCellPerPage+2)*NB];
aCopy[0] = (u8*)&szCell[(mxCellPerPage+2)*NB];
for(i=1; i<NB; i++){
- aCopy[i] = &aCopy[i-1][pBt->pageSize+sizeof(MemPage)];
+ aCopy[i] = &aCopy[i-1][pBt->psAligned+sizeof(MemPage)];
}
- aSpace = &aCopy[NB-1][pBt->pageSize+sizeof(MemPage)];
+ aSpace = &aCopy[NB-1][pBt->psAligned+sizeof(MemPage)];
/*
** Find the cell in the parent page whose left child points back
** process of being overwritten.
*/
for(i=0; i<nOld; i++){
- MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->pageSize];
- p->aData = &((u8*)p)[-pBt->pageSize];
- memcpy(p->aData, apOld[i]->aData, pBt->pageSize + sizeof(MemPage));
- p->aData = &((u8*)p)[-pBt->pageSize];
+ MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->psAligned];
+ p->aData = &((u8*)p)[-pBt->psAligned];
+ memcpy(p->aData, apOld[i]->aData, pBt->psAligned + sizeof(MemPage));
+ p->aData = &((u8*)p)[-pBt->psAligned];
}
/*
szCell[nCell] = sz;
pTemp = &aSpace[iSpace];
iSpace += sz;
- assert( iSpace<=pBt->pageSize*5 );
+ assert( iSpace<=pBt->psAligned*5 );
memcpy(pTemp, apDiv[i], sz);
apCell[nCell] = pTemp+leafCorrection;
dropCell(pParent, nxDiv, sz);
pCell = &aSpace[iSpace];
fillInCell(pParent, pCell, 0, info.nKey, 0, 0, &sz);
iSpace += sz;
- assert( iSpace<=pBt->pageSize*5 );
+ assert( iSpace<=pBt->psAligned*5 );
pTemp = 0;
}else{
pCell -= 4;
pTemp = &aSpace[iSpace];
iSpace += sz;
- assert( iSpace<=pBt->pageSize*5 );
+ assert( iSpace<=pBt->psAligned*5 );
}
insertCell(pParent, nxDiv, pCell, sz, pTemp);
put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.167 2004/10/05 02:41:43 drh Exp $
+** @(#) $Id: pager.c,v 1.168 2004/10/22 16:22:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
# define SQLITE_BUSY_RESERVED_LOCK 0
#endif
+/*
+** This macro rounds values up so that if the value is an address it
+** is guaranteed to be an address that is aligned to an 8-byte boundary.
+*/
+#define FORCE_ALIGNMENT(X) (((X)+7)&~7)
+
/*
** Each in-memory image of a page begins with the following header.
** This header is only visible to this pager module. The client
u8 alwaysRollback; /* Disable dont_rollback() for this page */
short int nRef; /* Number of users of this page */
PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */
- /* pPager->pageSize bytes of page data follow this header */
+ /* pPager->psAligned bytes of page data follow this header */
/* Pager.nExtra bytes of local data follow the page data */
};
*/
#define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
-#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->pageSize])
+#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->psAligned])
#define PGHDR_TO_HIST(P,PGR) \
- ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra])
+ ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->psAligned+(PGR)->nExtra])
/*
** How big to make the hash table used for locating in-memory pages
void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
void (*xReiniter)(void*,int); /* Call this routine when reloading pages */
int pageSize; /* Number of bytes in a page */
+ int psAligned; /* pageSize rounded up to a multiple of 8 */
int nPage; /* Total number of in-memory pages */
int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
int mxPage; /* Maximum number of pages to hold in cache */
pPager->nRef = 0;
pPager->dbSize = memDb-1;
pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
+ pPager->psAligned = FORCE_ALIGNMENT(pPager->pageSize);
pPager->stmtSize = 0;
pPager->stmtJSize = 0;
pPager->nPage = 0;
pPager->pFirst = 0;
pPager->pFirstSynced = 0;
pPager->pLast = 0;
- pPager->nExtra = nExtra;
+ pPager->nExtra = FORCE_ALIGNMENT(nExtra);
pPager->sectorSize = PAGER_SECTOR_SIZE;
pPager->pBusyHandler = 0;
memset(pPager->aHash, 0, sizeof(pPager->aHash));
void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
pPager->pageSize = pageSize;
+ pPager->psAligned = FORCE_ALIGNMENT(pageSize);
}
/*
pPager->nMiss++;
if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || pPager->memDb ){
/* Create a new page */
- pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
+ pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->psAligned
+ sizeof(u32) + pPager->nExtra
+ pPager->memDb*sizeof(PgHistory) );
if( pPg==0 ){