📄 ndx.cpp
字号:
else { n->PrevNode = CurNode; CurNode->NextNode = n; CurNode = n; } } else CurNode = n; return 0;}/***********************************************************************///! Short description/*! \param n*/#ifdef XBASE_DEBUGvoid xbNdx::DumpNodeRec( xbLong n ){ char *p; xbLong NoOfKeys, LeftBranch, RecNo; xbShort i,j; FILE * log; if(( log = fopen( "xbase.log", "a+t" )) == NULL ) return; GetLeafNode( n, 0 ); NoOfKeys = dbf->xbase->GetLong( Node ); p = Node + 4; /* go past no of keys */ fprintf( log, "\n--------------------------------------------------------" ); fprintf( log, "\nNode # %ld", n ); fprintf( log, "\nNumber of keys = %ld", NoOfKeys ); fprintf( log, "\n Key Left Rec Key" ); fprintf( log, "\nNumber Branch Number Data" ); for( i = 0; i < GetKeysPerNode() /*NoOfKeys*/; i++ ) { LeftBranch = dbf->xbase->GetLong( p ); p+=4; RecNo = dbf->xbase->GetLong( p ); p+=4; fprintf( log, "\n %d %ld %ld ", i, LeftBranch, RecNo ); if( !HeadNode.KeyType ) for( j = 0; j < HeadNode.KeyLen; j++ ) fputc( *p++, log ); else { fprintf( log, "??????" /*, dbf->xbase->GetDouble( p )*/ ); p += 8; } } fclose( log );}#endif/***********************************************************************/#ifndef XB_INLINE_GETDBFNOxbLong xbNdx::GetDbfNo( xbShort RecNo, xbNdxNodeLink * n ){ xbNdxLeafNode *temp; char *p; if( !n ) return 0L; temp = &n->Leaf; if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode - 1 )) return 0L; p = temp->KeyRecs + 4; p += RecNo * ( 8 + HeadNode.KeyLen ); return( dbf->xbase->GetLong( p ));}#endif/***********************************************************************///! Short description/*! \param RecNo \param n*/xbLong xbNdx::GetLeftNodeNo( xbShort RecNo, xbNdxNodeLink * n ){ xbNdxLeafNode *temp; char *p; if( !n ) return 0L; temp = &n->Leaf; if( RecNo < 0 || RecNo > temp->NoOfKeysThisNode ) return 0L; p = temp->KeyRecs; p += RecNo * ( 8 + HeadNode.KeyLen ); return( dbf->xbase->GetLong( p ));}/***********************************************************************///! Short description/*! \param RecNo \param n*/char * xbNdx::GetKeyData( xbShort RecNo, xbNdxNodeLink * n ){ xbNdxLeafNode *temp; char *p; if( !n ) return 0L; temp = &n->Leaf; if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode - 1 )) return 0L; p = temp->KeyRecs + 8; p += RecNo * ( 8 + HeadNode.KeyLen ); return( p );}/***********************************************************************///! Short description/*!*/xbLong xbNdx::GetTotalNodes( void ) { if( &HeadNode ) return HeadNode.TotalNodes; else return 0L;}/***********************************************************************///! Short description/*!*/xbUShort xbNdx::GetKeysPerNode( void ) { if( &HeadNode ) return HeadNode.KeysPerNode; else return 0L;}/***********************************************************************///! Short description/*! \param RetrieveSw*/xbShort xbNdx::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 ) { CurDbfRec = 0L;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif 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 xbNdx::GetNextKey( xbShort RetrieveSw ){/* This routine returns 0 on success and sets CurDbfRec to the record *//* corresponding to the next index pointer */ xbNdxNodeLink * TempxbNodeLink; xbLong TempNodeNo; xbShort rc = 0; #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 xb_eof_error; } /* 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 */ TempxbNodeLink = CurNode; CurNode = CurNode->PrevNode; CurNode->NextNode = NULL; ReleaseNodeMemory( TempxbNodeLink ); /* while no more right keys && not head node, pop up one node */ while(( CurNode->CurKeyNo >= CurNode->Leaf.NoOfKeysThisNode ) && ( CurNode->NodeNo != HeadNode.StartNode )) { TempxbNodeLink = CurNode; CurNode = CurNode->PrevNode; CurNode->NextNode = NULL; ReleaseNodeMemory( TempxbNodeLink ); } /* 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 xb_eof_error; } /* 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 ) { 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 xbNdx::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; if( NodeNo < 0 || NodeNo > HeadNode.TotalNodes ) xb_error(XB_INVALID_NODE_NO); /* initialize the node chain */ if( NodeChain ) { ReleaseNodeMemory( NodeChain ); NodeChain = NULL; } if( NodeNo == 0L ) if(( rc = GetHeadNode()) != 0 ) { CurDbfRec = 0L; return rc; }#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) if((rc = LockIndex(F_SETLKW, F_RDLCK)) != 0) return rc;#endif /* get a node and add it to the link */ if( NodeNo == 0L ) { if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ) { CurDbfRec = 0L;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; } } else { if(( rc = GetLeafNode( NodeNo, 1 )) != 0 ) { CurDbfRec = 0L;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif 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 ) { CurDbfRec = 0L;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; } CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode; } CurNode->CurKeyNo--; /* leaf node has one fewer ix recs */ CurDbfRec = GetDbfNo( CurNode->Leaf.NoOfKeysThisNode-1, 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 xbNdx::GetPrevKey( xbShort RetrieveSw ){/* This routine returns 0 on success and sets CurDbfRec to the record *//* corresponding to the previous index pointer */ xbNdxNodeLink * TempxbNodeLink; xbLong TempNodeNo; xbShort rc = 0; if( !IndexStatus ) { CurDbfRec = 0L; xb_error(XB_NOT_OPEN); } if( !CurNode ) { CurDbfRec = 0L; return GetFirstKey( RetrieveSw ); }#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) if((rc = LockIndex(F_SETLKW, F_RDLCK)) != 0) return rc;#endif /* more keys on this node ? */ if( CurNode->CurKeyNo > 0 ) { 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; } /* 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 */ if( !CurNode->PrevNode ) { /* michael - make sure prev node exists */#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif xb_eof_error; } TempxbNodeLink = CurNode; CurNode = CurNode->PrevNode; CurNode->NextNode = NULL; ReleaseNodeMemory( TempxbNodeLink ); /* while no more left keys && not head node, pop up one node */ while(( CurNode->CurKeyNo == 0 ) && ( CurNode->NodeNo != HeadNode.StartNode )) { TempxbNodeLink = CurNode; CurNode = CurNode->PrevNode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -