/ Check-in [73637d12]
Login

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

Overview
Comment:Minor performance improvement and size reduction for the btree-page space allocator.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 73637d12e31f5489efe37d8cf4ab50a1911d4c75
User & Date: drh 2014-08-20 00:54:46
Context
2014-08-20
10:42
Fix a typo in the showdb usage message. check-in: 6c66beae user: dan tags: trunk
00:54
Minor performance improvement and size reduction for the btree-page space allocator. check-in: 73637d12 user: drh tags: trunk
2014-08-19
23:04
Modify the memsubsys1-3.1.4 test so that it does not fail arbitrarily due to variations in the behavior of system malloc(). check-in: d280157d user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
....
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217

1218




1219


1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
....
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
** the first two bytes past the cell pointer area since presumably this
** allocation is being made in order to insert a new cell, so we will
** also end up needing a new cell pointer.
*/
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  const int hdr = pPage->hdrOffset;    /* Local cache of pPage->hdrOffset */
  u8 * const data = pPage->aData;      /* Local cache of pPage->aData */
  int nFrag;                           /* Number of fragmented bytes on pPage */
  int top;                             /* First byte of cell content area */
  int gap;        /* First byte of gap between cell pointers and cell content */
  int rc;         /* Integer return code */
  int usableSize; /* Usable size of the page */
  
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt );
................................................................................
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( nByte>=0 );  /* Minimum cell size is 4 */
  assert( pPage->nFree>=nByte );
  assert( pPage->nOverflow==0 );
  usableSize = pPage->pBt->usableSize;
  assert( nByte < usableSize-8 );

  nFrag = data[hdr+7];
  assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
  gap = pPage->cellOffset + 2*pPage->nCell;

  top = get2byteNotZero(&data[hdr+5]);




  if( gap>top ) return SQLITE_CORRUPT_BKPT;


  testcase( gap+2==top );
  testcase( gap+1==top );
  testcase( gap==top );

  if( nFrag>=60 ){
    /* Always defragment highly fragmented pages */
    rc = defragmentPage(pPage);
    if( rc ) return rc;
    top = get2byteNotZero(&data[hdr+5]);
  }else if( gap+2<=top ){
    /* Search the freelist looking for a free slot big enough to satisfy 
    ** the request. The allocation is made from the first free slot in 
................................................................................
        int x = size - nByte;
        testcase( x==4 );
        testcase( x==3 );
        if( x<4 ){
          /* Remove the slot from the free-list. Update the number of
          ** fragmented bytes within the page. */
          memcpy(&data[addr], &data[pc], 2);
          data[hdr+7] = (u8)(nFrag + x);
        }else if( size+pc > usableSize ){
          return SQLITE_CORRUPT_BKPT;
        }else{
          /* The slot remains on the free-list. Reduce its size to account
          ** for the portion used by the new allocation. */
          put2byte(&data[pc+2], x);
        }







<







 







<


>
|
>
>
>
>
|
>
>




|







 







|







1193
1194
1195
1196
1197
1198
1199

1200
1201
1202
1203
1204
1205
1206
....
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
....
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
** the first two bytes past the cell pointer area since presumably this
** allocation is being made in order to insert a new cell, so we will
** also end up needing a new cell pointer.
*/
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  const int hdr = pPage->hdrOffset;    /* Local cache of pPage->hdrOffset */
  u8 * const data = pPage->aData;      /* Local cache of pPage->aData */

  int top;                             /* First byte of cell content area */
  int gap;        /* First byte of gap between cell pointers and cell content */
  int rc;         /* Integer return code */
  int usableSize; /* Usable size of the page */
  
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt );
................................................................................
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( nByte>=0 );  /* Minimum cell size is 4 */
  assert( pPage->nFree>=nByte );
  assert( pPage->nOverflow==0 );
  usableSize = pPage->pBt->usableSize;
  assert( nByte < usableSize-8 );


  assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
  gap = pPage->cellOffset + 2*pPage->nCell;
  assert( gap<=65536 );
  top = get2byte(&data[hdr+5]);
  if( gap>top ){
    if( top==0 ){
      top = 65536;
    }else{
      return SQLITE_CORRUPT_BKPT;
    }
  }
  testcase( gap+2==top );
  testcase( gap+1==top );
  testcase( gap==top );

  if( data[hdr+7]>=60 ){
    /* Always defragment highly fragmented pages */
    rc = defragmentPage(pPage);
    if( rc ) return rc;
    top = get2byteNotZero(&data[hdr+5]);
  }else if( gap+2<=top ){
    /* Search the freelist looking for a free slot big enough to satisfy 
    ** the request. The allocation is made from the first free slot in 
................................................................................
        int x = size - nByte;
        testcase( x==4 );
        testcase( x==3 );
        if( x<4 ){
          /* Remove the slot from the free-list. Update the number of
          ** fragmented bytes within the page. */
          memcpy(&data[addr], &data[pc], 2);
          data[hdr+7] += (u8)x;
        }else if( size+pc > usableSize ){
          return SQLITE_CORRUPT_BKPT;
        }else{
          /* The slot remains on the free-list. Reduce its size to account
          ** for the portion used by the new allocation. */
          put2byte(&data[pc+2], x);
        }