📄 ntx.cpp
字号:
} 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 xbNtx::GetPrevKey( xbShort RetrieveSw ){/* This routine returns 0 on success and sets CurDbfRec to the record *//* corresponding to the previous 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 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return GetFirstKey( RetrieveSw ); } /* 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#ifdef HAVE_EXCEPTIONS throw xbEoFException();#else return XB_EOF;#endif } TempNodeLink = CurNode; CurNode = CurNode->PrevNode; CurNode->NextNode = NULL; ReleaseNodeMemory( TempNodeLink ); /* while no more left keys && not head node, pop up one node */ while(( CurNode->CurKeyNo == 0 ) && ( CurNode->NodeNo != HeadNode.StartNode )) { TempNodeLink = CurNode; CurNode = CurNode->PrevNode; CurNode->NextNode = NULL; ReleaseNodeMemory( TempNodeLink ); } /* if head node && left most key, return end-of-file */ if(( HeadNode.StartNode == CurNode->NodeNo ) && ( CurNode->CurKeyNo == 0 )) {#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 left */ 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; } if( GetLeftNodeNo( 0, CurNode )) /* if interior node */ CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode; else /* leaf node */ CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode -1;/* traverse down the right side of the tree */ while( GetLeftNodeNo( 0, CurNode )) /* while interior node */ { 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; } if( GetLeftNodeNo( 0, CurNode )) /* if interior node */ CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode; else /* leaf node */ CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode -1; } 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 Key1 \param Key2 \param Klen*/xbShort xbNtx::CompareKey( const char * Key1, const char * Key2, xbShort Klen ){/* if key1 = key2 --> return 0 *//* if key1 > key2 --> return 1 *//* if key1 < key2 --> return 2 */ const char *k1, *k2; xbShort i; if( Klen > HeadNode.KeyLen ) Klen = HeadNode.KeyLen; k1 = Key1; k2 = Key2; for( i = 0; i < Klen; i++ ) { if( *k1 > *k2 ) return 1; if( *k1 < *k2 ) return 2; k1++; k2++; } return 0;}/***********************************************************************///! Short description./*! \param Key1 \param Key2*/xbShort xbNtx::CompareKey( const char * Key1, const char * Key2){/* if key1 = key2 --> return 0 *//* if key1 > key2 --> return 1 *//* if key1 < key2 --> return 2 */ int rc; rc = strcmp(Key1, Key2); if (rc < 0) return 2; else if (rc > 0) return 1; else return 0;}/***********************************************************************///! Short description./*! \param Tkey \param */xbULong xbNtx::GetLeafFromInteriorNode( const char * Tkey, xbShort ){ /* This function scans an interior node for a key and returns the */ /* correct interior leaf node no */ xbShort rc, p; /* if Tkey > any keys in node, return right most key */ p = CurNode->Leaf.NoOfKeysThisNode -1 ; if( CompareKey( Tkey, GetKeyData( p, CurNode )) == 1 ) { CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode; return GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode ); } /* otherwise, start at the beginning and scan up */ p = 0; while( p < CurNode->Leaf.NoOfKeysThisNode) { rc = CompareKey( Tkey, GetKeyData( p, CurNode ) ); if (rc == 2) break; else if (rc == 0) { CurNode->CurKeyNo = p; CurDbfRec = GetDbfNo( p, CurNode ); return 0; } p++; } CurNode->CurKeyNo = p; return GetLeftNodeNo( p, CurNode );}/***********************************************************************///! Short description./*! \param d*/xbShort xbNtx::KeyExists( xbDouble d ){ char buf[9]; memset( buf, 0x00, 9 ); dbf->xbase->PutDouble( buf, d ); return FindKey( buf, 8, 0 );}/***********************************************************************///! Short description./*! \param d*/xbShort xbNtx::FindKey( xbDouble d ){ char buf[9]; memset( buf, 0x00, 9 ); dbf->xbase->PutDouble( buf, d ); return FindKey( buf, 8, 1 );}/***********************************************************************///! Short description./*! \param Key*/xbShort xbNtx::FindKey( const char * Key ){ return FindKey( Key, strlen( Key ), 1 );}/***********************************************************************///! Short description./*! \param Tkey \param DbfRec*/xbShort xbNtx::FindKey( const char * Tkey, xbLong DbfRec ){ /* find a key with a specifc xbDbf record number */ xbShort rc; xbLong CurDbfRecNo; xbLong CurNtxDbfNo;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) if((rc = LockIndex(F_SETLKW, F_RDLCK)) != 0) return rc;#endif /* if we are already on the correct key, return XB_FOUND */ if( CurNode ) { CurDbfRecNo = dbf->GetCurRecNo(); CurNtxDbfNo = GetDbfNo( CurNode->CurKeyNo, CurNode ); if( CurDbfRecNo == CurNtxDbfNo ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return XB_FOUND; } } rc = FindKey( Tkey, HeadNode.KeyLen, 0 ); while( rc == 0 || rc == XB_FOUND ) { if( strncmp( Tkey, GetKeyData( CurNode->CurKeyNo, CurNode ), HeadNode.KeyLen ) == 0 ) { if( DbfRec == GetDbfNo( CurNode->CurKeyNo, CurNode )) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return XB_FOUND; } else rc = GetNextKey( 0 ); } else {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return XB_NOT_FOUND; } }#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return XB_NOT_FOUND;}/***********************************************************************///! Short description./*!*/xbShort xbNtx::FindKey( void ){ /* if no paramaters given, use KeyBuf */ return( FindKey( KeyBuf, HeadNode.KeyLen, 0 ));}/***********************************************************************///! Short description./*! \param Tkey \param Klen \param RetrieveSw*/xbShort xbNtx::FindKey( const char * Tkey, xbShort Klen, xbShort RetrieveSw ){ /* This routine sets the current key to the found key */ /* if RetrieveSw is true, the method positions the dbf record */ xbShort rc,i; xbLong TempNodeNo;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) if((rc = LockIndex(F_SETLKW, F_RDLCK)) != 0) return rc;#endif if( NodeChain ) { ReleaseNodeMemory( NodeChain ); NodeChain = NULL; } if(( rc = GetHeadNode()) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return rc; } // If the index is empty if ( HeadNode.StartNode == 0) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return XB_NOT_FOUND; } /* load first node */ if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ) { CurDbfRec = 0L;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; } /* traverse down the tree until it hits a leaf */ while( GetLeftNodeNo( 0, CurNode )) /* while interior node */ { TempNodeNo = GetLeafFromInteriorNode( Tkey, Klen );#if 1 // GetLeafFromInteriorNode will return 0 if the key is found on // an inode. But the leftNodeNo will not be 0. if (TempNodeNo == 0 && GetLeftNodeNo( 0, CurNode ) != 0) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif if( RetrieveSw ) dbf->GetRecord( CurDbfRec ); return XB_FOUND; }#endif if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ) {#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif CurDbfRec = 0L; return rc; } } /* leaf level */ for( i = 0; i < CurNode->Leaf.NoOfKeysThisNode; i++ ) { rc = CompareKey( Tkey, GetKeyData( i, CurNode ) ); if( rc == 0 ) { CurNode->CurKeyNo = i; CurDbfRec = GetDbfNo( i, CurNode );#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif if( RetrieveSw ) dbf->GetRecord( CurDbfRec ); return XB_FOUND; } else if( rc == 2 ) { CurNode->CurKeyNo = i; CurDbfRec = GetDbfNo( i, CurNode ); if( RetrieveSw ) dbf->GetRecord( CurDbfRec ); // If key is lessthan, without length involved, // Check to see if the substring match#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif if (CompareKey( Tkey, GetKeyData( i, CurNode ), Klen ) == 0) return XB_FOUND; else return XB_NOT_FOUND; } } CurNode->CurKeyNo = i; CurDbfRec = GetDbfNo( i, CurNode );#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif if( RetrieveSw ) dbf->GetRecord( CurDbfRec ); return XB_NOT_FOUND;}/***********************************************************************///! Short description./*!*/xbShort xbNtx::CalcKeyLen( void ){ xbShort rc; xbExpNode * TempNode; char FieldName[11]; char Type; TempNode = dbf->xbase->GetFirstTreeNode( ExpressionTree );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -