-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
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
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
** 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
/*
-** 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;
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;
}
}
#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;
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;
** (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 );
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);
}
/*