Exemplo n.º 1
0
void test_1b_2(void)
{
  int rc;
  chidb *db;
  MemPage *page;
  uint8_t *rawpage;
  
  remove(NEWFILE);
  db = malloc(sizeof(chidb));
  rc = chidb_Btree_open(NEWFILE, db, &db->bt);
  CU_ASSERT(rc == CHIDB_OK);
  
  rc = chidb_Pager_readPage(db->bt->pager, 1, &page);
  CU_ASSERT(rc == CHIDB_OK);
  rawpage = page->data;
  
  if (strcmp((char *) rawpage, "SQLite format 3") || 
      rawpage[18] != 1 || 
      rawpage[19] != 1 || 
      rawpage[20] != 0 || 
      rawpage[21] != 64 || 
      rawpage[22] != 32 || 
      rawpage[23] != 32 ||
      get4byte(&rawpage[32]) != 0 || 
      get4byte(&rawpage[36]) != 0 || 
      get4byte(&rawpage[44]) != 1 || 
      get4byte(&rawpage[52]) != 0 || 
      get4byte(&rawpage[56]) != 1 || 
      get4byte(&rawpage[64]) != 0 ||
      get4byte(&rawpage[48]) != 20000)
    CU_FAIL("File header is not well-formed.");	
  
  if (rawpage[100] != PGTYPE_TABLE_LEAF || 
      get2byte(&rawpage[101]) != 108 || 
      get2byte(&rawpage[103]) != 0 ||
      get2byte(&rawpage[105]) != 1024 || 
      rawpage[107] != 0)
    CU_FAIL("Page 1 header is not well-formed.");	
  
  rc = chidb_Btree_close(db->bt);
  remove(NEWFILE);
  free(db);
}
Exemplo n.º 2
0
void test_2_3(void)
{
  chidb *db;
  BTreeNode *btn;
  
  db = malloc(sizeof(chidb));
  chidb_Btree_open(TESTFILE_1, db, &db->bt);
  chidb_Btree_getNodeByPage(db->bt, 2, &btn);
  
  btn_sanity_check(db->bt, btn, false);
  CU_ASSERT(btn->page->npage == 2);	
  CU_ASSERT(btn->type == PGTYPE_TABLE_LEAF);
  CU_ASSERT(btn->n_cells == 4);
  CU_ASSERT(btn->free_offset == 16);
  CU_ASSERT(btn->cells_offset == 480);
  CU_ASSERT(get2byte(&btn->celloffset_array[0]) == 888);
  CU_ASSERT(get2byte(&btn->celloffset_array[2]) == 752);
  CU_ASSERT(get2byte(&btn->celloffset_array[4]) == 616);
  CU_ASSERT(get2byte(&btn->celloffset_array[6]) == 480);
    
  chidb_Btree_freeMemNode(db->bt, btn);
  chidb_Btree_close(db->bt);
  free(db);
}
Exemplo n.º 3
0
void test_2_2(void)
{
  chidb *db;
  BTreeNode *btn;
  
  db = malloc(sizeof(chidb));
  chidb_Btree_open(TESTFILE_1, db, &db->bt);
  chidb_Btree_getNodeByPage(db->bt, 1, &btn);
  
  btn_sanity_check(db->bt, btn, false);
  CU_ASSERT(btn->page->npage == 1);	
  CU_ASSERT(btn->type == PGTYPE_TABLE_INTERNAL);
  CU_ASSERT(btn->n_cells == 3);
  CU_ASSERT(btn->right_page == 2);
  CU_ASSERT(btn->free_offset == 118);
  CU_ASSERT(btn->cells_offset == 1000);
  CU_ASSERT(get2byte(&btn->celloffset_array[0]) == 1008);
  CU_ASSERT(get2byte(&btn->celloffset_array[2]) == 1016);
  CU_ASSERT(get2byte(&btn->celloffset_array[4]) == 1000);
    
  chidb_Btree_freeMemNode(db->bt, btn);
  chidb_Btree_close(db->bt);
  free(db);
}
Exemplo n.º 4
0
void btn_sanity_check(BTree *bt, BTreeNode *btn, bool empty)
{
  CU_ASSERT_FATAL(btn->page->npage >= 1);	
  int header_offset = btn->page->npage==1? 100:0;
  CU_ASSERT_FATAL(btn->type == PGTYPE_TABLE_INTERNAL || 
		  btn->type == PGTYPE_TABLE_LEAF || 
		  btn->type == PGTYPE_INDEX_INTERNAL || 
		  btn->type == PGTYPE_INDEX_LEAF);
  CU_ASSERT_FATAL(btn->n_cells >= 0);
  switch (btn->type) {
  case PGTYPE_TABLE_INTERNAL: 
  case PGTYPE_INDEX_INTERNAL:
    CU_ASSERT_FATAL(btn->free_offset == header_offset + 
		    INTPG_CELLSOFFSET_OFFSET + 
		    (btn->n_cells * 2));
    CU_ASSERT_FATAL(btn->celloffset_array == btn->page->data + 
		    header_offset + 
		    INTPG_CELLSOFFSET_OFFSET);
    break;
  case PGTYPE_TABLE_LEAF: 
  case PGTYPE_INDEX_LEAF:
    CU_ASSERT_FATAL(btn->free_offset == header_offset + 
		    LEAFPG_CELLSOFFSET_OFFSET + 
		    (btn->n_cells * 2));
    CU_ASSERT_FATAL(btn->celloffset_array == btn->page->data + 
		    header_offset + 
		    LEAFPG_CELLSOFFSET_OFFSET);
    break;
  }
  CU_ASSERT_FATAL(btn->cells_offset >= btn->free_offset);
  CU_ASSERT_FATAL(btn->cells_offset <= bt->pager->page_size);
  for (int i=0; i<btn->n_cells; i++) {
    uint16_t cell_offset = get2byte(&btn->celloffset_array[i*2]);
    CU_ASSERT_FATAL(cell_offset >= btn->cells_offset);
    CU_ASSERT_FATAL(cell_offset <= bt->pager->page_size);
  }	
  if (!empty && 
      (btn->type == PGTYPE_TABLE_INTERNAL || btn->type == PGTYPE_INDEX_INTERNAL)) {
    CU_ASSERT_FATAL(btn->right_page > 1);
    CU_ASSERT_FATAL(btn->right_page <= bt->pager->n_pages);
  }
}
Exemplo n.º 5
0
static int statDecodePage(Btree *pBt, StatPage *p){
  int nUnused;
  int iOff;
  int nHdr;
  int isLeaf;
  int szPage;

  u8 *aData = sqlite3PagerGetData(p->pPg);
  u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];

  p->flags = aHdr[0];
  p->nCell = get2byte(&aHdr[3]);
  p->nMxPayload = 0;

  isLeaf = (p->flags==0x0A || p->flags==0x0D);
  nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;

  nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
  nUnused += (int)aHdr[7];
  iOff = get2byte(&aHdr[1]);
  while( iOff ){
    nUnused += get2byte(&aData[iOff+2]);
    iOff = get2byte(&aData[iOff]);
  }
  p->nUnused = nUnused;
  p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
  szPage = sqlite3BtreeGetPageSize(pBt);

  if( p->nCell ){
    int i;                        /* Used to iterate through cells */
    int nUsable;                  /* Usable bytes per page */

    sqlite3BtreeEnter(pBt);
    nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
    sqlite3BtreeLeave(pBt);
    p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
    if( p->aCell==0 ) return SQLITE_NOMEM_BKPT;
    memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));

    for(i=0; i<p->nCell; i++){
      StatCell *pCell = &p->aCell[i];

      iOff = get2byte(&aData[nHdr+i*2]);
      if( !isLeaf ){
        pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
        iOff += 4;
      }
      if( p->flags==0x05 ){
        /* A table interior node. nPayload==0. */
      }else{
        u32 nPayload;             /* Bytes of payload total (local+overflow) */
        int nLocal;               /* Bytes of payload stored locally */
        iOff += getVarint32(&aData[iOff], nPayload);
        if( p->flags==0x0D ){
          u64 dummy;
          iOff += sqlite3GetVarint(&aData[iOff], &dummy);
        }
        if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
        getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
        pCell->nLocal = nLocal;
        assert( nLocal>=0 );
        assert( nPayload>=(u32)nLocal );
        assert( nLocal<=(nUsable-35) );
        if( nPayload>(u32)nLocal ){
          int j;
          int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
          pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
          pCell->nOvfl = nOvfl;
          pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
          if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
          pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
          for(j=1; j<nOvfl; j++){
            int rc;
            u32 iPrev = pCell->aOvfl[j-1];
            DbPage *pPg = 0;
            rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg, 0);
            if( rc!=SQLITE_OK ){
              assert( pPg==0 );
              return rc;
            } 
            pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg));
            sqlite3PagerUnref(pPg);
          }
        }
      }
    }
  }

  return SQLITE_OK;
}