⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btree.c

📁 轻量级数据库软件,嵌入式设计可以考虑考虑,性能不错
💻 C
📖 第 1 页 / 共 5 页
字号:
  p->inTrans = TRANS_NONE;  p->pSqlite = pSqlite;  /* Try to find an existing Btree structure opened on zFilename. */#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)  pTsdro = sqlite3ThreadDataReadOnly();  if( pTsdro->useSharedData && zFilename && !isMemdb ){    char *zFullPathname = sqlite3OsFullPathname(zFilename);    if( !zFullPathname ){      sqliteFree(p);      return SQLITE_NOMEM;    }    for(pBt=pTsdro->pBtree; pBt; pBt=pBt->pNext){      assert( pBt->nRef>0 );      if( 0==strcmp(zFullPathname, sqlite3pager_filename(pBt->pPager)) ){        p->pBt = pBt;        *ppBtree = p;        pBt->nRef++;        sqliteFree(zFullPathname);        return SQLITE_OK;      }    }    sqliteFree(zFullPathname);  }#endif  /*  ** The following asserts make sure that structures used by the btree are  ** the right size.  This is to guard against size changes that result  ** when compiling on a different architecture.  */  assert( sizeof(i64)==8 || sizeof(i64)==4 );  assert( sizeof(u64)==8 || sizeof(u64)==4 );  assert( sizeof(u32)==4 );  assert( sizeof(u16)==2 );  assert( sizeof(Pgno)==4 );  pBt = sqliteMalloc( sizeof(*pBt) );  if( pBt==0 ){    *ppBtree = 0;    sqliteFree(p);    return SQLITE_NOMEM;  }  rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);  if( rc==SQLITE_OK ){    rc = sqlite3pager_read_fileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);  }  if( rc!=SQLITE_OK ){    if( pBt->pPager ){      sqlite3pager_close(pBt->pPager);    }    sqliteFree(pBt);    sqliteFree(p);    *ppBtree = 0;    return rc;  }  p->pBt = pBt;  sqlite3pager_set_destructor(pBt->pPager, pageDestructor);  sqlite3pager_set_reiniter(pBt->pPager, pageReinit);  pBt->pCursor = 0;  pBt->pPage1 = 0;  pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);  pBt->pageSize = get2byte(&zDbHeader[16]);  if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE       || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){    pBt->pageSize = SQLITE_DEFAULT_PAGE_SIZE;    pBt->maxEmbedFrac = 64;   /* 25% */    pBt->minEmbedFrac = 32;   /* 12.5% */    pBt->minLeafFrac = 32;    /* 12.5% */#ifndef SQLITE_OMIT_AUTOVACUUM    /* If the magic name ":memory:" will create an in-memory database, then    ** do not set the auto-vacuum flag, even if SQLITE_DEFAULT_AUTOVACUUM    ** is true. On the other hand, if SQLITE_OMIT_MEMORYDB has been defined,    ** then ":memory:" is just a regular file-name. Respect the auto-vacuum    ** default in this case.    */    if( zFilename && !isMemdb ){      pBt->autoVacuum = SQLITE_DEFAULT_AUTOVACUUM;    }#endif    nReserve = 0;  }else{    nReserve = zDbHeader[20];    pBt->maxEmbedFrac = zDbHeader[21];    pBt->minEmbedFrac = zDbHeader[22];    pBt->minLeafFrac = zDbHeader[23];    pBt->pageSizeFixed = 1;#ifndef SQLITE_OMIT_AUTOVACUUM    pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);#endif  }  pBt->usableSize = pBt->pageSize - nReserve;  assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */  sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)  /* Add the new btree to the linked list starting at ThreadData.pBtree.  ** There is no chance that a malloc() may fail inside of the   ** sqlite3ThreadData() call, as the ThreadData structure must have already  ** been allocated for pTsdro->useSharedData to be non-zero.  */  if( pTsdro->useSharedData && zFilename && !isMemdb ){    pBt->pNext = pTsdro->pBtree;    sqlite3ThreadData()->pBtree = pBt;  }#endif  pBt->nRef = 1;  *ppBtree = p;  return SQLITE_OK;}/*** Close an open database and invalidate all cursors.*/int sqlite3BtreeClose(Btree *p){  BtShared *pBt = p->pBt;  BtCursor *pCur;#ifndef SQLITE_OMIT_SHARED_CACHE  ThreadData *pTsd;#endif  /* Close all cursors opened via this handle.  */  pCur = pBt->pCursor;  while( pCur ){    BtCursor *pTmp = pCur;    pCur = pCur->pNext;    if( pTmp->pBtree==p ){      sqlite3BtreeCloseCursor(pTmp);    }  }  /* Rollback any active transaction and free the handle structure.  ** The call to sqlite3BtreeRollback() drops any table-locks held by  ** this handle.  */  sqlite3BtreeRollback(p);  sqliteFree(p);#ifndef SQLITE_OMIT_SHARED_CACHE  /* If there are still other outstanding references to the shared-btree  ** structure, return now. The remainder of this procedure cleans   ** up the shared-btree.  */  assert( pBt->nRef>0 );  pBt->nRef--;  if( pBt->nRef ){    return SQLITE_OK;  }  /* Remove the shared-btree from the thread wide list. Call   ** ThreadDataReadOnly() and then cast away the const property of the   ** pointer to avoid allocating thread data if it is not really required.  */  pTsd = (ThreadData *)sqlite3ThreadDataReadOnly();  if( pTsd->pBtree==pBt ){    assert( pTsd==sqlite3ThreadData() );    pTsd->pBtree = pBt->pNext;  }else{    BtShared *pPrev;    for(pPrev=pTsd->pBtree; pPrev && pPrev->pNext!=pBt; pPrev=pPrev->pNext){}    if( pPrev ){      assert( pTsd==sqlite3ThreadData() );      pPrev->pNext = pBt->pNext;    }  }#endif  /* Close the pager and free the shared-btree structure */  assert( !pBt->pCursor );  sqlite3pager_close(pBt->pPager);  if( pBt->xFreeSchema && pBt->pSchema ){    pBt->xFreeSchema(pBt->pSchema);  }  sqliteFree(pBt->pSchema);  sqliteFree(pBt);  return SQLITE_OK;}/*** Change the busy handler callback function.*/int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){  BtShared *pBt = p->pBt;  pBt->pBusyHandler = pHandler;  sqlite3pager_set_busyhandler(pBt->pPager, pHandler);  return SQLITE_OK;}/*** Change the limit on the number of pages allowed in the cache.**** The maximum number of cache pages is set to the absolute** value of mxPage.  If mxPage is negative, the pager will** operate asynchronously - it will not stop to do fsync()s** to insure data is written to the disk surface before** continuing.  Transactions still work if synchronous is off,** and the database cannot be corrupted if this program** crashes.  But if the operating system crashes or there is** an abrupt power failure when synchronous is off, the database** could be left in an inconsistent and unrecoverable state.** Synchronous is on by default so database corruption is not** normally a worry.*/int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){  BtShared *pBt = p->pBt;  sqlite3pager_set_cachesize(pBt->pPager, mxPage);  return SQLITE_OK;}/*** Change the way data is synced to disk in order to increase or decrease** how well the database resists damage due to OS crashes and power** failures.  Level 1 is the same as asynchronous (no syncs() occur and** there is a high probability of damage)  Level 2 is the default.  There** is a very low but non-zero probability of damage.  Level 3 reduces the** probability of damage to near zero but with a write performance reduction.*/#ifndef SQLITE_OMIT_PAGER_PRAGMASint sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){  BtShared *pBt = p->pBt;  sqlite3pager_set_safety_level(pBt->pPager, level, fullSync);  return SQLITE_OK;}#endif/*** Return TRUE if the given btree is set to safety level 1.  In other** words, return TRUE if no sync() occurs on the disk files.*/int sqlite3BtreeSyncDisabled(Btree *p){  BtShared *pBt = p->pBt;  assert( pBt && pBt->pPager );  return sqlite3pager_nosync(pBt->pPager);}#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)/*** Change the default pages size and the number of reserved bytes per page.**** The page size must be a power of 2 between 512 and 65536.  If the page** size supplied does not meet this constraint then the page size is not** changed.**** Page sizes are constrained to be a power of two so that the region** of the database file used for locking (beginning at PENDING_BYTE,** the first byte past the 1GB boundary, 0x40000000) needs to occur** at the beginning of a page.**** If parameter nReserve is less than zero, then the number of reserved** bytes per page is left unchanged.*/int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){  BtShared *pBt = p->pBt;  if( pBt->pageSizeFixed ){    return SQLITE_READONLY;  }  if( nReserve<0 ){    nReserve = pBt->pageSize - pBt->usableSize;  }  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&        ((pageSize-1)&pageSize)==0 ){    assert( (pageSize & 7)==0 );    assert( !pBt->pPage1 && !pBt->pCursor );    pBt->pageSize = sqlite3pager_set_pagesize(pBt->pPager, pageSize);  }  pBt->usableSize = pBt->pageSize - nReserve;  return SQLITE_OK;}/*** Return the currently defined page size*/int sqlite3BtreeGetPageSize(Btree *p){  return p->pBt->pageSize;}int sqlite3BtreeGetReserve(Btree *p){  return p->pBt->pageSize - p->pBt->usableSize;}#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) *//*** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it** is disabled. The default value for the auto-vacuum property is ** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.*/int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){  BtShared *pBt = p->pBt;;#ifdef SQLITE_OMIT_AUTOVACUUM  return SQLITE_READONLY;#else  if( pBt->pageSizeFixed ){    return SQLITE_READONLY;  }  pBt->autoVacuum = (autoVacuum?1:0);  return SQLITE_OK;#endif}/*** Return the value of the 'auto-vacuum' property. If auto-vacuum is ** enabled 1 is returned. Otherwise 0.*/int sqlite3BtreeGetAutoVacuum(Btree *p){#ifdef SQLITE_OMIT_AUTOVACUUM  return 0;#else  return p->pBt->autoVacuum;#endif}/*** Get a reference to pPage1 of the database file.  This will** also acquire a readlock on that file.**** SQLITE_OK is returned on success.  If the file is not a** well-formed database file, then SQLITE_CORRUPT is returned.** SQLITE_BUSY is returned if the database is locked.  SQLITE_NOMEM** is returned if we run out of memory.  SQLITE_PROTOCOL is returned** if there is a locking protocol violation.*/static int lockBtree(BtShared *pBt){  int rc, pageSize;  MemPage *pPage1;  if( pBt->pPage1 ) return SQLITE_OK;  rc = getPage(pBt, 1, &pPage1);  if( rc!=SQLITE_OK ) return rc;    /* Do some checking to help insure the file we opened really is  ** a valid database file.   */  rc = SQLITE_NOTADB;  if( sqlite3pager_pagecount(pBt->pPager)>0 ){    u8 *page1 = pPage1->aData;    if( memcmp(page1, zMagicHeader, 16)!=0 ){      goto page1_init_failed;    }    if( page1[18]>1 || page1[19]>1 ){      goto page1_init_failed;    }    pageSize = get2byte(&page1[16]);    if( ((pageSize-1)&pageSize)!=0 ){      goto page1_init_failed;    }    assert( (pageSize & 7)==0 );    pBt->pageSize = pageSize;    pBt->usableSize = pageSize - page1[20];    if( pBt->usableSize<500 ){      goto page1_init_failed;    }    pBt->maxEmbedFrac = page1[21];    pBt->minEmbedFrac = page1[22];    pBt->minLeafFrac = page1[23];#ifndef SQLITE_OMIT_AUTOVACUUM    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);#endif  }  /* maxLocal is the maximum amount of payload to store locally for  ** a cell.  Make sure it is small enough so that at least minFanout  ** cells can will fit on one page.  We assume a 10-byte page header.  ** Besides the payload, the cell must store:  **     2-byte pointer to the cell  **     4-byte child pointer  **     9-byte nKey value  **     4-byte nData value  **     4-byte overflow page pointer  ** So a cell consists of a 2-byte poiner, a header which is as much as  ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte ove

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -