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

Overview
Comment:Fix a couple of other bugs.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 822a5aad62557b880be4ef23ec38b7c4443cf8a4
User & Date: dan 2014-02-04 19:40:19.969
Context
2014-02-05
19:10
Add extra tests and fixes. Make the block size and page size configurable. check-in: b43e752c98 user: dan tags: trunk
2014-02-04
19:40
Fix a couple of other bugs. check-in: 822a5aad62 user: dan tags: trunk
2014-02-03
17:30
Fix a problem with reading very large delete-key entries. check-in: 0cabe78ef4 user: dan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to lsm-test/lsmtest_main.c.
272
273
274
275
276
277
278

279
280
281
282
283
284
285
  TestDb *pDb1,                   /* Control (trusted) database */
  TestDb *pDb2,                   /* Database being tested */
  int bReverse,
  void *pKey1, int nKey1, 
  void *pKey2, int nKey2, 
  int *pRc
){

  if( *pRc==0 ){
    ScanResult res1;
    ScanResult res2;
    void *pRes1 = (void *)&res1;
    void *pRes2 = (void *)&res2;

    memset(&res1, 0, sizeof(ScanResult));







>







272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  TestDb *pDb1,                   /* Control (trusted) database */
  TestDb *pDb2,                   /* Database being tested */
  int bReverse,
  void *pKey1, int nKey1, 
  void *pKey2, int nKey2, 
  int *pRc
){
  static int nCall = 0; nCall++;
  if( *pRc==0 ){
    ScanResult res1;
    ScanResult res2;
    void *pRes1 = (void *)&res1;
    void *pRes2 = (void *)&res2;

    memset(&res1, 0, sizeof(ScanResult));
Changes to src/bt_main.c.
122
123
124
125
126
127
128

129
130
131
132
133
134
135
static int fiLoadSummary(bt_db *, BtCursor *, const u8 **, int *);
static void btReadSummary(const u8 *, int, u16 *, u16 *, u16 *);
static int btCsrData(BtCursor *, int, int, const void **, int *);
static int btReadSchedule(bt_db *, u8 *, BtSchedule *);
static int btCsrEnd(BtCursor *pCsr, int bLast);
static int btCsrStep(BtCursor *pCsr, int bNext);
static int btCsrKey(BtCursor *pCsr, const void **ppK, int *pnK);



/* 
** Meta-table summary key.
*/
static const u8 aSummaryKey[] = {0xFF, 0xFF, 0xFF, 0xFF};








>







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
static int fiLoadSummary(bt_db *, BtCursor *, const u8 **, int *);
static void btReadSummary(const u8 *, int, u16 *, u16 *, u16 *);
static int btCsrData(BtCursor *, int, int, const void **, int *);
static int btReadSchedule(bt_db *, u8 *, BtSchedule *);
static int btCsrEnd(BtCursor *pCsr, int bLast);
static int btCsrStep(BtCursor *pCsr, int bNext);
static int btCsrKey(BtCursor *pCsr, const void **ppK, int *pnK);
void sqlite4BtDebugFastTree(bt_db *db, int iCall);


/* 
** Meta-table summary key.
*/
static const u8 aSummaryKey[] = {0xFF, 0xFF, 0xFF, 0xFF};

406
407
408
409
410
411
412

413
414
415
416
417
418
419
*/
static int btCsrDescend(BtCursor *pCsr, u32 pgno){
  int rc;
  if( pCsr->nPg>=BT_MAX_DEPTH ){
    rc = btErrorBkpt(SQLITE4_CORRUPT);
  }else{
    bt_db *pDb = pCsr->base.pDb;

    rc = sqlite4BtPageGet(pDb->pPager, pgno, &pCsr->apPage[pCsr->nPg]);
    if( rc==SQLITE4_OK ){
      assert( pCsr->apPage[pCsr->nPg] );
      pCsr->nPg++;
    }
  }
  return rc;







>







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
*/
static int btCsrDescend(BtCursor *pCsr, u32 pgno){
  int rc;
  if( pCsr->nPg>=BT_MAX_DEPTH ){
    rc = btErrorBkpt(SQLITE4_CORRUPT);
  }else{
    bt_db *pDb = pCsr->base.pDb;
    assert( pCsr->nPg>=0 );
    rc = sqlite4BtPageGet(pDb->pPager, pgno, &pCsr->apPage[pCsr->nPg]);
    if( rc==SQLITE4_OK ){
      assert( pCsr->apPage[pCsr->nPg] );
      pCsr->nPg++;
    }
  }
  return rc;
977
978
979
980
981
982
983
984
985
986
987
988
989
990


991
992
993
994
995
996
997
      rc = sqlite4BtCsrKey((bt_cursor*)pCsr, &pCsrKey, &nCsrKey);
    }
  }

  if( rc==SQLITE4_OK ){
    if( aPrefix ){
      if( nCsrKey<8 ){
        res = 1;
        goto keycompare_done;
      }
      res = memcmp(pCsrKey, aPrefix, 8);
      if( res ) goto keycompare_done;
      nCsrKey -= 8;
      pCsrKey = (void*)(((u8*)pCsrKey) + 8);


    }

    nCmp = MIN(nCsrKey, nK);
    res = memcmp(pCsrKey, pK, nCmp);
    if( res==0 ){
      res = nCsrKey - nK;
    }







|
|
|
|
<
|
|
>
>







979
980
981
982
983
984
985
986
987
988
989

990
991
992
993
994
995
996
997
998
999
1000
      rc = sqlite4BtCsrKey((bt_cursor*)pCsr, &pCsrKey, &nCsrKey);
    }
  }

  if( rc==SQLITE4_OK ){
    if( aPrefix ){
      if( nCsrKey<8 ){
        res = memcmp(pCsrKey, aPrefix, nCsrKey);
        if( res==0 ) res = -1;
      }else{
        res = memcmp(pCsrKey, aPrefix, 8);

        nCsrKey -= 8;
        pCsrKey = (void*)(((u8*)pCsrKey) + 8);
      }
      if( res ) goto keycompare_done;
    }

    nCmp = MIN(nCsrKey, nK);
    res = memcmp(pCsrKey, pK, nCmp);
    if( res==0 ){
      res = nCsrKey - nK;
    }
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
              pSeek = pMin;
              nSeek = nMin;
            }
          }

          rc = btCsrSeek(&pSub->csr, 0, pSeek, nSeek, eSeek, BT_CSRSEEK_SEEK);
          if( rc==SQLITE4_NOTFOUND ){
            if( eSeek==BT_SEEK_LE ){
              rc = fiSubCsrStep(pCsr, pSub, 0);
            }else{
              btCsrReset(pM, 0);
            }
          }else{
            if( rc==SQLITE4_OK ) bMatch = 1;
            if( rc==SQLITE4_INEXACT ) bHit = 1;
          }

          if( rc==SQLITE4_INEXACT || rc==SQLITE4_NOTFOUND ) rc = SQLITE4_OK;
        }else{







<
|
<
<
<







1930
1931
1932
1933
1934
1935
1936

1937



1938
1939
1940
1941
1942
1943
1944
              pSeek = pMin;
              nSeek = nMin;
            }
          }

          rc = btCsrSeek(&pSub->csr, 0, pSeek, nSeek, eSeek, BT_CSRSEEK_SEEK);
          if( rc==SQLITE4_NOTFOUND ){

            rc = fiSubCsrStep(pCsr, pSub, (eSeek==BT_SEEK_GE ? 1 : 0));



          }else{
            if( rc==SQLITE4_OK ) bMatch = 1;
            if( rc==SQLITE4_INEXACT ) bHit = 1;
          }

          if( rc==SQLITE4_INEXACT || rc==SQLITE4_NOTFOUND ) rc = SQLITE4_OK;
        }else{
4244
4245
4246
4247
4248
4249
4250

4251
4252
4253
4254
4255
4256
4257
  btCsrReset(&csr, 1);
  btCsrReset(&mcsr, 1);
  sqlite4_buffer_clear(&buf);

#if 0
  if( rc==SQLITE4_OK ){
    btPrintMetaTree(db->pPager, 1, pHdr);

  }
#endif
  assert_summary_ok(db, SQLITE4_OK);
  db->bFastInsertOp = bFastInsertOp;
  return rc;
}








>







4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
  btCsrReset(&csr, 1);
  btCsrReset(&mcsr, 1);
  sqlite4_buffer_clear(&buf);

#if 0
  if( rc==SQLITE4_OK ){
    btPrintMetaTree(db->pPager, 1, pHdr);
    sqlite4BtDebugFastTree(db, nCall);
  }
#endif
  assert_summary_ok(db, SQLITE4_OK);
  db->bFastInsertOp = bFastInsertOp;
  return rc;
}

4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
      rc = btCsrData(pM, 0, 4, &pVal, &nVal);
      if( rc==SQLITE4_OK ){
        u32 iRoot = sqlite4BtGetU32((const u8*)pVal);
        btCsrSetup(db, iRoot, &pSub->csr);
        rc = btCsrSeek(&pSub->csr, 0, pKey, nKey, BT_SEEK_GE, 0);
        if( rc==SQLITE4_INEXACT ) rc = SQLITE4_OK;
        if( rc==SQLITE4_NOTFOUND ){
          btCsrReset(pM, 0);
          rc = SQLITE4_OK;
        }
      }
    }else if( rc==SQLITE4_NOTFOUND ){
      assert( pSub->csr.nPg==0 );
      assert( pSub->mcsr.nPg==0 );
      rc = SQLITE4_OK;
    }







|
|







4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
      rc = btCsrData(pM, 0, 4, &pVal, &nVal);
      if( rc==SQLITE4_OK ){
        u32 iRoot = sqlite4BtGetU32((const u8*)pVal);
        btCsrSetup(db, iRoot, &pSub->csr);
        rc = btCsrSeek(&pSub->csr, 0, pKey, nKey, BT_SEEK_GE, 0);
        if( rc==SQLITE4_INEXACT ) rc = SQLITE4_OK;
        if( rc==SQLITE4_NOTFOUND ){
          rc = fiSubCsrStep(0, pSub, 1);
          if( rc==SQLITE4_NOTFOUND ) rc = SQLITE4_OK;
        }
      }
    }else if( rc==SQLITE4_NOTFOUND ){
      assert( pSub->csr.nPg==0 );
      assert( pSub->mcsr.nPg==0 );
      rc = SQLITE4_OK;
    }
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
    assert( rc!=BT_BLOCKFULL );
  }
  pPg = &p->aHier[0];

  /* Calculate the space required for the cell. And space available on
  ** the current leaf page.  */
  nReq = nCell + 2;
  nFree = p->pgsz - pPg->iFree - (6 + 2*(pPg->nCell+1));

  if( nReq>nFree ){
    /* The current leaf page is finished. Cell pCell/nCell will become
    ** the first cell on the next leaf page.  */
    const u8 *pOld; int nOld;     /* Prefix of last key on current leaf */
    const u8 *pNew; int nNew;     /* Prefix of new key */
    int nPrefix;







|







4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
    assert( rc!=BT_BLOCKFULL );
  }
  pPg = &p->aHier[0];

  /* Calculate the space required for the cell. And space available on
  ** the current leaf page.  */
  nReq = nCell + 2;
  nFree = p->pgsz - pPg->iFree - (6 + 2*pPg->nCell);

  if( nReq>nFree ){
    /* The current leaf page is finished. Cell pCell/nCell will become
    ** the first cell on the next leaf page.  */
    const u8 *pOld; int nOld;     /* Prefix of last key on current leaf */
    const u8 *pNew; int nNew;     /* Prefix of new key */
    int nPrefix;
4883
4884
4885
4886
4887
4888
4889

4890
4891
4892
4893
4894
4895
4896
        s.iNextPg = sqlite4BtPagePgno(pCsr->apPage[pCsr->nPg-1]);
        s.iNextCell = pCsr->aiCell[pCsr->nPg-1];
      }
      s.iFreeList = 0;
      s.eBusy = BT_SCHEDULE_DONE;

      assert( s.iFreeList==0 );

      if( writer.aTrunk ){
        rc = fiWriterFlushOvfl(&writer, &s.iFreeList);
      }
      if( rc==SQLITE4_OK ){
        rc = fiWriterFlushAll(&writer);
      }
      if( rc==SQLITE4_OK ){







>







4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
        s.iNextPg = sqlite4BtPagePgno(pCsr->apPage[pCsr->nPg-1]);
        s.iNextCell = pCsr->aiCell[pCsr->nPg-1];
      }
      s.iFreeList = 0;
      s.eBusy = BT_SCHEDULE_DONE;

      assert( s.iFreeList==0 );
      rc = SQLITE4_OK;
      if( writer.aTrunk ){
        rc = fiWriterFlushOvfl(&writer, &s.iFreeList);
      }
      if( rc==SQLITE4_OK ){
        rc = fiWriterFlushAll(&writer);
      }
      if( rc==SQLITE4_OK ){
4950
4951
4952
4953
4954
4955
4956






















4957
4958
4959
4960
4961
4962
4963
  sqlite4BtPageGet(db->pPager, iRoot, &pPg);
  btPageToAscii(iRoot, 1, db->pPager, sqlite4BtPageData(pPg), pgsz, &buf);
  fprintf(stderr, "%d TREE at %d:\n", iCall, (int)iRoot);
  fprintf(stderr, "%.*s", buf.n, (char*)buf.p);
  sqlite4_buffer_clear(&buf);
  sqlite4BtPageRelease(pPg);
}
























