mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Combine the internal btree functions BtreePutData() and getPayload(). (CVS 3901)
FossilOrigin-Name: a100a5304b0e7cbbdb6dac71a39c78eb71d44a03
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
|||||||
C More\sfixes\sand\simprovements\sto\sthe\szeroblob()\smechanism.\s(CVS\s3900)
|
C Combine\sthe\sinternal\sbtree\sfunctions\sBtreePutData()\sand\sgetPayload().\s(CVS\s3901)
|
||||||
D 2007-05-02T16:51:59
|
D 2007-05-02T17:48:46
|
||||||
F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
|
F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
|
||||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -59,7 +59,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
|
|||||||
F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
|
F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
|
||||||
F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
|
F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
|
||||||
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
|
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
|
||||||
F src/btree.c 4efb50fa388aa1678eb9cce5e5fc6fa8247406b2
|
F src/btree.c ecd0a02c8f867509b5439379208f0ee4d801389e
|
||||||
F src/btree.h 2c187d60cf76d74c2b4767294d6b5fa267037ff0
|
F src/btree.h 2c187d60cf76d74c2b4767294d6b5fa267037ff0
|
||||||
F src/build.c 02e01ec7907c7d947ab3041fda0e81eaed05db42
|
F src/build.c 02e01ec7907c7d947ab3041fda0e81eaed05db42
|
||||||
F src/callback.c 6414ed32d55859d0f65067aa5b88d2da27b3af9e
|
F src/callback.c 6414ed32d55859d0f65067aa5b88d2da27b3af9e
|
||||||
@@ -471,7 +471,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P 349f1ea7895f06c40affc985a13aa6686dfdea07
|
P 83ab25014e890b1cc6ea08ca1ebeeee0078da466
|
||||||
R c40994429188bdd3545336b5231dc204
|
R 6382007c866ff2246040af323c0a9f53
|
||||||
U drh
|
U danielk1977
|
||||||
Z 278e5bf758bcf3f514d6f2d4595a443f
|
Z 54f827912c39196d14fa4e08648aa7ab
|
||||||
|
@@ -1 +1 @@
|
|||||||
83ab25014e890b1cc6ea08ca1ebeeee0078da466
|
a100a5304b0e7cbbdb6dac71a39c78eb71d44a03
|
144
src/btree.c
144
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.366 2007/05/02 16:48:37 danielk1977 Exp $
|
** $Id: btree.c,v 1.367 2007/05/02 17:48:46 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** For a detailed discussion of BTrees, refer to
|
||||||
@@ -3139,20 +3139,28 @@ static int getOverflowPage(
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Read payload information from the entry that the pCur cursor is
|
** This function is used to read or overwrite payload information
|
||||||
** pointing to. Begin reading the payload at "offset" and read
|
** for the entry that the pCur cursor is pointing to. If the eOp
|
||||||
** a total of "amt" bytes. Put the result in zBuf.
|
** parameter is 0, this is a read operation (data copied into
|
||||||
|
** buffer pBuf). If it is non-zero, a write (data copied from
|
||||||
|
** buffer pBuf).
|
||||||
|
**
|
||||||
|
** A total of "amt" bytes are read or written beginning at "offset".
|
||||||
|
** Data is read to or from the buffer pBuf.
|
||||||
**
|
**
|
||||||
** This routine does not make a distinction between key and data.
|
** This routine does not make a distinction between key and data.
|
||||||
** It just reads bytes from the payload area. Data might appear
|
** It just reads or writes bytes from the payload area. Data might
|
||||||
** on the main page or be scattered out on multiple overflow pages.
|
** appear on the main page or be scattered out on multiple overflow
|
||||||
|
** pages.
|
||||||
*/
|
*/
|
||||||
static int getPayload(
|
#define getPayload(a,b,c,d,e) accessPayload(a,b,c,d,e,0)
|
||||||
|
static int accessPayload(
|
||||||
BtCursor *pCur, /* Cursor pointing to entry to read from */
|
BtCursor *pCur, /* Cursor pointing to entry to read from */
|
||||||
int offset, /* Begin reading this far into payload */
|
int offset, /* Begin reading this far into payload */
|
||||||
int amt, /* Read this many bytes */
|
int amt, /* Read this many bytes */
|
||||||
unsigned char *pBuf, /* Write the bytes into this buffer */
|
unsigned char *pBuf, /* Write the bytes into this buffer */
|
||||||
int skipKey /* offset begins at data if this is true */
|
int skipKey, /* offset begins at data if this is true */
|
||||||
|
int eOp /* zero to read. non-zero to write. */
|
||||||
){
|
){
|
||||||
unsigned char *aPayload;
|
unsigned char *aPayload;
|
||||||
Pgno nextPage;
|
Pgno nextPage;
|
||||||
@@ -3187,7 +3195,17 @@ static int getPayload(
|
|||||||
if( a+offset>pCur->info.nLocal ){
|
if( a+offset>pCur->info.nLocal ){
|
||||||
a = pCur->info.nLocal - offset;
|
a = pCur->info.nLocal - offset;
|
||||||
}
|
}
|
||||||
memcpy(pBuf, &aPayload[offset], a);
|
if( eOp ){
|
||||||
|
/* A write operation. */
|
||||||
|
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
memcpy(&aPayload[offset], pBuf, a);
|
||||||
|
}else{
|
||||||
|
/* A read operation */
|
||||||
|
memcpy(pBuf, &aPayload[offset], a);
|
||||||
|
}
|
||||||
if( a==amt ){
|
if( a==amt ){
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@@ -3232,8 +3250,8 @@ static int getPayload(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}else{
|
}else{
|
||||||
/* Need to read this page properly, to obtain data to copy into
|
/* Need to read this page properly. It contains some of the
|
||||||
** the caller's buffer.
|
** range of data that is being read (eOp==0) or written (eOp!=0).
|
||||||
*/
|
*/
|
||||||
DbPage *pDbPage;
|
DbPage *pDbPage;
|
||||||
int a = amt;
|
int a = amt;
|
||||||
@@ -3246,7 +3264,18 @@ static int getPayload(
|
|||||||
if( a + offset > ovflSize ){
|
if( a + offset > ovflSize ){
|
||||||
a = ovflSize - offset;
|
a = ovflSize - offset;
|
||||||
}
|
}
|
||||||
memcpy(pBuf, &aPayload[offset+4], a);
|
if( eOp ){
|
||||||
|
/* A write operation. */
|
||||||
|
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqlite3PagerUnref(pDbPage);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
memcpy(&aPayload[offset+4], pBuf, a);
|
||||||
|
}else{
|
||||||
|
/* A read operation */
|
||||||
|
memcpy(pBuf, &aPayload[offset+4], a);
|
||||||
|
}
|
||||||
offset = 0;
|
offset = 0;
|
||||||
amt -= a;
|
amt -= a;
|
||||||
pBuf += a;
|
pBuf += a;
|
||||||
@@ -6942,7 +6971,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, const void *z){
|
|||||||
** (d) the cursor points at a valid row of an intKey table.
|
** (d) the cursor points at a valid row of an intKey table.
|
||||||
*/
|
*/
|
||||||
if( pBt->inTransaction!=TRANS_WRITE ){
|
if( pBt->inTransaction!=TRANS_WRITE ){
|
||||||
/* Must start a transaction before doing an insert */
|
/* Must start a transaction before writing to a blob */
|
||||||
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
assert( !pBt->readOnly );
|
assert( !pBt->readOnly );
|
||||||
@@ -6956,94 +6985,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, const void *z){
|
|||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the cell-info. Check that the cell-data area is large
|
return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1);
|
||||||
** enough for the proposed write operation.
|
|
||||||
*/
|
|
||||||
getCellInfo(pCsr);
|
|
||||||
pInfo = &pCsr->info;
|
|
||||||
if( pInfo->nData<(offset+amt) ){
|
|
||||||
return SQLITE_ERROR;
|
|
||||||
}
|
|
||||||
ovflSize = pBt->usableSize - 4;
|
|
||||||
|
|
||||||
assert(pCsr->cacheOverflow);
|
|
||||||
if( !pCsr->aOverflow ){
|
|
||||||
int nOverflow = (pInfo->nPayload - pInfo->nLocal + ovflSize - 1)/ovflSize;
|
|
||||||
pCsr->aOverflow = (Pgno *)sqliteMalloc(sizeof(Pgno)*nOverflow);
|
|
||||||
if( nOverflow && !pCsr->aOverflow ){
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pInfo->nLocal>iOffset ){
|
|
||||||
/* In this case data must be written to the b-tree page. */
|
|
||||||
int iWrite = pInfo->nLocal - offset;
|
|
||||||
if( iWrite>iRem ){
|
|
||||||
iWrite = iRem;
|
|
||||||
}
|
|
||||||
rc = sqlite3PagerWrite(pCsr->pPage->pDbPage);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
memcpy(&pInfo->pCell[iOffset+pInfo->nHeader], zRem, iWrite);
|
|
||||||
|
|
||||||
zRem += iWrite;
|
|
||||||
iRem -= iWrite;
|
|
||||||
}
|
|
||||||
iOffset = ((iOffset<pInfo->nLocal)?0:(iOffset-pInfo->nLocal));
|
|
||||||
|
|
||||||
assert(pInfo->iOverflow>0 || iRem==0);
|
|
||||||
if( iRem>0 ){
|
|
||||||
if( pCsr->aOverflow[iOffset/ovflSize] ){
|
|
||||||
iIdx = iOffset/ovflSize;
|
|
||||||
iOvfl = pCsr->aOverflow[iIdx];
|
|
||||||
iOffset = iOffset%ovflSize;
|
|
||||||
}else{
|
|
||||||
iOvfl = get4byte(&pInfo->pCell[pInfo->iOverflow]);
|
|
||||||
}
|
|
||||||
for(iIdx++; iRem>0; iIdx++){
|
|
||||||
if( iOffset>ovflSize ){
|
|
||||||
/* The only reason to read this page is to obtain the page
|
|
||||||
** number for the next page in the overflow chain. So try
|
|
||||||
** the getOverflowPage() shortcut. */
|
|
||||||
rc = getOverflowPage(pBt, iOvfl, 0, &iOvfl);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
iOffset -= ovflSize;
|
|
||||||
pCsr->aOverflow[iIdx] = iOvfl;
|
|
||||||
}else{
|
|
||||||
int iWrite = ovflSize - iOffset;
|
|
||||||
DbPage *pOvfl; /* The overflow page. */
|
|
||||||
u8 *aData; /* Page data */
|
|
||||||
|
|
||||||
rc = sqlite3PagerGet(pBt->pPager, iOvfl, &pOvfl);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
rc = sqlite3PagerWrite(pOvfl);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
sqlite3PagerUnref(pOvfl);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
aData = sqlite3PagerGetData(pOvfl);
|
|
||||||
iOvfl = get4byte(aData);
|
|
||||||
pCsr->aOverflow[iIdx] = iOvfl;
|
|
||||||
if( iWrite>iRem ){
|
|
||||||
iWrite = iRem;
|
|
||||||
}
|
|
||||||
memcpy(&aData[iOffset+4], zRem, iWrite);
|
|
||||||
sqlite3PagerUnref(pOvfl);
|
|
||||||
|
|
||||||
zRem += iWrite;
|
|
||||||
iRem -= iWrite;
|
|
||||||
iOffset = ((iOffset<ovflSize)?0:(iOffset-ovflSize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user