/ Check-in [121308fa]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Size reduction and performance improvements in btree.c and the allocateSpace() routine. Also fix an assert() in freeSpace().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 121308fa869ad490a6924798d276c0ff32759acc
User & Date: drh 2014-08-20 13:35:45
Context
2014-08-20
14:37
Refactor local variable names in the freeSpace() routine of btree.c for improved understandability. check-in: 7e63089a user: drh tags: trunk
13:35
Size reduction and performance improvements in btree.c and the allocateSpace() routine. Also fix an assert() in freeSpace(). check-in: 121308fa user: drh tags: trunk
13:25
Add SQLITE_API macros in front of interface routines in the test_intarray.c extension. check-in: eea06617 user: drh tags: trunk
13:17
Change an assert() added by the previous commit into a testcase(). Fix a separate assert() in btree.c:freeSpace(). Closed-Leaf check-in: fe51d3aa user: drh tags: btree-speedup
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  1218   1218     if( gap>top ){
  1219   1219       if( top==0 ){
  1220   1220         top = 65536;
  1221   1221       }else{
  1222   1222         return SQLITE_CORRUPT_BKPT;
  1223   1223       }
  1224   1224     }
         1225  +
         1226  +  /* If there is enough space between gap and top for one more cell pointer
         1227  +  ** array entry offset, and if the freelist is not empty, then search the
         1228  +  ** freelist looking for a free slot big enough to satisfy the request.
         1229  +  */
  1225   1230     testcase( gap+2==top );
  1226   1231     testcase( gap+1==top );
  1227   1232     testcase( gap==top );
  1228         -
  1229         -  if( data[hdr+7]>=60 ){
  1230         -    /* Always defragment highly fragmented pages */
  1231         -    rc = defragmentPage(pPage);
  1232         -    if( rc ) return rc;
  1233         -    top = get2byteNotZero(&data[hdr+5]);
  1234         -  }else if( gap+2<=top ){
  1235         -    /* Search the freelist looking for a free slot big enough to satisfy 
  1236         -    ** the request. The allocation is made from the first free slot in 
  1237         -    ** the list that is large enough to accommodate it.
  1238         -    */
         1233  +  if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
  1239   1234       int pc, addr;
  1240   1235       for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
  1241   1236         int size;            /* Size of the free slot */
  1242   1237         if( pc>usableSize-4 || pc<addr+4 ){
  1243   1238           return SQLITE_CORRUPT_BKPT;
  1244   1239         }
  1245   1240         size = get2byte(&data[pc+2]);
  1246   1241         if( size>=nByte ){
  1247   1242           int x = size - nByte;
  1248   1243           testcase( x==4 );
  1249   1244           testcase( x==3 );
  1250   1245           if( x<4 ){
         1246  +          if( data[hdr+7]>=60 ) goto defragment_page;
  1251   1247             /* Remove the slot from the free-list. Update the number of
  1252   1248             ** fragmented bytes within the page. */
  1253   1249             memcpy(&data[addr], &data[pc], 2);
  1254   1250             data[hdr+7] += (u8)x;
  1255   1251           }else if( size+pc > usableSize ){
  1256   1252             return SQLITE_CORRUPT_BKPT;
  1257   1253           }else{
................................................................................
  1261   1257           }
  1262   1258           *pIdx = pc + x;
  1263   1259           return SQLITE_OK;
  1264   1260         }
  1265   1261       }
  1266   1262     }
  1267   1263   
  1268         -  /* Check to make sure there is enough space in the gap to satisfy
  1269         -  ** the allocation.  If not, defragment.
         1264  +  /* The request could not be fulfilled using a freelist slot.  Check
         1265  +  ** to see if defragmentation is necessary.
  1270   1266     */
  1271   1267     testcase( gap+2+nByte==top );
  1272   1268     if( gap+2+nByte>top ){
         1269  +defragment_page:
         1270  +    testcase( pPage->nCell==0 );
  1273   1271       rc = defragmentPage(pPage);
  1274   1272       if( rc ) return rc;
  1275   1273       top = get2byteNotZero(&data[hdr+5]);
  1276   1274       assert( gap+nByte<=top );
  1277   1275     }
  1278   1276   
  1279   1277   
................................................................................
  1304   1302     unsigned char *data = pPage->aData;
  1305   1303   
  1306   1304     assert( pPage->pBt!=0 );
  1307   1305     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  1308   1306     assert( start>=pPage->hdrOffset+6+pPage->childPtrSize );
  1309   1307     assert( (start + size) <= (int)pPage->pBt->usableSize );
  1310   1308     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  1311         -  assert( size>=0 );   /* Minimum cell size is 4 */
         1309  +  assert( size>=4 );   /* Minimum cell size is 4 */
  1312   1310   
  1313   1311     if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
  1314   1312       /* Overwrite deleted information with zeros when the secure_delete
  1315   1313       ** option is enabled */
  1316   1314       memset(&data[start], 0, size);
  1317   1315     }
  1318   1316