/*
** Delete the entry that the cursor currently points to.
*/
int sqlite4BtDelete(bt_cursor *pBase){
  bt_db *db = pBase->pDb;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
  sqlite4BtPageGet(db->pPager, iRoot, &pPg);
  btPageToAscii(iRoot, 1, db->pPager, sqlite4BtPageData(pPg), pgsz, &buf);
  fprintf(stderr, "%d TREE at %d:\n", iCall, (int)iRoot);
  fprintf(stderr, "%.*s", buf.n, (char*)buf.p);
  sqlite4_buffer_clear(&buf);
  sqlite4BtPageRelease(pPg);
}

void sqlite4BtDebugFastTree(bt_db *db, int iCall){
  BtDbHdr *pHdr;
  BtCursor mcsr;
  int rc;

  pHdr = sqlite4BtPagerDbhdr(db->pPager);
  btCsrSetup(db, pHdr->iMRoot, &mcsr);
  for(rc=btCsrEnd(&mcsr, 0); rc==SQLITE4_OK; rc=btCsrStep(&mcsr, 1)){
    u32 iSubRoot;
    const void *pK; int nK;
    rc = btCsrKey(&mcsr, &pK, &nK);
    if( rc!=SQLITE4_OK ) break;
    if( nK==sizeof(aSummaryKey) && 0==memcmp(aSummaryKey, pK, nK) ) break;
    rc = btCsrData(&mcsr, 0, 4, &pK, &nK);
    if( rc!=SQLITE4_OK ) break;

    iSubRoot = btGetU32((const u8*)pK);
    sqlite4BtDebugTree(db, iCall, iSubRoot);
  }
  btCsrReset(&mcsr, 1);
}


/*
** Delete the entry that the cursor currently points to.
*/
int sqlite4BtDelete(bt_cursor *pBase){
  bt_db *db = pBase->pDb;