]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid parsing cells that fit entirely on the b-tree page when searching a b-tree...
authordanielk1977 <danielk1977@noemail.net>
Mon, 4 May 2009 19:01:26 +0000 (19:01 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 4 May 2009 19:01:26 +0000 (19:01 +0000)
FossilOrigin-Name: 77a8239548722f702ead9d7c60df0d68180948fb

manifest
manifest.uuid
src/btree.c

index 9ffc8e78ff2049a6d87fdfc01f25cd28a31d3d46..f1266a2668e84df6b938d37bc5cc932833e74b57 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Changes\sto\sauth.c\sto\spromote\sfull\scoverage\stesting.\s(CVS\s6600)
-D 2009-05-04T18:01:40
+C Avoid\sparsing\scells\sthat\sfit\sentirely\son\sthe\sb-tree\spage\swhen\ssearching\sa\sb-tree\sindex.\s(CVS\s6601)
+D 2009-05-04T19:01:26
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -106,7 +106,7 @@ F src/auth.c 98db07c2088455797678eb1031f42d4d94d18a71
 F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d
 F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d
 F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
-F src/btree.c 62f3194f5ef2cb4c1622e9600bb6257635369d8d
+F src/btree.c a601a89bcf1fc614babbde0afedbfc83e18e3c02
 F src/btree.h 58d876d3ed944a8f4f1fd0e67024b385243fc9dd
 F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
 F src/build.c 8e83444d31975a732be9c393cdcbe51930a35638
@@ -727,7 +727,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P cac4f3d812f0a02ca5c1fa78d366f694403929a8
-R e9ee069731064c4aed8a67abd21e3dc7
-U drh
-Z f9a6939b6e933820d20808f0d4fed962
+P c7615b44583c4b3afa45b57c6047478c18c234e9
+R a1f1431e2f3be0df2e97e7004ec2ab35
+U danielk1977
+Z 615e89480489b234d20acace24b33a9c
index 0fafffae840035bf76f0d1558429b7ce4e346f85..924ce42596d9dc6d4a1646673bea63b97fe5a873 100644 (file)
@@ -1 +1 @@
-c7615b44583c4b3afa45b57c6047478c18c234e9
\ No newline at end of file
+77a8239548722f702ead9d7c60df0d68180948fb
\ No newline at end of file
index 48e4c59a90017a6651a5b6b542226f0165e5ce23..6a22eb83682385e9d0e05f18346c23647b1d16ca 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.606 2009/05/04 11:42:30 danielk1977 Exp $
+** $Id: btree.c,v 1.607 2009/05/04 19:01:26 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -4036,14 +4036,13 @@ int sqlite3BtreeMovetoUnpacked(
       pCur->aiIdx[pCur->iPage] = (u16)((upr+lwr)/2);
     }
     for(;;){
-      void *pCellKey;
-      i64 nCellKey;
-      int idx = pCur->aiIdx[pCur->iPage];
+      int idx = pCur->aiIdx[pCur->iPage]; /* Index of current cell in pPage */
+      u8 *pCell;                          /* Pointer to current cell in pPage */
+
       pCur->info.nSize = 0;
-      pCur->validNKey = 1;
+      pCell = findCell(pPage, idx) + pPage->childPtrSize;
       if( pPage->intKey ){
-        u8 *pCell;
-        pCell = findCell(pPage, idx) + pPage->childPtrSize;
+        i64 nCellKey;
         if( pPage->hasData ){
           u32 dummy;
           pCell += getVarint32(pCell, dummy);
@@ -4057,26 +4056,50 @@ int sqlite3BtreeMovetoUnpacked(
           assert( nCellKey>intKey );
           c = +1;
         }
+        pCur->validNKey = 1;
+        pCur->info.nKey = nCellKey;
       }else{
-        int available;
-        pCellKey = (void *)fetchPayload(pCur, &available, 0);
-        nCellKey = pCur->info.nKey;
-        if( available>=nCellKey ){
-          c = sqlite3VdbeRecordCompare((int)nCellKey, pCellKey, pIdxKey);
+        /* The maximum supported page-size is 32768 bytes. This means that
+        ** the maximum number of record bytes stored on an index B-Tree
+        ** page is at most 8198 bytes, which may be stored as a 2-byte
+        ** varint. This information is used to attempt to avoid parsing 
+        ** the entire cell by checking for the cases where the record is 
+        ** stored entirely within the b-tree page by inspecting the first 
+        ** 2 bytes of the cell.
+        */
+        int nCell = pCell[0];
+        if( !(nCell & 0x80) && nCell<=pPage->maxLocal ){
+          /* This branch runs if the record-size field of the cell is a
+          ** single byte varint and the record fits entirely on the main
+          ** b-tree page.  */
+          c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
+        }else if( !(pCell[1] & 0x80) 
+          && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
+        ){
+          /* The record-size field is a 2 byte varint and the record 
+          ** fits entirely on the main b-tree page.  */
+          c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
         }else{
-          pCellKey = sqlite3Malloc( (int)nCellKey );
+          /* The record flows over onto one or more overflow pages. In
+          ** this case the whole cell needs to be parsed, a buffer allocated
+          ** and accessPayload() used to retrieve the record into the
+          ** buffer before VdbeRecordCompare() can be called. */
+          void *pCellKey;
+          u8 * const pCellBody = pCell - pPage->childPtrSize;
+          sqlite3BtreeParseCellPtr(pPage, pCellBody, &pCur->info);
+          nCell = pCur->info.nKey;
+          pCellKey = sqlite3Malloc( nCell );
           if( pCellKey==0 ){
             rc = SQLITE_NOMEM;
             goto moveto_finish;
           }
-          rc = sqlite3BtreeKey(pCur, 0, (int)nCellKey, (void*)pCellKey);
-          c = sqlite3VdbeRecordCompare((int)nCellKey, pCellKey, pIdxKey);
+          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0, 0);
+          c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
           sqlite3_free(pCellKey);
           if( rc ) goto moveto_finish;
         }
       }
       if( c==0 ){
-        pCur->info.nKey = nCellKey;
         if( pPage->intKey && !pPage->leaf ){
           lwr = idx;
           upr = lwr - 1;
@@ -4093,7 +4116,6 @@ int sqlite3BtreeMovetoUnpacked(
         upr = idx-1;
       }
       if( lwr>upr ){
-        pCur->info.nKey = nCellKey;
         break;
       }
       pCur->aiIdx[pCur->iPage] = (u16)((lwr+upr)/2);