📄 tabindnode.cpp
字号:
return -1; } delete poTmpNode; } m_nPrevNodePtr = poNewNode->GetNodeBlockPtr(); // Move half the entries to the new block m_poDataBlock->GotoByteInBlock(12 + 0); if (poNewNode->SetNodeBufferDirectly(numInNode1, m_poDataBlock->GetCurDataPtr()) != 0) return -1; // Shift the second half of the entries to beginning of buffer memmove (m_poDataBlock->GetCurDataPtr(), m_poDataBlock->GetCurDataPtr()+numInNode1*(m_nKeyLength+4), numInNode2*(m_nKeyLength+4));#ifdef DEBUG // Just in case, reset space previously used by moved entries memset(m_poDataBlock->GetCurDataPtr()+numInNode2*(m_nKeyLength+4), 0, numInNode1*(m_nKeyLength+4));#endif // And update current node members m_numEntriesInNode = numInNode2; m_nCurIndexEntry -= numInNode1; // Update parent node with new children info if (m_poParentNodeRef) { if (m_poParentNodeRef->UpdateSplitChild(poNewNode->GetNodeKey(), poNewNode->GetNodeBlockPtr(), GetNodeKey(), GetNodeBlockPtr(), 2) != 0) return -1; } } /*----------------------------------------------------------------- * Update current node header *----------------------------------------------------------------*/ m_poDataBlock->GotoByteInBlock(0); m_poDataBlock->WriteInt32(m_numEntriesInNode); m_poDataBlock->WriteInt32(m_nPrevNodePtr); m_poDataBlock->WriteInt32(m_nNextNodePtr); /*----------------------------------------------------------------- * Flush and destroy temporary node *----------------------------------------------------------------*/ if (poNewNode->CommitToFile() != 0) return -1; delete poNewNode; return 0;}/********************************************************************** * TABINDNode::SplitRootNode() * * (private method) * * Split a Root Node. * First, a level of nodes must be added to the tree, then the contents * of what used to be the root node is moved 1 level down and then that * node is split like a regular node. * * Returns 0 on success, -1 on error **********************************************************************/int TABINDNode::SplitRootNode(){ /*----------------------------------------------------------------- * Since a root note cannot be split, we add a level of nodes * under it and we'll do the split at that level. *----------------------------------------------------------------*/ TABINDNode *poNewNode = new TABINDNode(m_eAccessMode); if (poNewNode->InitNode(m_fp, 0, m_nKeyLength, m_nSubTreeDepth, m_bUnique, m_poBlockManagerRef, this, 0, 0)!= 0 || poNewNode->SetFieldType(m_eFieldType) != 0) { return -1; } // Move all entries to the new child m_poDataBlock->GotoByteInBlock(12 + 0); if (poNewNode->SetNodeBufferDirectly(m_numEntriesInNode, m_poDataBlock->GetCurDataPtr(), m_nCurIndexEntry, m_poCurChildNode) != 0) { return -1; }#ifdef DEBUG // Just in case, reset space previously used by moved entries memset(m_poDataBlock->GetCurDataPtr(), 0, m_numEntriesInNode*(m_nKeyLength+4));#endif /*----------------------------------------------------------------- * Rewrite current node. (the new root node) *----------------------------------------------------------------*/ m_numEntriesInNode = 0; m_nSubTreeDepth++; m_poDataBlock->GotoByteInBlock(0); m_poDataBlock->WriteInt32(m_numEntriesInNode); InsertEntry(poNewNode->GetNodeKey(), poNewNode->GetNodeBlockPtr()); /*----------------------------------------------------------------- * Keep a reference to the new child *----------------------------------------------------------------*/ m_poCurChildNode = poNewNode; m_nCurIndexEntry = 0; /*----------------------------------------------------------------- * And finally force the child to split itself *----------------------------------------------------------------*/ return m_poCurChildNode->SplitNode();}/********************************************************************** * TABINDNode::SetNodeBufferDirectly() * * (private method) * * Set the key/value part of the nodes buffer and the pointers to the * current child direclty. This is used when copying info to a new node * in SplitNode() and SplitRootNode() * * Returns 0 on success, -1 on error **********************************************************************/int TABINDNode::SetNodeBufferDirectly(int numEntries, UGKByte *pBuf, int nCurIndexEntry/*=0*/, TABINDNode *poCurChild/*=NULL*/){ m_poDataBlock->GotoByteInBlock(0); m_poDataBlock->WriteInt32(numEntries); m_numEntriesInNode = numEntries; m_poDataBlock->GotoByteInBlock(12); if ( m_poDataBlock->WriteBytes(numEntries*(m_nKeyLength+4), pBuf) != 0) { return -1; // An error msg should have been reported already } m_nCurIndexEntry = nCurIndexEntry; m_poCurChildNode = poCurChild; if (m_poCurChildNode) m_poCurChildNode->m_poParentNodeRef = this; return 0;}/********************************************************************** * TABINDNode::GetNodeKey() * * Returns a reference to the key for the first entry in the node, which * is also the key for this node at the level above it in the tree. * * Returns NULL if node is empty. **********************************************************************/UGKByte* TABINDNode::GetNodeKey(){ if (m_poDataBlock == NULL || m_numEntriesInNode == 0) return NULL; m_poDataBlock->GotoByteInBlock(12); return m_poDataBlock->GetCurDataPtr();}/********************************************************************** * TABINDNode::SetPrevNodePtr() * * Update the m_nPrevNodePtr member. * * Returns 0 on success, -1 on error. **********************************************************************/int TABINDNode::SetPrevNodePtr(UGKInt32 nPrevNodePtr){ if ((m_eAccessMode != TABWrite && m_eAccessMode != TABReadWrite) || m_poDataBlock == NULL) return -1; if (m_nPrevNodePtr == nPrevNodePtr) return 0; // Nothing to do. m_poDataBlock->GotoByteInBlock(4); return m_poDataBlock->WriteInt32(nPrevNodePtr);}/********************************************************************** * TABINDNode::SetNextNodePtr() * * Update the m_nNextNodePtr member. * * Returns 0 on success, -1 on error. **********************************************************************/int TABINDNode::SetNextNodePtr(UGKInt32 nNextNodePtr){ if ((m_eAccessMode != TABWrite && m_eAccessMode != TABReadWrite) || m_poDataBlock == NULL) return -1; if (m_nNextNodePtr == nNextNodePtr) return 0; // Nothing to do. m_poDataBlock->GotoByteInBlock(8); return m_poDataBlock->WriteInt32(nNextNodePtr);}/********************************************************************** * TABINDNode::Dump() * * Dump block contents... available only in DEBUG mode. **********************************************************************/void TABINDNode::Dump(FILE *fpOut /*=NULL*/){ if (fpOut == NULL) fpOut = stdout; fprintf(fpOut, "----- TABINDNode::Dump() -----\n"); if (m_fp == NULL) { fprintf(fpOut, "Node is not initialized.\n"); } else { fprintf(fpOut, " m_numEntriesInNode = %d\n", m_numEntriesInNode); fprintf(fpOut, " m_nCurDataBlockPtr = %d\n", m_nCurDataBlockPtr); fprintf(fpOut, " m_nPrevNodePtr = %d\n", m_nPrevNodePtr); fprintf(fpOut, " m_nNextNodePtr = %d\n", m_nNextNodePtr); fprintf(fpOut, " m_nSubTreeDepth = %d\n", m_nSubTreeDepth); fprintf(fpOut, " m_nKeyLength = %d\n", m_nKeyLength); fprintf(fpOut, " m_eFieldtype = %s\n", TABFIELDTYPE_2_STRING(m_eFieldType) ); if (m_nSubTreeDepth > 0) { UGKByte aKeyValBuf[255]; UGKInt32 nRecordPtr, nValue; TABINDNode oChildNode; if (m_nKeyLength > 254) { UGKError(ET_Failure, UGKErr_NotSupported, "Dump() cannot handle keys longer than 254 chars."); return; } fprintf(fpOut, "\n"); for (int i=0; i<m_numEntriesInNode; i++) { if (m_nSubTreeDepth > 1) { fprintf(fpOut, " >>>> Child %d of %d <<<<<\n", i, m_numEntriesInNode); } else { fprintf(fpOut, " >>>> Record (leaf) %d of %d <<<<<\n", i, m_numEntriesInNode); } if (m_eFieldType == TABFChar) { nRecordPtr = ReadIndexEntry(i, aKeyValBuf); fprintf(fpOut, " nRecordPtr = %d\n", nRecordPtr); fprintf(fpOut, " Char Val= \"%s\"\n", (char*)aKeyValBuf); } else if (m_nKeyLength != 4) { nRecordPtr = ReadIndexEntry(i, aKeyValBuf); fprintf(fpOut, " nRecordPtr = %d\n", nRecordPtr); fprintf(fpOut, " Int Value = %d\n", *(UGKInt32*)aKeyValBuf); fprintf(fpOut, " Int16 Val= %d\n",*(UGKInt16*)(aKeyValBuf+2)); fprintf(fpOut, " Hex Val= 0x%8.8x\n",*(UGKUInt32*)aKeyValBuf); } else { nRecordPtr = ReadIndexEntry(i, (UGKByte*)&nValue); fprintf(fpOut, " nRecordPtr = %d\n", nRecordPtr); fprintf(fpOut, " Int Value = %d\n", nValue); fprintf(fpOut, " Hex Value = 0x%8.8x\n",nValue); } if (m_nSubTreeDepth > 1) { oChildNode.InitNode(m_fp, nRecordPtr, m_nKeyLength, m_nSubTreeDepth - 1, FALSE); oChildNode.SetFieldType(m_eFieldType); oChildNode.Dump(fpOut); } } } } fflush(fpOut);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -