B树

来源:互联网 发布:淘宝童装批发怎么宣传 编辑:程序博客网 时间:2024/05/26 22:59

#ifndef _TREE_H
#define _TREE_H


#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "assert.h"

typedef struct Btree Btree;
typedef struct Cell Cell;
typedef struct Cursor Cursor;
typedef struct Pool Pool;
typedef unsigned int u16;
typedef unsigned char u8;

struct Cell{
 char aPayLoad[8];
 Pool* leftChild;//左孩子
 u16 iNext;//下一个Cell
 //key和data
};
struct PoolHead{
 Pool* rightChild;//右孩子
 u16 firstFree;//第一个空闲块
 u16 firstCell;//第一个Cell
};

struct PoolArray{
 Pool* k[500];
 u8 tag[500];
 u8 n;
};
#define MAX_LENGTH 1024 
struct Pool{
 union{
  PoolHead h;
  char aDisk[1024+2];
 }u;
 Pool* pParent;
 Cell* apCell[1024/8];//访问点
 u16  nCell;
 u16 nFree;
 u8 isOverfull;
 u8 isInit;
 u8 idxShift;//如果apCell[]中的索引发生了变化
 u8 idxParent;
};
struct Cursor{//指向一个记录
 Btree* pBt;
 Pool* pPool;
 u16 idx;
};
struct Btree{
 Pool* root;
 int nPool;
 PoolArray Number;
};
struct FreeBlk {
  u16 iSize;      /* 在这个块中自由空间的字节数目?*/
  u16 iNext;      /* 下一个自由块的.u.aDisk[]的索引 */
};
void CreateBtree(Btree** ppBt,size_t nPool);//创建一个Btree
void DestroyBtree(Btree* pBt);//释放一个Btree
void zeroPool(Pool* pPool);
void initPool(Pool* pPool,Pool* pParent);
void mallocPool(Btree* pBt,Pool**ppPool);
void freePool(Btree* pBt,Pool* pPool);
int mallocCell(Pool* pPool,int sz);
void fillInCell(Cell* pCell,const void* pKey,int nKey,const void* pData,int nData);
void refragmentpool(Pool* pPool);
void initCursor(Btree* pBt,Cursor* pCur);
void movetoroot(Cursor* pCur);
void movetochild(Cursor* pCur);
int  moveto(Cursor* pCur,const void* pKey,int nKey);
void relinkCell(Pool*pPool);
void insertCell(Pool* pPool,Cell* pCell,int i,int sz);
void reparent( Pool* pChild, Pool *pNewParent,int idx);
void reparentChild(Btree *pBt, Pool *pPool);
void copyPool(Pool *pTo, Pool *pFrom);
void balance(Btree *pBt, Pool *pPool);
void dropCell(Btree *pBt, Pool *pPool, int idx, int sz);
void freeSpace(Btree *pBt, Pool *pPool, int start, int size);
int BtreeInsert(Cursor *pCur,const void *pKey,int nKey,const void *pData,int nData);
void Test(Pool* pPool,int high);
void BtreeDell(Cursor* pCur,Btree* pBt,const void * pKey,int nKey);

 

 

 

#endif

 

#include "tree.h"

void CreateBtree(Btree** ppBt,size_t nPool){
 (*ppBt)=(Btree*)malloc(sizeof(Btree));
 (*ppBt)->root=(Pool*)malloc(sizeof(Pool));
 zeroPool((*ppBt)->root);
 initPool((*ppBt)->root,0);//父亲页
 (*ppBt)->nPool=nPool>10?nPool:nPool;
 for(size_t i=0;i<nPool;i++){
  (*ppBt)->Number.k[i]=(Pool*)malloc(sizeof(Pool));
  (*ppBt)->Number.tag[i]=0;
  
  zeroPool((*ppBt)->Number.k[i]);
 }
 (*ppBt)->Number.n=nPool;
}

void DestroyBtree(Btree* pBt){
 for(int i=0;i<pBt->nPool;i++){
  //printf("%d/n",i);
  free(pBt->Number.k[i]);
 }
 free(pBt->root);
 free(pBt);
}

void zeroPool(Pool* pPool){
 int hdr_sz=sizeof(PoolHead);
 FreeBlk* pFree;
 memset(pPool,0,1024);
 pPool->u.h.rightChild=0;
 pPool->u.h.firstCell=0;
 pPool->u.h.firstFree=hdr_sz;

 pFree=(FreeBlk*)&(pPool->u.aDisk[hdr_sz]);
 pFree->iNext=0; 
 pFree->iSize=1024-hdr_sz;

 pPool->isOverfull=0;
 pPool->isInit=0;
 pPool->nCell=0;
 pPool->nFree=1024-hdr_sz;
 pPool->pParent=0;

}

void initPool(Pool* pPool,Pool* pParent){
 if(pPool->pParent) return ;
 if(pParent){
  pPool->pParent=pParent;
 }
 if(pPool->isInit)return ;

 pPool->isInit=1;
 pPool->nCell=0;
 
 u16 freespace=1024-sizeof(PoolHead);
 u16 idx=pPool->u.h.firstCell;
 while(idx!=0){//
  Cell* pCell=(Cell*)pPool->u.aDisk[idx];
  freespace-=sizeof(Cell);
  pPool->apCell[pPool->nCell++]=pCell;
  idx=pCell->iNext;
 }
 pPool->nFree=0;
 idx=pPool->u.h.firstFree;
 while(idx!=0){
  FreeBlk* pFBlk=(FreeBlk*)&pPool->u.aDisk[idx];
  pPool->nFree+=pFBlk->iSize;
  idx=pFBlk->iNext;
 }
}


void mallocPool(Btree* pBt,Pool** ppPool){
 for(int i=0;i<pBt->nPool;i++){
  if(!pBt->Number.tag[i]){
    (*ppPool)=pBt->Number.k[i];
    pBt->Number.tag[i]=1;
  }else{
   continue;
  }
 }
 (pBt)->Number.k[pBt->nPool]=(Pool*)malloc(sizeof(Pool));
  (pBt)->Number.tag[pBt->nPool]=0;
  pBt->nPool++;
  zeroPool((pBt)->Number.k[pBt->nPool-1]);
  (*ppPool)=(pBt)->Number.k[pBt->nPool-1];
  //assert(pBt->nPool<50);

}
void freePool(Btree* pBt,Pool* pPool){
 for(int i=0;i<pBt->nPool;i++){
  if(pBt->Number.k[i]==pPool){
   pBt->Number.tag[i]=0;
   return ;
  }
 }
}


int  mallocCell(Pool* pPool,int sz){
 FreeBlk* pFree;
 u16* pIdx=&pPool->u.h.firstFree;
 u16 start=0;
 u16 iSize;
 //printf("/n%d/n",pPool->nFree);
 //assert(pPool->nFree>sz);
 if(pPool->nFree<sz)
  return -1;
 pFree=(FreeBlk*)&pPool->u.aDisk[*pIdx];
 while((iSize=pFree->iSize)<sz){
  if(pFree->iNext==0){
   refragmentpool(pPool);
   pIdx=&pPool->u.h.firstFree;
  }else{
   pIdx=&pFree->iNext;
  }
  pFree=(FreeBlk*)&pPool->apCell[*pIdx];
 }
 //assert(pFree->iSize>=sz);

 if(iSize==sz){
  start=*pIdx;
  *pIdx=pFree->iNext;
 }else{
  start=*pIdx;
  FreeBlk* pNew=(FreeBlk*)&pPool->u.aDisk[start+sz];
  pNew->iNext=pFree->iNext;
  pNew->iSize=iSize-sz;
  
  *pIdx=(start+sz);
 }
 pPool->nFree-=sz;
 return start;
}


void refragmentpool(Pool* pPool){
 //assert(1);
 char aux[1024];
 u16 paux=0;
 paux=sizeof(PoolHead);
 memcpy(aux,pPool,paux);
 for(u16 i=0;i<pPool->nCell;i++){
  Cell* pCell=pPool->apCell[i];
  memcpy(aux+paux,pCell,sizeof(Cell));
  pPool->apCell[i]=(Cell*)&pPool->u.aDisk[paux];
  paux+=sizeof(Cell);
 }
 memcpy(pPool,aux,paux);

 pPool->u.h.firstCell=sizeof(PoolHead);
 if(pPool->nCell>0){
  pPool->apCell[pPool->nCell-1]->iNext=0;
 }

 FreeBlk*  pFree=(FreeBlk*)&pPool->u.aDisk[paux];
 pFree->iSize=1024-paux;
 pFree->iNext=0;
 pPool->u.h.firstCell=paux;
 memset(&pFree[i],0,1024-paux-sizeof(FreeBlk));
}

void fillInCell(Cell* pCell,const void* pKey,int nKey,const void* pData,int nData){
 pCell->iNext=0;
 pCell->leftChild=0;
 memcpy(pCell->aPayLoad,pKey,nKey);
 memcpy(pCell->aPayLoad+nKey,pData,nData);
}
//cursor的初始化
void initCursor(Btree* pBt,Cursor* pCur){
 pCur->idx=0;
 pCur->pBt=pBt;
 pCur->pPool=0;
}

void movetoroot(Cursor* pCur){
 pCur->pPool=pCur->pBt->root;
 pCur->idx=0;
}

void movetochild(Cursor* pCur){
 if(pCur->idx>=pCur->pPool->nCell){
  pCur->pPool=pCur->pPool->u.h.rightChild;
  pCur->idx=0;
 }else{
  pCur->pPool=pCur->pPool->apCell[pCur->idx]->leftChild;
 }
}


int  moveto(Cursor* pCur,const void* pKey,int nKey){
 movetoroot(pCur);
 int c=-1;
 for(;;){
  Pool* pPool=pCur->pPool;
  int low=0;
  int high=pPool->nCell-1;
  while(low<=high){
   pCur->idx=(low+high)/2;
   c=memcmp(pPool->apCell[pCur->idx],pKey,nKey);
   if(c==0)return 0;
   if(c<0)low=pCur->idx+1;
   if(c>0) high=pCur->idx-1;
  }
  //printf("/n%d/n",c);
  //assert(c<0);
  if(low>=pPool->nCell){

   pPool=pPool->u.h.rightChild;
  }else{
   pPool=pPool->apCell[low]->leftChild;
  }
  if(pPool==0){
  // pCur->idx=low;
   return c;
  }
  pCur->idx=low;
  movetochild(pCur);
 }
}
typedef unsigned int uptr;
#define Addr(X)  ((uptr)X)
void relinkCell(Pool* pPool){
 u16 idx;
 u16* pIdx=&pPool->u.h.firstCell;
 for(int  i=0;i<pPool->nCell;i++){
  idx=Addr(pPool->apCell[i])-Addr(pPool);
  *pIdx=idx;
  pIdx=&pPool->apCell[i]->iNext;
 }
}

void insertCell(Pool* pPool,Cell* pCell,int i,int sz){
 int idx=mallocCell(pPool,sz);
//assert(idx>0);
 for(int j=pPool->nCell;j>i;j--){
  pPool->apCell[j]=pPool->apCell[j-1];
 }
 pPool->nCell++;

 if(idx<0){
  pPool->isOverfull=1;
  pPool->apCell[i]=pCell;
 }else{
  //??????????????assert(sz!=16);
  memcpy(&pPool->u.aDisk[idx],pCell,sz);
  pPool->apCell[i]=(Cell*)&pPool->u.aDisk[idx];
  //assert(pPool->apCell[i]!=0);
 }
 pPool->idxShift=1;
}

void reparent( Pool* pChild, Pool *pNewParent,int idx){
  Pool *pThis;
  pThis = pChild;
  if( pThis && pThis->isInit ){
    if( pThis->pParent!=pNewParent ){
      pThis->pParent = pNewParent;
    }
    pThis->idxParent = idx;//他在父亲的apCell[]中的位置
  }
}

void reparentChild(Btree *pBt, Pool *pPool){
  int i;
  for(i=0; i<pPool->nCell; i++){
    reparent(pPool->apCell[i]->leftChild, pPool, i);
  }
  reparent( pPool->u.h.rightChild, pPool, i);
  pPool->idxShift = 0;
}

void copyPool(Pool *pTo, Pool *pFrom){
  uptr from, to;//uptr
  int i;
  memcpy(pTo->u.aDisk, pFrom->u.aDisk, 1024);
  pTo->pParent = 0;
  pTo->isInit = 1;
  pTo->nCell = pFrom->nCell;
  pTo->nFree = pFrom->nFree;
  pTo->isOverfull = pFrom->isOverfull;
  to = Addr(pTo);
  from = Addr(pFrom);
//调整pTo->apCell[]中的指针,
  for(i=0; i<pTo->nCell; i++){
    uptr x = Addr(pFrom->apCell[i]);
    if( x>from && x<from+1024 ){
      *((uptr*)&pTo->apCell[i]) =to+( x  - from);
    }else{//那些溢出的页码
      pTo->apCell[i] = pFrom->apCell[i];
    }
  }
}
#define NN 1             /* Number of neighbors on either side of pPage */
#define NB (NN*2+1)      /* Total pages involved in the balance */

void balance(Btree *pBt, Pool *pPool){
  Pool *pParent;            /* The parent of pPage */
  int nCell;                   /* Number of cells in apCell[] */
  int nOld;                    /* Number of pages in apOld[] */
  int nNew;                    /* Number of pages in apNew[] */
  int nDiv;                    /* Number of cells in apDiv[] */
 
  int idx;                     /* Index of pPage in pParent->apCell[] */
  int nxDiv;                   /* Next divider slot in pParent->apCell[] */
  int subtotal;                /* Subtotal of bytes in cells on one page */
  Pool *extraUnref = 0;     /* A page that needs to be unref-ed */
  Pool *apOld[NB];          /* pPage and up to two siblings */
  Pool *apNew[NB+1];        /* pPage and up to NB siblings after balancing */
  int idxDiv[NB];              /* Indices of divider cells in pParent */
  Cell *apDiv[NB];             /* Divider cells in pParent */
  Cell aTemp[NB];              /* Temporary holding area for apDiv[] */
  int cntNew[NB+1];            /* Index in apCell[] of cell after i-th page */
  int szNew[NB+1];             /* Combined size of cells place on i-th page */
  Pool aOld[NB];            /* Temporary copies of pPage and its siblings */
  Cell *apCell[200]; /* All cells from pages being balanced */
  int szCell[200];  /* Local size of all cells */
int i,j,k;                 /* Loop counters */
  Pool* PoolOld[NB];
  Pool* PoolNew[NB+1];
  if( !pPool->isOverfull && pPool->nFree<512 && pPool->nCell>=2){
    relinkCell(pPool);
    return ;
  }

  pParent = pPool->pParent;
  if( pParent==0 ){//
    Pool *pChild;
    if( pPool->nCell==0 ){
      if(pPool->u.h.rightChild){
  pChild=pPool->u.h.rightChild;
        memcpy(pPool, pChild, 1024);
        pPool->isInit = 0;
        initPool(pPool,0);
        reparentChild(pBt, pPool);

        freePool(pBt, pChild);
      }else{
        relinkCell( pPool);
      }
      return  ;
    }
    if( !pPool->isOverfull ){
      relinkCell( pPool);
      return  ;
    }
//分配一个新页
    mallocPool(pBt, &pChild);
    copyPool(pChild, pPool);
    pChild->pParent = pPool;
    //pChild->idxParent = 0;

    pChild->isOverfull = 1;

    zeroPool(pPool);
    pPool->u.h.rightChild = pChild;
    pParent = pPool;
    pPool = pChild;
  }
 //到这个地方说明pPage已经不是根页了
  /*
  ** 在parent页中查找一个Cell,他的h.leftChild指向pPage,idx就是cell的下标,
  如果pPage是pParent最右边的孩子,那么设置idx为pParen->nCell
  */
 
    for(idx=0; idx<pParent->nCell; idx++){
      if( pParent->apCell[idx]->leftChild==pPool ){
        break;
      }
    }
 

  nOld = nNew = 0;
 
  nxDiv = idx - NN;
  if( nxDiv + NB > pParent->nCell ){
    nxDiv = pParent->nCell - NB + 1;
  }
  if( nxDiv<0 ){
    nxDiv = 0;
  }
  nDiv = 0;

  for(i=0, k=nxDiv; i<NB; i++, k++){
    if( k<pParent->nCell ){
      idxDiv[i] = k;//记录下来pPool和他的兄弟们在pParent中的索引
      apDiv[i] = pParent->apCell[k];//记录下来pPool和他的兄弟们在pParent中的cell
      nDiv++;//记录在apDiv[]中记录的个数
      PoolOld[i] = apDiv[i]->leftChild;////记录下来pPool和他的兄弟们
   apOld[i]=apDiv[i]->leftChild;
    }else if( k==pParent->nCell ){
  apOld[i]=pParent->u.h.rightChild;
  PoolOld[i]=pParent->u.h.rightChild;
    }else{
      break;
    }
 if(apOld[i]==0){
  mallocPool(pBt,&apOld[i]);
 }

   initPool( apOld[i], pParent);
   //apOld[i]->idxParent = k;
    nOld++;//记录老叶的个数
  }
  for(i=0; i<nOld; i++){
    copyPool(&aOld[i], apOld[i]);
  }


  nCell = 0;
  for(i=0; i<nOld; i++){
    Pool *pOld = &aOld[i];//保存的是老页pPage和他的兄弟的内容
    for(j=0; j<pOld->nCell; j++){
      apCell[nCell] = pOld->apCell[j];
      szCell[nCell] = sizeof(Cell);//保存每一个Cell的大小
      nCell++;
    }
    if( i<nOld-1 ){
      szCell[nCell] =sizeof(Cell);
   //???????????????????
      memcpy(&aTemp[i], apDiv[i], szCell[nCell]);//把分裂的Cells拷到aTemp[]中
      apCell[nCell] = &aTemp[i];
      dropCell(pBt, pParent, nxDiv, szCell[nCell]);//从pParent中移出分裂的Cells
      apCell[nCell]->leftChild = pOld->u.h.rightChild;
      nCell++;
    }
  }
//将nCell个Cells分配到k个页,这不要求均匀的,前面几个页的尽量放,最后一个页或许不满
  for(subtotal=k=i=0; i<nCell; i++){
    subtotal += szCell[i];
    if( subtotal > 1024-sizeof(PoolHead) ){
      szNew[k] = subtotal - szCell[i];
      cntNew[k] = i;
      subtotal = 0;
      k++;
    }
  }
  szNew[k] = subtotal;
  cntNew[k] = nCell;
  k++;
  for(i=k-1; i>0; i--){
    while( szNew[i]<(1024-sizeof(PoolHead))/2 ){
      cntNew[i-1]--;
      szNew[i] += szCell[cntNew[i-1]];
      szNew[i-1] -= szCell[cntNew[i-1]-1];
    }
  }
  /*
  ** Allocate k new pages.  Reuse old pages where possible.
  */
  for(i=0; i<k; i++){
    if( i<nOld ){
      apNew[i] = apOld[i];
     PoolNew[i] = PoolOld[i];
      apOld[i] = 0;
 
    }else{
       mallocPool(pBt, &apNew[i]);
  PoolNew[i]=apNew[i];
    }
    nNew++;
    zeroPool( apNew[i]);
    apNew[i]->isInit = 1;
  }

  /* Free any old pages that were not reused as new pages.
  */
  while( i<nOld ){
  
 freePool(pBt,apOld[i]);
    apOld[i] = 0;
    i++;
  }


  /*
  ** Evenly distribute the data in apCell[] across the new pages.
  ** Insert divider cells into pParent as necessary.
  */
  j = 0;
  for(i=0; i<nNew; i++){
    Pool *pNew = apNew[i];
    while( j<cntNew[i] ){
      insertCell(pNew,  apCell[j],pNew->nCell, szCell[j]);
      j++;
    }
    relinkCell( pNew);
    if( i<nNew-1 && j<nCell ){
      pNew->u.h.rightChild = apCell[j]->leftChild;
      apCell[j]->leftChild =PoolNew[i];
      insertCell( pParent, apCell[j],nxDiv,  szCell[j]);
      j++;
      nxDiv++;
    }
  }
  apNew[nNew-1]->u.h.rightChild = aOld[nOld-1].u.h.rightChild;
  if( nxDiv==pParent->nCell ){
    pParent->u.h.rightChild =PoolNew[nNew-1];
  }else{
    pParent->apCell[nxDiv]->leftChild = PoolNew[nNew-1];
  }

 
  for(i=0; i<nNew; i++){
    reparentChild(pBt, apNew[i]);
  }
  reparentChild(pBt, pParent);

 
 balance(pBt, pParent);

  return ;
}

 void freeSpace(Btree *pBt, Pool *pPool, int start, int size){
  int end = start + size;//记录一下结束的位置
  u16 *pIdx;
  u16 idx;
  FreeBlk *pFBlk;
  FreeBlk *pNew;
  FreeBlk *pNext;
  int iSize;


  pIdx = &pPool->u.h.firstFree;//pIdx指向第一个空闲块下标
  idx =  *pIdx;//第一个自由块的下标
// ------------------------------------------------------------------------------------
//  |  PageHdr | Cell     |Cell| Cell | ... | first FreeBlk |Cell|……|将要释放的空闲块
// ------------------------------------------------------------------------------------
  while( idx!=0 && idx<start ){//空闲块的下标还在start之前
    pFBlk = (FreeBlk*)&pPool->u.aDisk[idx];
    iSize =pFBlk->iSize;//记录一下pFBlk块的大小
// ------------------------------------------------------------------------------------
//  |  PageHdr | Cell     |Cell| Cell | ... | first FreeBlk(头部信息) |第一个空闲块|将要被释放的

//空闲块|………………
// ------------------------------------------------------------------------------------
    if( idx + iSize == start ){//被释放的空闲块恰好在两个空闲块之间
      pFBlk->iSize =iSize + size;
      if( idx + iSize + size ==  pFBlk->iNext){
// ------------------------------------------------------------------------------------
//  |  PageHdr | Cell     |Cell| Cell | ... | first FreeBlk(头部信息) |第一个空闲块|将要被释放的

//空闲块|空闲块|
// ------------------------------------------------------------------------------------
        pNext = (FreeBlk*)&pPool->u.aDisk[idx + iSize + size];

          pFBlk->iSize += pNext->iSize;
     
        pFBlk->iNext = pNext->iNext;
      }
// ------------------------------------------------------------------------------------
//  |  PageHdr | Cell     |Cell| Cell | ... | first FreeBlk(头部信息) |第一个空闲块|将要被释放的

//空闲块|Cell|………………
// ------------------------------------------------------------------------------------
      pPool->nFree += size;
      return;
    }
// ------------------------------------------------------------------------------------
//  |  PageHdr | Cell     |Cell| Cell | ... | first FreeBlk |Cell|…|FreeBld|…|将要释放的空闲块
// ------------------------------------------------------------------------------------
//找到离将要被释放的块最近的那个块,当
    pIdx = &pFBlk->iNext;
    idx = *pIdx;
  }
//将要被释放的空闲块
//当到这个地方的时候,将要被释放的空闲块找到了需要放的地方
  pNew = (FreeBlk*)&pPool->u.aDisk[start];
  if( idx != end ){//要释放的空闲块与已经在空闲表空闲块是不相邻的;
// ----------------------------------------------------------------------//将要释放的空闲块|  …

//…|释放的空闲块之后的第一个自由块
// ------------------------------------------------------------------------------------
//
    pNew->iSize =  size;
    pNew->iNext = idx;//将原来的自由块放到第二个位置
  }else{//要释放的空闲块与空闲块相邻的;
// ------------------------------------------------------------------------------------
//  |  PageHdr | Cell     |Cell| Cell | ... | first FreeBlk |Cell|…|FreeBld|…|将要释放的空闲块|

//释放的空闲块之后的第一个自由块
// ------------------------------------------------------------------------------------
    pNext = (FreeBlk*)&pPool->u.aDisk[idx];//原来的自由块
    pNew->iSize =  size + pNext->iSize;
    pNew->iNext = pNext->iNext;
  }
  *pIdx = start;
  pPool->nFree += size;
}

 void dropCell(Btree *pBt, Pool *pPool, int idx, int sz){
  int j;
 
//删除start=Addr(pPool->apCell[idx]) - Addr(pPool),size=sz
  freeSpace(pBt, pPool, Addr(pPool->apCell[idx]) - Addr(pPool), sz);
  for(j=idx; j<pPool->nCell-1; j++){//仅仅维护了apCell[]
    pPool->apCell[j] = pPool->apCell[j+1];
  }
  pPool->nCell--;
  pPool->idxShift = 1;//表示apCell[]中的元素被移动过
}

 int BtreeInsert(
  Cursor *pCur,                /* Insert data into the table of this cursor */
  const void *pKey, int nKey,    /* The key of the new record */
  const void *pData, int nData   /* The data of the new record */
){
  Cell newCell;//新的Cell
  int rc;//返回值
  int loc;
  int szNew=sizeof(newCell);
  Pool* pPool;
 
  Btree *pBt = pCur->pBt;

  if( pCur->pPool==0 ){
    return 0;  /* A rollback destroyed this cursor */
  }
 
//把pCur移动到pKey的位置,结果都在loc里面
   loc=moveto(pCur, pKey, nKey);
  pPool = pCur->pPool;
  int idx=pCur->idx;
//填充一个新的Cell
  fillInCell( &newCell, pKey, nKey,pData,nData);
  //pCur->idx=idx;
  if( loc==0 ){//准确匹配的话,删除原来的页。
    newCell.leftChild= pPool->apCell[pCur->idx]->leftChild;
    dropCell(pBt, pPool, pCur->idx, szNew);
  }else if( loc<0 && pPool->nCell>0 ){//插入只能在页节点上做的,左孩子
    //assert( pNode->u.hdr.rightChild==0 );  /* Must be a leaf page */
    pCur->idx++;
  }else{
    //assert( pNode->u.hdr.rightChild==0 );  /* Must be a leaf page */
  }
 insertCell(pPool,&newCell,pCur->idx, szNew);
 //printf("%d/n",*(int*)(pKey));

 balance(pCur->pBt, pPool);
  return rc;
}
inline int GetKey(Cell* pCell){
  int x;
  memcpy(&x,pCell->aPayLoad,4);
  return x;
 }
 void Test(Pool* pPool,int high){
  if(pPool==0){
   return ;
  }
  int i;
  for( i=0;i<pPool->nCell;i++){
   Test(pPool->apCell[i]->leftChild,high+1); 
   //printf("%c/n",'c');
  }
  Test(pPool->u.h.rightChild,high+1);
  printf("深度为%d:/n",high);
  for( i=0;i<pPool->nCell;i++){
   printf("%d,",GetKey(pPool->apCell[i]));
  }
  printf("/n%d/n",pPool->nCell);
  /*  for( i=0;i<pPool->nCell;i++){
    if(GetKey(pPool->apCell[i])==99)
   printf("%d,",GetKey(pPool->apCell[i]));*/
 

 }
 void BtreeDell(Cursor* pCur,Btree* pBt,const void * pKey,int nKey){
  int rc=moveto(pCur,pKey,nKey);
  if(rc==0){
   dropCell(pBt, pCur->pPool, pCur->idx, sizeof(Cell));
  }
 }

  


 

原创粉丝点击