void *Undo_Do_Block_Split( struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack, int realline, void *pointer ){ struct Undo_Block_MergeSplit *ubm=(struct Undo_Block_MergeSplit *)pointer; struct WBlocks *wblocktemp=NULL; if(ubm->nwblock==NULL){ //Undo ubm->nwblock=CB_CopyBlock(wblock); // wblocktemp=CB_CopyBlock((struct WBlocks*)ListPrevElement1(&window->wblocks->l,&wblock->l)); wblocktemp=CB_CopyBlock(NextWBlock(wblock)); CB_PasteBlock(window,ubm->wblock,wblock); DeleteBlock(ubm->blockpos+1); ubm->wblock=wblocktemp; }else{ //Redo InsertBlock(ubm->blockpos,20,20,"n"); wblocktemp=CB_CopyBlock(wblock); CB_PasteBlock(window,ubm->wblock,wblock); CB_PasteBlock(window,ubm->nwblock,(struct WBlocks*)ListPrevElement1(&window->wblocks->l,&wblock->l)); ubm->wblock=wblocktemp; ubm->nwblock=NULL; } BS_UpdateBlockList(); BS_UpdatePlayList(); return ubm; }
struct Blocks *InsertBlock_CurrPos( struct Tracker_Windows *window ) { struct WBlocks *wblock=window->wblock; NInt blockpos=wblock->l.num; ADD_UNDO(Block_Insert(blockpos)); struct Blocks *ret; PC_Pause();{ ret = InsertBlock(blockpos,wblock->block->num_tracks,wblock->block->num_lines,"NN"); SelectWBlock(window,(struct WBlocks *)ListFindElement1(&window->wblocks->l,blockpos)); BS_UpdateBlockList(); BS_UpdatePlayList(); }PC_StopPause(window); return ret; }
bool wxSheetSelection::SelectBlock( const wxSheetBlock &block, bool combineNow, wxArraySheetBlock *addedBlocks ) { if (block.IsEmpty()) return false; wxArraySheetBlock extraBlocks; wxArraySheetBlock *extra = &extraBlocks; if (addedBlocks) { extra = addedBlocks; extra->Clear(); } extra->Add(block); int extra_count = 1; int n, k, count = m_blocks.GetCount(); if (((m_options & wxSHEET_SELECTION_MULTIPLE_SEL) == 0) && (count > 0) && m_bounds.Intersects(block)) { const int bottom_row = block.GetBottom(); wxSheetBlock top, bottom, left, right; // interate though blocks breaking up input block if it's already selected for (n=FindTopRow(bottom_row); n<count; n++) { if (bottom_row < m_blocks[n].GetTop()) break; for (k=0; k<extra_count; k++) { const int combined = m_blocks[n].Combine(extra->Item(k), top, bottom, left, right); if (combined != wxSHEET_BLOCK_NONE) { extra->RemoveAt(k); extra_count--; k--; if (combined != wxSHEET_BLOCK_ALL) { if ((combined & wxSHEET_BLOCK_TOP) != 0) { extra->Add(top); extra_count++; } if ((combined & wxSHEET_BLOCK_BOTTOM) != 0) { extra->Add(bottom); extra_count++; } if ((combined & wxSHEET_BLOCK_LEFT) != 0) { extra->Add(left); extra_count++; } if ((combined & wxSHEET_BLOCK_RIGHT) != 0) { extra->Add(right); extra_count++; } } if (extra_count == 0) { n = count; break; } } } } } #ifdef CHECK_BLOCK_SORTING for (int m=1; m<m_blocks.GetCount(); m++) if (m_blocks[m] < m_blocks[m-1]) PRINT_BLOCK("Not sorted", m_blocks[m]); #endif // CHECK_BLOCK_SORTING if (extra_count != 0) { m_minimized = false; for (n=0; n<extra_count; n++) InsertBlock(extra->Item(n)); if (combineNow) Minimize(); return true; } return false; }
bool wxSheetSelection::DeselectBlock( const wxSheetBlock& block, bool combineNow, wxArraySheetBlock *deletedBlocks ) { int n, count = m_blocks.GetCount(); if ((count == 0) || !m_bounds.Intersects(block)) return false; bool done = false; bool recalc_bounds = false; const int bottom_row = block.GetBottom(); if (deletedBlocks) deletedBlocks->Clear(); wxArraySheetBlock extraBlocks; wxSheetBlock top, bottom, left, right; // iterate though blocks cutting input block out and adding remainder to end for (n=FindTopRow(bottom_row); n<count; n++) { if (bottom_row < m_blocks[n].GetTop()) break; const int deleted = m_blocks[n].Delete(block, top, bottom, left, right); if (deleted != wxSHEET_BLOCK_NONE) { done = true; int last_n = n; if (deletedBlocks) deletedBlocks->Add(m_blocks[n].Intersect(block)); if (m_bounds.SideMatches(m_blocks[n]) != wxSHEET_BLOCK_NONE) recalc_bounds = true; if (m_blocks[n].Contains(block)) n = count + 100; // all done, but add cutouts back else n--; m_blocks.RemoveAt(last_n); count--; if (deleted != wxSHEET_BLOCK_ALL) { if ((deleted & wxSHEET_BLOCK_TOP) != 0) extraBlocks.Add(top); if ((deleted & wxSHEET_BLOCK_BOTTOM) != 0) extraBlocks.Add(bottom); if ((deleted & wxSHEET_BLOCK_LEFT) != 0) extraBlocks.Add(left); if ((deleted & wxSHEET_BLOCK_RIGHT) != 0) extraBlocks.Add(right); } } } if (done) { m_minimized = false; const int extra_count = extraBlocks.GetCount(); for (n=0; n<extra_count; n++) InsertBlock(extraBlocks.Item(n)); if (combineNow) Minimize(); if (recalc_bounds) CalculateBounds(); } return done; }
BOOL FAR MergeFile(LPSTR FileName, int view) { HCURSOR hSaveCursor; char line[MAX_USER_LINE + 1]; int offset; //Current offset of storage in block int lineLen; // length of line BYTE prevLength; //Previous line size LPVIEWREC v = &Views[view]; WORD res; LPDOCREC d =&Docs[v->Doc]; LPLINEREC pCurLine, pLastLine; LPBLOCKDEF pCurBlock, pNewBlock; long y; Assert( v->Doc >= 0); if ((hFileDoc = _lopen(FileName, OF_READ)) == HFILE_ERROR) return ErrorBox(ERR_File_Open, (LPSTR)FileName); if ((pszBufferDoc = DocAlloc(DISK_BLOCK_SIZE)) == NULL) { ErrorBox(SYS_Allocate_Memory); goto error1; } dwBytesReadDoc = DISK_BLOCK_SIZE; dwOffsetDoc = DISK_BLOCK_SIZE; lineLen = 0; //Delete selected text if any if (v->BlockStatus) { long XR, YR; GetBlockCoord (view, &(v->X), &(v->Y), &XR, &YR); DeleteStream(view, v->X, v->Y, XR, YR, FALSE); } //Set the Hour glass cursor hSaveCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); //Insert first line res = LoadLine(line, &lineLen, d->NbLines); if (res == END_OF_FILE || res == END_OF_LINE) { //Add a CR+LF if (res == END_OF_LINE) { line[lineLen] = CR; line[lineLen + 1] = LF; lineLen += 2; } if (!InsertBlock(v->Doc, v->X, v->Y, (WORD) lineLen, line)) goto error2; } else { if (res == ERR_File_Read || res == ERR_Not_A_Text_File) ErrorBox(res, (LPSTR)FileName); goto error2; } if (res != END_OF_FILE) { //Get current line status (we just inserted it) y = v->Y; if (!FirstLine(v->Doc, &pCurLine, &y, &pCurBlock)) return FALSE; //Get next line (just after the line we just inserted) if (!NextLine(v->Doc, &pCurLine, &y, &pCurBlock)) return FALSE; //Set offset to StoreLine start offset = (LPSTR)pCurLine - (LPSTR)pCurBlock->Data; prevLength = pCurLine->PrevLength; //Split block in 2 blocks by first allocating a new block and then //copying right side of block in new block if (!AllocateBlock(pCurBlock, pCurBlock->NextBlock, &pNewBlock)) return FALSE; pLastLine = (LPLINEREC)(pCurBlock->Data + pCurBlock->LastLineOffset); memmove(pNewBlock->Data, (LPSTR)pCurLine, (LPSTR)pLastLine - (LPSTR)pCurLine + pLastLine->Length); //Set new old block len and new new block len pCurBlock->LastLineOffset = (LPSTR)pCurLine - (LPSTR)pCurBlock->Data - pCurLine->PrevLength; pNewBlock->LastLineOffset = (LPSTR)pLastLine - (LPSTR)pCurLine; //Backward links next block with new one if (pCurBlock->NextBlock == NULL) d->LastBlock = pNewBlock; else (pCurBlock->NextBlock)->PrevBlock = pNewBlock; //Forward link current block with new block pCurBlock->NextBlock = pNewBlock; CloseLine(v->Doc, &pCurLine, y, &pCurBlock); //Read and store all lines in new blocks res = LoadLine(line, &lineLen, d->NbLines); while (res == END_OF_LINE) { //Truncate a file too large if (d->NbLines >= MAX_LINE_NUMBER - 1) { ErrorBox(ERR_Truncate_Doc); res = END_OF_FILE; break; } if (!StoreLine(line, lineLen, &offset, &prevLength, &pCurBlock)) { res = END_ABORT; break; } res = LoadLine(line, &lineLen, ++d->NbLines); } //Take decisions switch (res) { case END_OF_FILE: //Store last line if (StoreLine(line, lineLen, &offset, &prevLength, &pCurBlock)) { d->NbLines++; //Forward link of last allocated block with new block pCurBlock->NextBlock = pNewBlock; //Backward link of new block with last allocated block pNewBlock->PrevBlock = pCurBlock; ((LPLINEREC)(pNewBlock->Data))->PrevLength = (BYTE)(lineLen + LHD); //Free memory if (!DocFree(pszBufferDoc)) InternalErrorBox(SYS_Free_Memory); //Restore cursor SetCursor(hSaveCursor); //Check syntax if C if (d->language == C_LANGUAGE) { d->lineTop = 0; d->lineBottom = d->NbLines; CheckSyntax(v->Doc); } SetVerticalScrollBar(view, TRUE); PosXY(view, v->X, v->Y, FALSE); InvalidateRect(v->hwndClient, (LPRECT)NULL, FALSE); CloseHandle (hFileDoc); return TRUE; } else goto abort; case ERR_File_Read: case ERR_Not_A_Text_File: ErrorBox(res, (LPSTR)FileName); //Fall through case END_ABORT: { abort: SetCursor(hSaveCursor); break; } default: Assert(FALSE); break; } } else InvalidateRect(v->hwndClient, (LPRECT)NULL, FALSE); error2: { SetCursor (hSaveCursor); if (!DocFree(pszBufferDoc)) InternalErrorBox(SYS_Free_Memory); } error1: { CloseHandle (hFileDoc); } return FALSE; } /* MergeFile() */
LPBNDS BuildBounds ( WORD coff, LPUL rgoff, LPW lpcbnds ) { LPBNDS rgbnds = (LPBNDS) MHAlloc (sizeof (BNDS) * cbndsAllocBlock); WORD cbndsAlloc = cbndsAllocBlock; WORD cbnds = 0; WORD ioff = 0; while (ioff < coff) { ULONG uoffCurr = rgoff [ ioff ]; ULONG uoffMax = 0; WORD ibnds = FindPosition (rgbnds, cbnds, rgoff, uoffCurr); if (ibnds == cbnds) { // We're after all other known blocks, so our max // is "infinity" uoffMax = 0xFFFFFFFF; rgbnds = InsertBlock (ibnds, 1, rgbnds, &cbnds, &cbndsAlloc); } else if (rgoff [ rgbnds [ ibnds ].ilnStart ] > uoffCurr) { // We're at an insertion point, not in the middle of // another block candidate uoffMax = rgoff [ rgbnds [ ibnds ].ilnStart ]; rgbnds = InsertBlock (ibnds, 1, rgbnds, &cbnds, &cbndsAlloc); } else { // We're in the middle of another block candidate, so we // must split it in two rgbnds = InsertBlock (ibnds, 2, rgbnds, &cbnds, &cbndsAlloc); // Start of ibnds is already set rgbnds [ ibnds ].ilnEnd = ScanBlock ( rgoff, coff, rgbnds [ ibnds ].ilnStart, uoffCurr ); rgbnds [ ibnds + 2 ].ilnStart = rgbnds [ ibnds ].ilnEnd + 1; // End of ibnds + 2 is already set uoffMax = rgoff [ rgbnds [ ibnds + 2 ].ilnStart ]; ibnds += 1; } rgbnds [ ibnds ].ilnStart = ioff; rgbnds [ ibnds ].ilnEnd = ScanBlock (rgoff, coff, ioff, uoffMax); ioff = rgbnds [ ibnds ].ilnEnd + 1; } *lpcbnds = cbnds; return rgbnds; }
bool Strip::Load (const TCHAR* lpszFileName) { // ----- Initialize ----- // FILE* stream = _tfopen(lpszFileName, _T("rb") CHARSET); if (stream == NULL || _pPimpl == NULL) { return false; } TiXmlDocument doc; TiXmlAttribute* pAttr; TiXmlElement* pRoot; TiXmlElement* pBlockNode; TiXmlElement* pUnitNode; TiXmlElement* pBallNode; Block* pBlockObject; Unit* pUnitObject; Ball* pBallObject; const char* sRootName; const char* sAttrName; double dValue; int nValue; if (!doc.LoadFile(stream)) { return false; } pRoot = doc.RootElement(); if (pRoot == false) { return false; } sRootName = pRoot->Value(); if (strcmp(sRootName, ROOT_NAME_STRIP) != 0) { return false; } _pPimpl->vectorBlocks.clear(); // ----- Get a Strip Data ----- // if (pRoot->QueryDoubleAttribute(ATTR_NAME_WIDTH, &dValue) == TIXML_SUCCESS) { _pPimpl->dWidth = dValue; } if (pRoot->QueryDoubleAttribute(ATTR_NAME_HEIGHT, &dValue) == TIXML_SUCCESS) { _pPimpl->dHeight = dValue; } // ----- Get Strip's childs ----- // pBlockNode = pRoot->FirstChildElement(); if (pBlockNode != NULL) { do { pBlockObject = new Block(); // ----- Get a Block Data ----- // if (pBlockNode->QueryIntAttribute (ATTR_NAME_COLUMN, &nValue) == TIXML_SUCCESS) { pBlockObject->SetColumn (nValue); } if (pBlockNode->QueryIntAttribute (ATTR_NAME_ROW, &nValue) == TIXML_SUCCESS) { pBlockObject->SetRow (nValue); } if (pBlockNode->QueryDoubleAttribute (ATTR_NAME_WIDTH, &dValue) == TIXML_SUCCESS) { pBlockObject->SetWidth (dValue); } if (pBlockNode->QueryDoubleAttribute (ATTR_NAME_HEIGHT, &dValue) == TIXML_SUCCESS) { pBlockObject->SetHeight (dValue); } if (pBlockNode->QueryDoubleAttribute (ATTR_NAME_START_X, &dValue) == TIXML_SUCCESS) { pBlockObject->SetStartX (dValue); } if (pBlockNode->QueryDoubleAttribute (ATTR_NAME_START_Y, &dValue) == TIXML_SUCCESS) { pBlockObject->SetStartY (dValue); } // ----- Get Block's childs ----- // pUnitNode = pBlockNode->FirstChildElement(); if (pUnitNode != NULL) { do { pUnitObject = new Unit(); // ----- Get a Unit Data ----- // if (pUnitNode->QueryIntAttribute (ATTR_NAME_COLUMN, &nValue) == TIXML_SUCCESS) { pUnitObject->SetColumn (nValue); } if (pUnitNode->QueryIntAttribute (ATTR_NAME_ROW, &nValue) == TIXML_SUCCESS) { pUnitObject->SetRow (nValue); } if (pUnitNode->QueryDoubleAttribute (ATTR_NAME_START_X, &dValue) == TIXML_SUCCESS) { pUnitObject->SetStartX (dValue); } if (pUnitNode->QueryDoubleAttribute (ATTR_NAME_START_Y, &dValue) == TIXML_SUCCESS) { pUnitObject->SetStartY (dValue); } if (pUnitNode->QueryDoubleAttribute (ATTR_NAME_CENTER_X, &dValue) == TIXML_SUCCESS) { pUnitObject->SetCenterX (dValue); } if (pUnitNode->QueryDoubleAttribute (ATTR_NAME_CENTER_Y, &dValue) == TIXML_SUCCESS) { pUnitObject->SetCenterY (dValue); } if (pUnitNode->QueryDoubleAttribute (ATTR_NAME_WIDTH, &dValue) == TIXML_SUCCESS) { pUnitObject->SetWidth (dValue); } if (pUnitNode->QueryDoubleAttribute (ATTR_NAME_HEIGHT, &dValue) == TIXML_SUCCESS) { pUnitObject->SetHeight (dValue); } // ----- Get Unit's childs ----- // pBallNode = pUnitNode->FirstChildElement(); if (pBallNode != NULL) { do { pBallObject = new Ball(); // ----- Get a Ball Data ----- // if (pBallNode->QueryDoubleAttribute (ATTR_NAME_DIAMETER, &dValue) == TIXML_SUCCESS) { pBallObject->SetDiameter (dValue); } if (pBallNode->QueryDoubleAttribute (ATTR_NAME_CENTER_X, &dValue) == TIXML_SUCCESS) { pBallObject->SetCenterX (dValue); } if (pBallNode->QueryDoubleAttribute (ATTR_NAME_CENTER_Y, &dValue) == TIXML_SUCCESS) { pBallObject->SetCenterY (dValue); } if (pBallNode->QueryIntAttribute (ATTR_NAME_BALL_STATUS, &nValue) == TIXML_SUCCESS) { pBallObject->SetStatus (nValue); } pUnitObject->InsertBall(pBallObject); } while (pBallNode = pBallNode->NextSiblingElement()); } pBlockObject->InsertUnit(pUnitObject); } while (pUnitNode = pUnitNode->NextSiblingElement()); } // ----- Add Block Object ----- // InsertBlock(pBlockObject); } while (pBlockNode = pBlockNode->NextSiblingElement()); } // ----- Close ----- // fclose(stream); return true; }
//按文件名顺序插入 void CIndex::insert(IndexElemType Record,BOOL bDir) { DebugTrace("**********插入记录\n"); int (*FunCmpare)(IndexElemType,IndexElemType); if(bDir) FunCmpare=comp_dir; else FunCmpare=comp_file; ++m_size; int cmp; PINDEX_BLOCK_NODE pNode; int i; for(i=0;i<m_dwBlockCount;++i) { pNode=m_pIndex[i]; cmp=FunCmpare(Record,pNode->PtrData[pNode->CurrentEnd-1]); if(cmp<=0) break; } if(i==m_dwBlockCount){// DebugTrace("当前插入的是最大文件目录名\n"); //看最后节点是否有空间插入,如果没有,则新增加节点 //满时:m_pLastNode->CurrentBegin==0 m_pLastNode->CurrentEnd==DirFrnIndexBlockNode::CountPerIndex //[CurrentBegin,CurrentEnd) if(m_pLastNode->IsEndFull()){//右满 DebugTrace("右满\n"); if(m_pLastNode->IsBeginFull()){//左满 DebugTrace("左满\n"); //先向左借空间 if(m_dwBlockCount>=2 && !m_pIndex[m_dwBlockCount-2]->IsFull()){//左有借 DebugTrace("左有借\n"); pNode=m_pIndex[m_dwBlockCount-2]; if(pNode->IsEndFull()){//右满 DebugTrace("左右端满,左移前Beg=%d,End=%d\n",pNode->CurrentBegin,pNode->CurrentEnd); pNode->LeftMove(); DebugTrace("左右端满,左移后Beg=%d,End=%d\n",pNode->CurrentBegin,pNode->CurrentEnd); } DebugTrace("最后右移动前,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd); pNode->AddEnd(m_pLastNode->RemoveBegin());//最后BEG右移 DebugTrace("最后右移动后,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd); m_pLastNode->LeftMove();//右移动一格 DebugTrace("左移动一格,【Beg=%d,End=%d】\n",m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd); }else{//左无借,将最后一个节点分裂保留3/4 1/4进新节点 DebugTrace("左无借【Beg=%d,End=%d】\n",m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd); pNode=m_pLastNode; AddLastBlock();//m_pLastNode已指向新块 DebugTrace("增加新块,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd); //分裂pNode m_pLastNode->CutFromLeft(pNode); DebugTrace("左剪切,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd); } DebugTrace("AddEnd【Beg=%d,End=%d】\n",m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd); m_pLastNode->AddEnd(Record); } else{//左未满 DebugTrace("左未满\n"); //整体左移动一格 m_pLastNode->LeftMove(); m_pLastNode->AddEnd(Record); } }else{//右未满 DebugTrace("右未满\n"); m_pLastNode->AddEnd(Record); } }else{//插入的值非最大值 //pNode指向插入节点 //寻找插入位置先 int low=pNode->CurrentBegin,high=pNode->CurrentEnd-1; int mid; DWORD dwInsert; while(low<=high) { mid=low+((high-low)>>1); cmp=FunCmpare(Record,pNode->PtrData[mid]); if(cmp<0) high=mid-1; else if(cmp>0) low=mid+1; else{//找到同名 dwInsert=mid; break; } } if(low>high) dwInsert=low; DebugTrace("寻找插入位置先【Beg=%d,dwInsert=%d,End=%d】\n",pNode->CurrentBegin,dwInsert,pNode->CurrentEnd); assert(dwInsert>=pNode->CurrentBegin && dwInsert<pNode->CurrentEnd); //插入位置 注意[dwInsert ,CurEnd) 应向右移动 if(pNode->IsFull()){ DebugTrace("插入节点满\n"); if(pNode==m_pLastNode){//在最后一个节点中插入 DebugTrace("是在最后一个节点中插入\n"); if(i>=1 && !m_pIndex[i-1]->IsFull()){//左有借 DebugTrace("左有借\n"); pNode=m_pIndex[i-1]; if(pNode->IsEndFull()){//右满 DebugTrace("左节点 右满【Beg=%d,End=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd); pNode->LeftMove(); DebugTrace("左移动 右满【Beg=%d,End=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd); } if(0==dwInsert){//BasicInfo< m_pLastNode的所有值 DebugTrace("直接插入左最后\n"); pNode->AddEnd(Record); DebugTrace("【Beg=%d,End=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd); return; }else pNode->AddEnd(m_pLastNode->RemoveBegin());//最后BEG右移 m_pLastNode->Insert(dwInsert,Record); DebugTrace("最后右移动后,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd); }else{//左无借,将最后一个节点分裂保留3/4 1/4进新节点 DebugTrace("左无借,分增加最后节点\n"); pNode=m_pLastNode; AddLastBlock();//m_pLastNode已指向新块 //分裂pNode m_pLastNode->CutFromLeft(pNode,&dwInsert); pNode->AddEnd(Record); } }else if(pNode==*m_pIndex){//在第一个节点中插入 DebugTrace("在第一个节点中插入\n"); if(m_dwBlockCount>1 && !m_pIndex[1]->IsFull()){//右有借 DebugTrace("右有借\n"); pNode=m_pIndex[1]; if(pNode->IsBeginFull()){//左满 DebugTrace("左满则右移动\n"); pNode->RightMove(); } //*m_pIndex的最后一个值一定大于插入指 pNode->AddBegin((*m_pIndex)->RemoveEnd()); (*m_pIndex)->Insert(dwInsert,Record); }else{//右无借 DebugTrace("右无借\n"); InsertBlock(1); pNode=m_pIndex[1]; //分裂pNode pNode->CutFromLeft(*m_pIndex,&dwInsert); (*m_pIndex)->AddEnd(Record); } }else{//即不是第一个节点 又不是最后节点插入 可能要向两边借 DebugTrace("向两边借\n"); if(!m_pIndex[i-1]->IsFull()){//试图向左借 pNode=m_pIndex[i-1]; if(pNode->IsEndFull()){//右满 pNode->LeftMove(); } if(0==dwInsert){//BasicInfo< m_pLastNode的所有值 pNode->AddEnd(Record); return; }else pNode->AddEnd(m_pIndex[i]->RemoveBegin());//最后BEG右移 m_pIndex[i]->Insert(dwInsert,Record); }else if(!m_pIndex[i+1]->IsFull()){//试图向右借 pNode=m_pIndex[i+1]; if(pNode->IsBeginFull()){//左满 pNode->RightMove(); } //*m_pIndex的最后一个值一定大于插入指 pNode->AddBegin(m_pIndex[i]->RemoveEnd()); m_pIndex[i]->Insert(dwInsert,Record); }else{//左右均无借的 //插入新节点,然后向两边借,本处仅实现的拷贝一边的 //优化:可以拷贝两边的数据,使得连续3个节点都未满 if(dwInsert<(INDEX_BLOCK_NODE::CountPerIndex>>1)){ //插入位置在前部 拷贝大块到令一块中央 InsertBlock(i+1); m_pIndex[i+1]->CutFromLeft(m_pIndex[i],&dwInsert); m_pIndex[i]->AddEnd(Record); }else{ InsertBlock(i); m_pIndex[i]->CutFromRight(m_pIndex[i+1],&dwInsert); m_pIndex[i+1]->AddBegin(Record); } } } }else{//本节点有位置可插