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)
|
||||
D 2007-05-02T16:51:59
|
||||
C Combine\sthe\sinternal\sbtree\sfunctions\sBtreePutData()\sand\sgetPayload().\s(CVS\s3901)
|
||||
D 2007-05-02T17:48:46
|
||||
F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
|
||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@@ -59,7 +59,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
|
||||
F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
|
||||
F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
|
||||
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
|
||||
F src/btree.c 4efb50fa388aa1678eb9cce5e5fc6fa8247406b2
|
||||
F src/btree.c ecd0a02c8f867509b5439379208f0ee4d801389e
|
||||
F src/btree.h 2c187d60cf76d74c2b4767294d6b5fa267037ff0
|
||||
F src/build.c 02e01ec7907c7d947ab3041fda0e81eaed05db42
|
||||
F src/callback.c 6414ed32d55859d0f65067aa5b88d2da27b3af9e
|
||||
@@ -471,7 +471,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P 349f1ea7895f06c40affc985a13aa6686dfdea07
|
||||
R c40994429188bdd3545336b5231dc204
|
||||
U drh
|
||||
Z 278e5bf758bcf3f514d6f2d4595a443f
|
||||
P 83ab25014e890b1cc6ea08ca1ebeeee0078da466
|
||||
R 6382007c866ff2246040af323c0a9f53
|
||||
U danielk1977
|
||||
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.
|
||||
**
|
||||
*************************************************************************
|
||||
** $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.
|
||||
** 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
|
||||
** pointing to. Begin reading the payload at "offset" and read
|
||||
** a total of "amt" bytes. Put the result in zBuf.
|
||||
** This function is used to read or overwrite payload information
|
||||
** for the entry that the pCur cursor is pointing to. If the eOp
|
||||
** 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.
|
||||
** It just reads bytes from the payload area. Data might appear
|
||||
** on the main page or be scattered out on multiple overflow pages.
|
||||
** It just reads or writes bytes from the payload area. Data might
|
||||
** 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 */
|
||||
int offset, /* Begin reading this far into payload */
|
||||
int amt, /* Read this many bytes */
|
||||
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;
|
||||
Pgno nextPage;
|
||||
@@ -3187,7 +3195,17 @@ static int getPayload(
|
||||
if( a+offset>pCur->info.nLocal ){
|
||||
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 ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -3232,8 +3250,8 @@ static int getPayload(
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
/* Need to read this page properly, to obtain data to copy into
|
||||
** the caller's buffer.
|
||||
/* 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;
|
||||
int a = amt;
|
||||
@@ -3246,7 +3264,18 @@ static int getPayload(
|
||||
if( a + offset > ovflSize ){
|
||||
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;
|
||||
amt -= 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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
assert( !pBt->readOnly );
|
||||
@@ -6956,94 +6985,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, const void *z){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
/* Parse the cell-info. Check that the cell-data area is large
|
||||
** 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;
|
||||
return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user