aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2016-06-04 20:37:10 +0000
committerdrh <drh@noemail.net>2016-06-04 20:37:10 +0000
commita7c90c42eaf1badd141ca21bd64669e03de9830c (patch)
tree3a75a6da20c897d85ae393b4a6e6655acf006782 /src
parentf94fdd832cc7f7ec1764af518edf746cba6a3687 (diff)
downloadsqlite-a7c90c42eaf1badd141ca21bd64669e03de9830c.tar.gz
sqlite-a7c90c42eaf1badd141ca21bd64669e03de9830c.zip
Change the sqlite3BtreeKeySize() interface into sqlite3BtreeIntegerKey() and
make it only work for table btrees. Change sqlite3BtreeDataSize() into sqlite3BtreePayloadSize() and make it work for all btrees. Combine sqlite3BtreeDataFetch() and sqlite3BtreeKeyFetch() into a single sqlite3BtreePayloadFetch() routine. These changes seem to make the b-tree interface more rational and they reduce both binary size and CPU usage. FossilOrigin-Name: bef35e18dd19732f7859287b097feeb593e5900f
Diffstat (limited to 'src')
-rw-r--r--src/btree.c61
-rw-r--r--src/btree.h7
-rw-r--r--src/test3.c15
-rw-r--r--src/vdbe.c49
-rw-r--r--src/vdbeapi.c3
-rw-r--r--src/vdbeaux.c6
-rw-r--r--src/vdbeblob.c2
-rw-r--r--src/vdbemem.c6
8 files changed, 42 insertions, 107 deletions
diff --git a/src/btree.c b/src/btree.c
index 7a2b80c23..4003352a5 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -609,20 +609,17 @@ static void btreeReleaseAllCursorPages(BtCursor *pCur){
** the key.
*/
static int saveCursorKey(BtCursor *pCur){
- int rc;
+ int rc = SQLITE_OK;
assert( CURSOR_VALID==pCur->eState );
assert( 0==pCur->pKey );
assert( cursorHoldsMutex(pCur) );
- rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
- assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
-
- /* If this is an intKey table, then the above call to BtreeKeySize()
- ** stores the integer key in pCur->nKey. In this case this value is
- ** all that is required. Otherwise, if pCur is not open on an intKey
- ** table, then malloc space for and store the pCur->nKey bytes of key
- ** data. */
- if( 0==pCur->curIntKey ){
+ if( pCur->curIntKey ){
+ /* Only the rowid is required for a table btree */
+ pCur->nKey = sqlite3BtreeIntegerKey(pCur);
+ }else{
+ /* For an index btree, save the complete key content */
+ pCur->nKey = sqlite3BtreePayloadSize(pCur);
void *pKey = sqlite3Malloc( pCur->nKey );
if( pKey ){
rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
@@ -4262,46 +4259,33 @@ int sqlite3BtreeCursorIsValid(BtCursor *pCur){
#endif /* NDEBUG */
/*
-** Set *pSize to the size of the buffer needed to hold the value of
-** the key for the current entry. If the cursor is not pointing
-** to a valid entry, *pSize is set to 0.
-**
-** For a table with the INTKEY flag set, this routine returns the key
-** itself, not the number of bytes in the key.
-**
-** The caller must position the cursor prior to invoking this routine.
-**
-** This routine cannot fail. It always returns SQLITE_OK.
+** Return the value of the integer key or "rowid" for a table btree.
+** This routine is only valid for a cursor that is pointing into a
+** ordinary table btree. If the cursor points to an index btree or
+** is invalid, the result of this routine is undefined.
*/
-int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
+i64 sqlite3BtreeIntegerKey(BtCursor *pCur){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
+ assert( pCur->curIntKey );
getCellInfo(pCur);
- *pSize = pCur->info.nKey;
- return SQLITE_OK;
+ return pCur->info.nKey;
}
/*
-** Set *pSize to the number of bytes of data in the entry the
-** cursor currently points to.
+** Return the number of bytes of payload for the entry that pCur is
+** currently pointing to. For table btrees, this will be the amount
+** of data. For index btrees, this will be the size of the key.
**
** The caller must guarantee that the cursor is pointing to a non-NULL
** valid entry. In other words, the calling procedure must guarantee
** that the cursor has Cursor.eState==CURSOR_VALID.
-**
-** Failure is not possible. This function always returns SQLITE_OK.
-** It might just as well be a procedure (returning void) but we continue
-** to return an integer result code for historical reasons.
*/
-int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
- assert( cursorOwnsBtShared(pCur) );
+u32 sqlite3BtreePayloadSize(BtCursor *pCur){
+ assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>=0 );
- assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
- assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
getCellInfo(pCur);
- *pSize = pCur->info.nPayload;
- return SQLITE_OK;
+ return pCur->info.nPayload;
}
/*
@@ -4743,10 +4727,7 @@ static const void *fetchPayload(
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
*/
-const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){
- return fetchPayload(pCur, pAmt);
-}
-const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){
+const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){
return fetchPayload(pCur, pAmt);
}
diff --git a/src/btree.h b/src/btree.h
index 5ac119c40..5720df90f 100644
--- a/src/btree.h
+++ b/src/btree.h
@@ -284,11 +284,10 @@ int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int *pRes);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int *pRes);
-int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
+i64 sqlite3BtreeIntegerKey(BtCursor*);
int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
-const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt);
-const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt);
-int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
+const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
+u32 sqlite3BtreePayloadSize(BtCursor*);
int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
diff --git a/src/test3.c b/src/test3.c
index 1e4baf757..bfd7c30b6 100644
--- a/src/test3.c
+++ b/src/test3.c
@@ -385,8 +385,7 @@ static int btree_payload_size(
const char **argv /* Text of each argument */
){
BtCursor *pCur;
- int n2;
- u64 n1;
+ u32 n;
char zBuf[50];
if( argc!=2 ){
@@ -396,17 +395,9 @@ static int btree_payload_size(
}
pCur = sqlite3TestTextToPtr(argv[1]);
sqlite3BtreeEnter(pCur->pBtree);
-
- /* The cursor may be in "require-seek" state. If this is the case, the
- ** call to BtreeDataSize() will fix it. */
- sqlite3BtreeDataSize(pCur, (u32*)&n2);
- if( pCur->apPage[pCur->iPage]->intKey ){
- n1 = 0;
- }else{
- sqlite3BtreeKeySize(pCur, (i64*)&n1);
- }
+ n = sqlite3BtreePayloadSize(pCur);
sqlite3BtreeLeave(pCur->pBtree);
- sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", (int)(n1+n2));
+ sqlite3_snprintf(sizeof(zBuf),zBuf, "%u", n);
Tcl_AppendResult(interp, zBuf, 0);
return SQLITE_OK;
}
diff --git a/src/vdbe.c b/src/vdbe.c
index d4392a89d..356cf52f0 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -2380,7 +2380,6 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
** skipped for length() and all content loading can be skipped for typeof().
*/
case OP_Column: {
- i64 payloadSize64; /* Number of bytes in the record */
int p2; /* column number to retrieve */
VdbeCursor *pC; /* The VDBE cursor */
BtCursor *pCrsr; /* The BTree cursor */
@@ -2433,22 +2432,9 @@ case OP_Column: {
}else{
assert( pC->eCurType==CURTYPE_BTREE );
assert( pCrsr );
- if( pC->isTable==0 ){
- assert( sqlite3BtreeCursorIsValid(pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);
- assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
- ** payload size, so it is impossible for payloadSize64 to be
- ** larger than 32 bits. */
- assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 );
- pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail);
- pC->payloadSize = (u32)payloadSize64;
- }else{
- assert( sqlite3BtreeCursorIsValid(pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize);
- assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail);
- }
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
+ pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
+ pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail);
assert( avail<=65536 ); /* Maximum page size is 64KiB */
if( pC->payloadSize <= (u32)avail ){
pC->szRow = pC->payloadSize;
@@ -4201,8 +4187,7 @@ case OP_NewRowid: { /* out2 */
v = 1; /* IMP: R-61914-48074 */
}else{
assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) );
- rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v);
- assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */
+ v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
if( v>=MAX_ROWID ){
pC->useRandomRowid = 1;
}else{
@@ -4459,8 +4444,7 @@ case OP_Delete: {
/* If p5 is zero, the seek operation that positioned the cursor prior to
** OP_Delete will have also set the pC->movetoTarget field to the rowid of
** the row that is being deleted */
- i64 iKey = 0;
- sqlite3BtreeKeySize(pC->uc.pCursor, &iKey);
+ i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
assert( pC->movetoTarget==iKey );
}
#endif
@@ -4476,7 +4460,7 @@ case OP_Delete: {
zDb = db->aDb[pC->iDb].zName;
pTab = pOp->p4.pTab;
if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
- sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
+ pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
}
}else{
zDb = 0; /* Not needed. Silence a compiler warning. */
@@ -4630,7 +4614,6 @@ case OP_RowData: {
VdbeCursor *pC;
BtCursor *pCrsr;
u32 n;
- i64 n64;
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
@@ -4662,20 +4645,9 @@ case OP_RowData: {
if( rc!=SQLITE_OK ) goto abort_due_to_error;
#endif
- if( pC->isTable==0 ){
- assert( !pC->isTable );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
- assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- n = (u32)n64;
- }else{
- VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n);
- assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
+ n = sqlite3BtreePayloadSize(pCrsr);
+ if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ goto too_big;
}
testcase( n==0 );
if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
@@ -4740,8 +4712,7 @@ case OP_Rowid: { /* out2 */
pOut->flags = MEM_Null;
break;
}
- rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v);
- assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */
+ v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
}
pOut->u.i = v;
break;
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 1feecb3e1..83718eae3 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -1650,8 +1650,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
u32 nRec;
u8 *aRec;
- rc = sqlite3BtreeDataSize(p->pCsr->uc.pCursor, &nRec);
- if( rc!=SQLITE_OK ) goto preupdate_old_out;
+ nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
aRec = sqlite3DbMallocRaw(db, nRec);
if( !aRec ) goto preupdate_old_out;
rc = sqlite3BtreeData(p->pCsr->uc.pCursor, 0, nRec, aRec);
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index bce676f10..63609d72d 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -4315,8 +4315,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
** this code can safely assume that nCellKey is 32-bits
*/
assert( sqlite3BtreeCursorIsValid(pCur) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
- assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
+ nCellKey = sqlite3BtreePayloadSize(pCur);
assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
/* Read in the complete content of the index entry */
@@ -4393,8 +4392,7 @@ int sqlite3VdbeIdxKeyCompare(
assert( pC->eCurType==CURTYPE_BTREE );
pCur = pC->uc.pCursor;
assert( sqlite3BtreeCursorIsValid(pCur) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
- assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
+ nCellKey = sqlite3BtreePayloadSize(pCur);
/* nCellKey will always be between 0 and 0xffffffff because of the way
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
if( nCellKey<=0 || nCellKey>0x7fffffff ){
diff --git a/src/vdbeblob.c b/src/vdbeblob.c
index f2b3ffef2..01827f94d 100644
--- a/src/vdbeblob.c
+++ b/src/vdbeblob.c
@@ -415,7 +415,7 @@ static int blobReadWrite(
** anyhow.
*/
sqlite3_int64 iKey;
- sqlite3BtreeKeySize(p->pCsr, &iKey);
+ iKey = sqlite3BtreeIntegerKey(p->pCsr);
sqlite3VdbePreUpdateHook(
v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1
);
diff --git a/src/vdbemem.c b/src/vdbemem.c
index f9396e570..04cb9c5c6 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -991,11 +991,7 @@ int sqlite3VdbeMemFromBtree(
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
** that both the BtShared and database handle mutexes are held. */
assert( (pMem->flags & MEM_RowSet)==0 );
- if( key ){
- zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
- }else{
- zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
- }
+ zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
assert( zData!=0 );
if( offset+amt<=available ){