📄 ntx.cpp
字号:
/* put the node in the chain */ if( SetNodeChain == 1 ) { if( NodeChain == NULL ) /* first one ? */ { NodeChain = n; CurNode = n; CurNode->PrevNode = NULL; } else { n->PrevNode = CurNode; CurNode->NextNode = n; CurNode = n; } } else CurNode = n; return 0;}/***********************************************************************///! Short description./*! \param n*/#ifdef XBASE_DEBUGvoid xbNtx::DumpNodeRec( xbLong n ){ char *p; xbShort NoOfKeys; xbLong LeftBranch, RecNo; xbShort i,j; GetLeafNode( n, 0 ); NoOfKeys = dbf->xbase->GetShort( Node ); p = Node + 4; /* go past no of keys */ cout << "\n--------------------------------------------------------"; cout << "\nNode # " << n << " Number of keys = " << NoOfKeys << "\n"; cout << "\n Key Left Rec Key"; cout << "\nNumber Branch Number Data"; for( i = 0; i < GetKeysPerNode()+1 /*NoOfKeys*/; i++ ) { LeftBranch = dbf->xbase->GetLong( p ); p+=4; RecNo = dbf->xbase->GetLong( p ); p+=4; cout << "\n" << i << " " << LeftBranch << " " << RecNo << " "; for( j = 0; j < HeadNode.KeyLen; j++ ) cout << *p++; }}#endif/***********************************************************************///! Short description./*! \param RecNo \param n*/xbLong xbNtx::GetDbfNo( xbShort RecNo, xbNodeLink * n ){ NtxLeafNode *temp; char *p; xbUShort itemOffset; if( !n ) return 0L; temp = &n->Leaf; p = temp->KeyRecs; if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode )) return 0L; itemOffset = GetItemOffset(RecNo, n, 0); // ItemOffset is from the beginning of the record. p += itemOffset; p += 4; return( dbf->xbase->GetLong( p ));}/***********************************************************************///! Short description./*! \param RecNo \param n*/xbLong xbNtx::GetLeftNodeNo( xbShort RecNo, xbNodeLink * n ){ NtxLeafNode *temp; char *p; xbUShort itemOffset; if( !n ) return 0L; temp = &n->Leaf; p = temp->KeyRecs; if( RecNo < 0 || RecNo > temp->NoOfKeysThisNode ) return 0L; itemOffset = GetItemOffset(RecNo, n, 0); // ItemOffset is from the beginning of the record. p += itemOffset; return( dbf->xbase->GetULong( p ));}/***********************************************************************///! Short description./*! \param RecNo \param n*/char * xbNtx::GetKeyData( xbShort RecNo, xbNodeLink * n ){ NtxLeafNode *temp; char *p; xbUShort itemOffset; if( !n ) return 0L; temp = &n->Leaf; p = temp->KeyRecs; if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode )) return 0L; itemOffset = GetItemOffset(RecNo, n, 0); // ItemOffset is from the beginning of the record. p += itemOffset + 8; return( p );}/***********************************************************************///! Short description./*! \param RecNo \param n \param*/xbUShortxbNtx::GetItemOffset(xbShort RecNo, xbNodeLink *n, xbShort) { if (RecNo > (this->HeadNode.KeysPerNode + 1)) { cout << "RecNo = " << RecNo << endl; cout << "this->HeadNode.KeysPerNode = " << this->HeadNode.KeysPerNode << endl; cout << "********************* BUG ***********************" << endl; // ;-) exit(1); } return n->offsets[RecNo];}//! Short description./*! \param pos \param n*/xbUShortxbNtx::InsertKeyOffset(xbShort pos, xbNodeLink *n){ xbUShort temp; // save the new offset temp = n->offsets[n->Leaf.NoOfKeysThisNode + 1]; for( int i = n->Leaf.NoOfKeysThisNode + 1; i > pos; i-- ) { n->offsets[i] = n->offsets[i-1]; } n->offsets[pos] = temp; return n->offsets[pos];}//! Short description./*! \param pos \param n*/xbUShortxbNtx::DeleteKeyOffset(xbShort pos, xbNodeLink *n){ xbUShort temp; xbShort i; // save the old offset temp = n->offsets[pos]; for( i = pos; i < n->Leaf.NoOfKeysThisNode; i++ ) { n->offsets[i] = n->offsets[i+1]; } n->offsets[i] = temp; return n->offsets[i];}/***********************************************************************///! Short description./*!*/xbLong xbNtx::GetTotalNodes( void ) {// if( &HeadNode )// return HeadNode.TotalNodes;// else return 0L;}/***********************************************************************///! Short description./*!*/xbUShort xbNtx::GetKeysPerNode( void ) { if( &HeadNode ) return HeadNode.KeysPerNode; else return 0L;}/***********************************************************************///! Short description./*! \param RetrieveSw*/xbShort xbNtx::GetFirstKey( xbShort RetrieveSw ){/* This routine returns 0 on success and sets CurDbfRec to the record *//* corresponding to the first index pointer */ xbLong TempNodeNo; xbShort rc; #ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) if((rc = LockIndex(F_SETLKW, F_RDLCK)) != 0) return rc;#endif /* initialize the node chain */ if( NodeChain ) { ReleaseNodeMemory( NodeChain ); NodeChain = NULL; } if(( rc = GetHeadNode()) != 0 ) { CurDbfRec = 0L;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; } /* get a node and add it to the link */ if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; }/* traverse down the left side of the tree */ while( GetLeftNodeNo( 0, CurNode )) { TempNodeNo = GetLeftNodeNo( 0, CurNode ); if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return rc; } CurNode->CurKeyNo = 0; } CurDbfRec = GetDbfNo( 0, CurNode );#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif if( RetrieveSw ) return dbf->GetRecord( CurDbfRec ); else return XB_NO_ERROR;}/***********************************************************************///! Short description./*! \param RetrieveSw*/xbShort xbNtx::GetNextKey( xbShort RetrieveSw ){/* This routine returns 0 on success and sets CurDbfRec to the record *//* corresponding to the next index pointer */ xbNodeLink * TempNodeLink; xbLong TempNodeNo; xbShort rc; #ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) if((rc = LockIndex(F_SETLKW, F_RDLCK)) != 0) return rc;#endif if( !IndexStatus ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; xb_error(XB_NOT_OPEN); } if( !CurNode ) { rc = GetFirstKey( RetrieveSw );#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; } /* more keys on this node ? */ if(( CurNode->Leaf.NoOfKeysThisNode -1 ) > CurNode->CurKeyNo ) { CurNode->CurKeyNo++; CurDbfRec = GetDbfNo( CurNode->CurKeyNo, CurNode );#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif if( RetrieveSw ) return dbf->GetRecord( CurDbfRec ); else return XB_NO_ERROR; } /* if head node we are at eof */ if( CurNode->NodeNo == HeadNode.StartNode ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif#ifdef HAVE_EXCEPTIONS throw xbEoFException();#else return XB_EOF;#endif } /* this logic assumes that interior nodes have n+1 left node no's where */ /* n is the number of keys in the node */ /* pop up one node to the interior node level & free the leaf node */ TempNodeLink = CurNode; CurNode = CurNode->PrevNode; CurNode->NextNode = NULL; ReleaseNodeMemory( TempNodeLink ); /* while no more right keys && not head node, pop up one node */ while(( CurNode->CurKeyNo >= CurNode->Leaf.NoOfKeysThisNode ) && ( CurNode->NodeNo != HeadNode.StartNode )) { TempNodeLink = CurNode; CurNode = CurNode->PrevNode; CurNode->NextNode = NULL; ReleaseNodeMemory( TempNodeLink ); } /* if head node && right most key, return end-of-file */ if(( HeadNode.StartNode == CurNode->NodeNo ) && ( CurNode->CurKeyNo >= CurNode->Leaf.NoOfKeysThisNode )) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif#ifdef HAVE_EXCEPTIONS throw xbEoFException();#else return XB_EOF;#endif } /* move one to the right */ CurNode->CurKeyNo++; TempNodeNo = GetLeftNodeNo( CurNode->CurKeyNo, CurNode ); if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; }/* traverse down the left side of the tree */ while( GetLeftNodeNo( 0, CurNode )) { TempNodeNo = GetLeftNodeNo( 0, CurNode ); if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return rc; } CurNode->CurKeyNo = 0; } CurDbfRec = GetDbfNo( 0, CurNode );#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif if( RetrieveSw ) return dbf->GetRecord( CurDbfRec ); else return XB_NO_ERROR;}/***********************************************************************///! Short description./*! \param NodeNo \param RetrieveSw*/xbShort xbNtx::GetLastKey( xbLong NodeNo, xbShort RetrieveSw ){/* This routine returns 0 on success and sets CurDbfRec to the record *//* corresponding to the last index pointer *//* If NodeNo = 0, start at head node, otherwise start at NodeNo */ xbLong TempNodeNo; xbShort rc;// TODO// NTX files keep no TotalNode count. // if( NodeNo < 0 || NodeNo > HeadNode.TotalNodes )// return XB_INVALID_NODE_NO;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) if((rc = LockIndex(F_SETLKW, F_RDLCK)) != 0) return rc;#endif /* initialize the node chain */ if( NodeChain ) { ReleaseNodeMemory( NodeChain ); NodeChain = NULL; } if( NodeNo == 0L ) if(( rc = GetHeadNode()) != 0 ) { #ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return rc; } /* get a node and add it to the link */ if( NodeNo == 0L ) { if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return rc; } } else { if(( rc = GetLeafNode( NodeNo, 1 )) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return rc; } } CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;/* traverse down the right side of the tree */ while( GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode )) { TempNodeNo = GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode ); if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return rc; } CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -