📄 ndx.cpp
字号:
CurNode->NextNode = NULL; ReleaseNodeMemory( TempxbNodeLink ); } /* 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 xb_eof_error; } /* 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 ) { 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;}#ifndef XB_INLINE_COMPAREKEY/***********************************************************************///! Short description/*! \param Key1 \param Key2 \param Klen*/xbShort xbNdx::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; xbDouble d1, d2; int c; if(!( Key1 && Key2 )) return -1; if( Klen > HeadNode.KeyLen ) Klen = HeadNode.KeyLen; if( HeadNode.KeyType == 0 ) {#if 0 k1 = Key1; k2 = Key2; for( i = 0; i < Klen; i++ ) { if( *k1 > *k2 ) return 1; if( *k1 < *k2 ) return 2; k1++; k2++; } return 0;#else//printf("comparing '%s' to '%s'\n", Key1, Key2); c = memcmp(Key1, Key2, Klen); if(c < 0) return 2; else if(c > 0) return 1; return 0;#endif } else /* key is numeric */ { d1 = dbf->xbase->GetDouble( Key1 ); d2 = dbf->xbase->GetDouble( Key2 ); if( d1 == d2 ) return 0; else if( d1 > d2 ) return 1; else return 2; }}#endif/**************************************************************************///! Short description/*! \param key \param klen \param node \param comp*//*** This is a pretty basic binary search with two exceptions: 1) it will** find the first of duplicate key values and 2) will return the index** and the value of the last comparision even if it doesn't find a ** match.*/xbShortxbNdx::BSearchNode(const char *key, xbShort klen, const xbNdxNodeLink *node, xbShort *comp){ xbShort c = 1, p = -1, start = 0, end = node->Leaf.NoOfKeysThisNode - 1; if(start > end) { *comp = 2; return 0; } do { p = (start + end) / 2; c = CompareKey(key, GetKeyData(p, (xbNdxNodeLink *)node), klen); switch(c) { case 1 : /* greater than */ start = p + 1; break; case 2 : /* less than */ end = p - 1; break; } } while(start <= end && c); if(c == 1) while(p < node->Leaf.NoOfKeysThisNode && (c = CompareKey(key, GetKeyData(p, (xbNdxNodeLink *)node), klen)) == 1) p++; *comp = c; if(!c) while(p > 0 && !CompareKey(key, GetKeyData(p - 1, (xbNdxNodeLink *)node), klen)) p--; return p;}/***********************************************************************///! Short description/*! \param Tkey \param Klen*/xbLong xbNdx::GetLeafFromInteriorNode( const char * Tkey, xbShort Klen ){ /* This function scans an interior node for a key and returns the */ /* correct interior leaf node no */ xbShort p, c; /* if Tkey > any keys in node, return right most key */ p = CurNode->Leaf.NoOfKeysThisNode - 1; if( CompareKey( Tkey, GetKeyData( p, CurNode ), Klen ) == 1 ) { CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode; return GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode ); }#ifndef USE_BSEARCH /* otherwise, start at the beginning and scan up */ p = 0; while( p < CurNode->Leaf.NoOfKeysThisNode && ( CompareKey( Tkey, GetKeyData( p, CurNode ), Klen ) == 1 )) p++;#else p = BSearchNode(Tkey, Klen, CurNode, &c);// if(c == 1)// p++;#endif CurNode->CurKeyNo = p; return GetLeftNodeNo( p, CurNode );}/***********************************************************************///! Short description/*! \param d*/xbShort xbNdx::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 xbNdx::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 xbNdx::FindKey( const char * Key ){ return FindKey( Key, strlen( Key ), 1 );}/***********************************************************************///! Short description/*! \param Tkey \param DbfRec*/xbShort xbNdx::FindKey( const char * Tkey, xbLong DbfRec ){ /* find a key with a specifc DBF record number */ xbShort rc; xbLong CurDbfRecNo; xbLong CurNdxDbfNo;#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(); CurNdxDbfNo = GetDbfNo( CurNode->CurKeyNo, CurNode ); if( CurDbfRecNo == CurNdxDbfNo && (strncmp(Tkey, GetKeyData( CurNode->CurKeyNo, CurNode ), HeadNode.KeyLen ) == 0 )) {#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 xbNdx::FindKey( void ){ /* if no paramaters given, use KeyBuf */ return( FindKey( KeyBuf, HeadNode.KeyLen, 0 ));}/***********************************************************************///! Short description/*! \param Tkey \param Klen \param RetrieveSw*/xbShort xbNdx::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; if( NodeChain ) { ReleaseNodeMemory( NodeChain ); NodeChain = NULL; }#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) if((rc = LockIndex(F_SETLKW, F_RDLCK)) != 0) return rc;#endif if(( rc = GetHeadNode()) != 0 ) { CurDbfRec = 0L;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; } /* 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(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ) { CurDbfRec = 0L;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return rc; } } /* leaf level */#ifndef USE_BSEARCH for( i = 0; i < CurNode->Leaf.NoOfKeysThisNode; i++ ) { rc = CompareKey( Tkey, GetKeyData( i, CurNode ), Klen ); 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 );#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif if (RetrieveSw) dbf->GetRecord(CurDbfRec); return XB_NOT_FOUND; } }#else i = BSearchNode(Tkey, Klen, CurNode, &rc); switch(rc) { case 0 : /* 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_FOUND; case 1 : /* less than */// if(i < CurNode->Leaf.NoOfKeysThisNode) break;// i++; case 2 : /* greater than */ 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; }#endif CurNode->CurKeyNo = i; if(i >= CurNode->Leaf.NoOfKeysThisNode) { CurDbfRec = 0;#ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return XB_EOF; } CurDbfRec = GetDbfNo( i, CurNode ); if ((RetrieveSw) && (CurDbfRec > 0)) dbf->GetRecord( CurDbfRec ); #ifdef XB_LOCKING_ON if( dbf->GetAutoLock() ) LockIndex(F_SETLKW, F_UNLCK);#endif return XB_NOT_FOUND;}/***********************************************************************///! Short description/*!*/xbShort xbNdx::CalcKeyLen( void ){ xbShort rc; xbExpNode * TempNode; char FieldName[11]; char Type; TempNode = dbf->xbase->GetFirstTreeNode( ExpressionTree ); if( !TempNode ) return 0; if( TempNode->Type == 'd' ) return -8; if( TempNode->Type == 'D' ) { memset( FieldName, 0x00, 11 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -