⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndx.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      memcpy( FieldName, TempNode->NodeText, TempNode->Len );      Type = dbf->GetFieldType( dbf->GetFieldNo( FieldName ));      if( Type == 'N' || Type == 'F' )         return -8;   }   if(( rc = dbf->xbase->ProcessExpression( ExpressionTree )) != XB_NO_ERROR )      return 0;      //   dbf->xbase->DumpExpressionTree(ExpressionTree);   TempNode = (xbExpNode *) dbf->xbase->Pop();   if( !TempNode )     return 0;   rc = TempNode->DataLen;   if( !TempNode->InTree )     delete TempNode;//     dbf->xbase->FreeExpNode( TempNode );//printf("CalcKeyLen returning %d\n", rc);   return rc;}/***********************************************************************///! Short description/*!  \param IxName  \param Exp  \param Unique  \param Overlay*/xbShort xbNdx::CreateIndex(const char * IxName, const char * Exp,          xbShort Unique, xbShort Overlay ){   xbShort i, NameLen, KeyLen, rc;   IndexStatus = XB_CLOSED;   if( strlen( Exp ) > 488 )     xb_error(XB_INVALID_KEY_EXPRESSION);   if( dbf->GetDbfStatus() == 0 )     xb_error(XB_NOT_OPEN);   /* Get the index file name and store it in the class */   NameLen = strlen( IxName ) + 1;   if(( rc = dbf->NameSuffixMissing( 2, IxName )) > 0 )      NameLen +=4;   IndexName = IxName;      if( rc == 1 )     IndexName += ".ndx";   else if( rc == 2 )     IndexName += ".NDX";   /* check if the file already exists */   if (((indexfp = fopen( IndexName, "r" )) != NULL ) && !Overlay ) {      fclose( indexfp );      xb_io_error(XB_FILE_EXISTS, IndexName);   }   if (indexfp)     fclose(indexfp);   if(( indexfp = fopen( IndexName, "w+b" )) == NULL )       xb_open_error(IndexName);#ifdef XB_LOCKING_ON      /*   **  Must turn off buffering when multiple programs may be accessing   **  index files.   */   setbuf( indexfp, NULL );#endif   #ifdef XB_LOCKING_ON   if( dbf->GetAutoLock() )      if((rc = LockIndex(F_SETLKW, F_WRLCK)) != 0)        return rc;#endif   /* parse the expression */   if(( rc = dbf->xbase->BuildExpressionTree( Exp, strlen( Exp ), dbf )) != XB_NO_ERROR )   {#ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif      return rc;   }   ExpressionTree = dbf->xbase->GetTree();   dbf->xbase->SetTreeToNull();    /* build the header record */   memset( &HeadNode, 0x00, sizeof( xbNdxHeadNode ));   HeadNode.StartNode  = 1L;   HeadNode.TotalNodes = 2L;   HeadNode.NoOfKeys   = 1L;   KeyLen = CalcKeyLen();   if( KeyLen == 0 || KeyLen > 100 )       /* 100 byte key length limit */     xb_error(XB_INVALID_KEY)   else if( KeyLen == -8 )   {       HeadNode.KeyType = 1;                /* numeric key */      HeadNode.KeyLen = 8;    }   else   {       HeadNode.KeyType = 0;                /* character key */      HeadNode.KeyLen = KeyLen;    }//   HeadNode.KeysPerNode = (xbUShort) ( XB_NDX_NODE_SIZE - (2*sizeof( xbLong ))) ///      (HeadNode.KeyLen + 8 );//   HeadNode.KeySize = HeadNode.KeyLen + 8;//   while(( HeadNode.KeySize % 4 ) != 0 ) HeadNode.KeySize++;  /* multiple of 4*//* above code replaced with following by Paul Koufalis pkoufalis@cogicom.com *///   while(( HeadNode.KeyLen % 4 ) != 0 ) HeadNode.KeyLen++;  /* multiple of 4*///   HeadNode.KeySize = HeadNode.KeyLen + 8;/* above two lines commented out by gary 4/14/99 and replaced w/ following     For compatibilyt with other Xbase tools      KeyLen is the length of the key data      KeySize = KeyLen+8, rounded up until divisible by 4*/   HeadNode.KeySize = HeadNode.KeyLen + 8;   while(( HeadNode.KeySize % 4 ) != 0 ) HeadNode.KeySize++;  /* multiple of 4*/   HeadNode.KeysPerNode = (xbUShort)     (XB_NDX_NODE_SIZE - (2*sizeof( xbLong ))) / HeadNode.KeySize;   HeadNode.Unique = Unique;   strncpy( HeadNode.KeyExpression, Exp, 488 );   KeyBuf  = (char *) malloc( HeadNode.KeyLen + 1 );    KeyBuf2 = (char *) malloc( HeadNode.KeyLen + 1 );    memset( KeyBuf,  0x00, HeadNode.KeyLen + 1 );   memset( KeyBuf2, 0x00, HeadNode.KeyLen + 1 );   if(( rc = PutHeadNode( &HeadNode, indexfp, 0 )) != 0 )    {#ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif      return rc;   }   /* write node #1 all 0x00 */   for( i = 0; i < XB_NDX_NODE_SIZE; i++ )   {      if ((fwrite("\x00", 1, 1, indexfp)) != 1)       {#ifdef XB_LOCKING_ON         if( dbf->GetAutoLock() )            LockIndex(F_SETLKW, F_UNLCK);#endif       fclose( indexfp );    xb_io_error(XB_WRITE_ERROR, IndexName);      }   }   IndexStatus = XB_OPEN;#ifdef XB_LOCKING_ON   if( dbf->GetAutoLock() )      LockIndex(F_SETLKW, F_UNLCK);#endif   return dbf->AddIndexToIxList( index, IndexName );  }/***********************************************************************///! Short description/*!  \param RecNo  \param n  \param NodeNo*/xbShort xbNdx::PutLeftNodeNo( xbShort RecNo, xbNdxNodeLink *n, xbLong NodeNo ){   /* This routine sets n node's leftnode number */   xbNdxLeafNode *temp;   char *p;   if( !n )     xb_error(XB_INVALID_NODELINK);   temp = &n->Leaf;   if( RecNo < 0 || RecNo > HeadNode.KeysPerNode)     xb_error(XB_INVALID_KEY);   p = temp->KeyRecs;   p+= RecNo * ( 8 + HeadNode.KeyLen );   dbf->xbase->PutLong( p, NodeNo );   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!  \param RecNo  \param n  \param DbfNo*/xbShort xbNdx::PutDbfNo( xbShort RecNo, xbNdxNodeLink *n, xbLong DbfNo ){   /* This routine sets n node's dbf number */   xbNdxLeafNode *temp;   char *p;   if( !n )     xb_error(XB_INVALID_NODELINK);   temp = &n->Leaf;   if( RecNo < 0 || RecNo > (HeadNode.KeysPerNode-1))     xb_error(XB_INVALID_KEY);   p = temp->KeyRecs + 4;   p+= RecNo * ( 8 + HeadNode.KeyLen );   dbf->xbase->PutLong( p, DbfNo );   return XB_NO_ERROR;}/************************************************************************///! Short description/*!  \param l  \param n*/xbShort xbNdx::PutLeafNode( xbLong l, xbNdxNodeLink *n ){   if ((fseek(indexfp, l * XB_NDX_NODE_SIZE , SEEK_SET)) != 0) {     fclose( indexfp );     xb_io_error(XB_SEEK_ERROR, IndexName);   }   dbf->xbase->PutLong( Node, n->Leaf.NoOfKeysThisNode );   if(( fwrite( Node, 4, 1, indexfp )) != 1 )   {     fclose( indexfp );     xb_io_error(XB_WRITE_ERROR, IndexName);   }   if(( fwrite( &n->Leaf.KeyRecs, XB_NDX_NODE_SIZE-4, 1, indexfp )) != 1 )   {     fclose( indexfp );     xb_io_error(XB_WRITE_ERROR, IndexName);   }   return 0;   }/************************************************************************///! Short description/*!  \param Head  \param f  \param UpdateOnly*/xbShort xbNdx::PutHeadNode( xbNdxHeadNode * Head, FILE * f, xbShort UpdateOnly ){   char buf[4];    if(( fseek( f, 0L, SEEK_SET )) != 0 )   {     fclose( f );     xb_io_error(XB_SEEK_ERROR, IndexName);   }   memset( buf, 0x00, 4 );   dbf->xbase->PutLong( buf, Head->StartNode );   if(( fwrite( &buf, 4, 1, f )) != 1 )   {     fclose( f );     xb_io_error(XB_WRITE_ERROR, IndexName);   }   memset( buf, 0x00, 4 );   dbf->xbase->PutLong( buf, Head->TotalNodes );   if(( fwrite( &buf, 4, 1, f )) != 1 )   {     fclose( f );     xb_io_error(XB_WRITE_ERROR, IndexName);   }   memset( buf, 0x00, 4 );   dbf->xbase->PutLong( buf, Head->NoOfKeys );   if(( fwrite( &buf, 4, 1, f )) != 1 )   {     fclose( f );     xb_io_error(XB_WRITE_ERROR, IndexName);   }   if( UpdateOnly )      return XB_NO_ERROR;   memset( buf, 0x00, 2 );   dbf->xbase->PutLong( buf, Head->KeyLen );   if(( fwrite( &buf, 2, 1, f )) != 1 )   {     fclose( f );     xb_io_error(XB_WRITE_ERROR, IndexName);   }   memset( buf, 0x00, 2 );   dbf->xbase->PutLong( buf, Head->KeysPerNode );   if(( fwrite( &buf, 2, 1, f )) != 1 )   {      fclose( f );      xb_io_error(XB_WRITE_ERROR, IndexName);   }   memset( buf, 0x00, 2 );   dbf->xbase->PutLong( buf, Head->KeyType );   if(( fwrite( &buf, 2, 1, f )) != 1 )   {     fclose( f );     xb_io_error(XB_WRITE_ERROR, IndexName);   }   memset( buf, 0x00, 4 );   dbf->xbase->PutLong( buf, Head->KeySize );   if(( fwrite( &buf, 4, 1, f )) != 1 )   {     fclose( f );     xb_io_error(XB_WRITE_ERROR, IndexName);   }//   if(( fwrite( &Head->Unknown2, 490, 1, f )) != 1 )   if(( fwrite( &Head->Unknown2, XB_NDX_NODE_SIZE - 22, 1, f )) != 1 )   {     fclose( f );     xb_io_error(XB_WRITE_ERROR, IndexName);   }   return 0;   }/************************************************************************///! Short description/*!  \param RecNo  \param n*/xbShort xbNdx::PutKeyData( xbShort RecNo, xbNdxNodeLink *n ){   /* This routine copies the KeyBuf data into xbNdxNodeLink n */   xbNdxLeafNode *temp;   char *p;   xbShort i;   if( !n )     xb_error(XB_INVALID_NODELINK);   temp = &n->Leaf;   if( RecNo < 0 || RecNo > (HeadNode.KeysPerNode-1))     xb_error(XB_INVALID_KEY);   p = temp->KeyRecs + 8;   p+= RecNo * ( 8 + HeadNode.KeyLen );   for( i = 0; i < HeadNode.KeyLen; i++ )   {      *p = KeyBuf[i];      p++;   }   return XB_NO_ERROR;}/************************************************************************///! Short description/*!  \param n  \param pos  \param d  \param l  \param w*/xbShort xbNdx::PutKeyInNode( xbNdxNodeLink * n, xbShort pos, xbLong d,     xbLong l, xbShort w ){   xbShort i;   /* check the node */   if (!n)     xb_error(XB_INVALID_NODELINK);   if(pos < 0 || pos > HeadNode.KeysPerNode)     xb_error(XB_INVALID_RECORD);   if(n->Leaf.NoOfKeysThisNode >= HeadNode.KeysPerNode)     xb_error(XB_NODE_FULL);   /* if key movement, save the original key */   if( pos < n->Leaf.NoOfKeysThisNode )      memcpy( KeyBuf2, KeyBuf, HeadNode.KeyLen + 1);   /* if interior node, handle the right most left node no */   if( GetLeftNodeNo( 0, n ))      PutLeftNodeNo( n->Leaf.NoOfKeysThisNode+1, n,         GetLeftNodeNo( n->Leaf.NoOfKeysThisNode, n ));   for( i = n->Leaf.NoOfKeysThisNode; i > pos; i-- )   {      memcpy( KeyBuf, GetKeyData(i-1,n), HeadNode.KeyLen );        PutKeyData( i, n );      PutDbfNo( i, n, GetDbfNo(i-1,n));      PutLeftNodeNo(i, n, GetLeftNodeNo(i-1,n));   }   /* put new key in node */   if( pos < n->Leaf.NoOfKeysThisNode )      memcpy( KeyBuf, KeyBuf2, HeadNode.KeyLen + 1);   PutKeyData( pos, n );   PutDbfNo( pos, n, d );   PutLeftNodeNo( pos, n, l );   n->Leaf.NoOfKeysThisNode++;   if( w )      return PutLeafNode( n->NodeNo, n );   else      return 0;}/************************************************************************///! Short description/*!  \param n1  \param n2  \param pos  \param d*/xbShort xbNdx::SplitLeafNode( xbNdxNodeLink *n1, xbNdxNodeLink *n2,   xbShort pos, xbLong d ){   xbShort i,j,rc;   if( !n1 || !n2 )     xb_error(XB_INVALID_NODELINK);   if( pos < 0 || pos > HeadNode.KeysPerNode )     xb_error(XB_INVALID_NODELINK);   if( pos < HeadNode.KeysPerNode ) /* if it belongs in node */   {      /* save the original key */      memcpy( KeyBuf2, KeyBuf, HeadNode.KeyLen + 1);      PutKeyData( HeadNode.KeysPerNode, n2 );       for( j = 0,i = pos; i < n1->Leaf.NoOfKeysThisNode; j++,i++ )      {         memcpy( KeyBuf, GetKeyData( i, n1 ), HeadNode.KeyLen );         PutKeyData   ( j, n2 );         PutDbfNo     ( j, n2, GetDbfNo  ( i, n1 ));         n2->Leaf.NoOfKeysThisNode++;       }      /* restore original key */      memcpy( KeyBuf, KeyBuf2, HeadNode.KeyLen + 1);      /* update original leaf */      PutKeyData( pos, n1 );      PutDbfNo  ( pos, n1, d );      n1->Leaf.NoOfKeysThisNode = pos+1;   }            else    /* put the key in a new node because it doesn't fit in the CurNode*/   {      PutKeyData   ( 0, n2 );      PutDbfNo     ( 0, n2, d );      n2->Leaf.NoOfKeysThisNode++;    }   if(( rc = PutLeafNode( n1->NodeNo, n1 )) != 0 )       return rc;   if(( rc = PutLeafNode( n2->NodeNo, n2 )) != 0 )       return rc;   return 0;}/************************************************************************///! Short description/*!  \param n1  \param n2  \param t*/xbShort xbNdx::SplitINode( xbNdxNodeLink *n1, xbNdxNodeLink *n2, xbLong t )                   /* parent, tempnode, tempnodeno */{   xbShort i,j,rc;   xbNdxNodeLink * SaveNodeChain;   xbNdxNodeLink * SaveCurNode;   /* if not at the end of the node shift everthing to the right */   if( n1->CurKeyNo+1 < HeadNode.KeysPerNode )   /* this clause appears to work */   {      if( CurNode->NodeNo == HeadNode.StartNode ) cout << "\nHead node ";         for( j = 0,i = n1->CurKeyNo+1; i < n1->Leaf.NoOfKeysThisNode; i++,j++ )       {         memcpy( KeyBuf, GetKeyData( i, n1 ), HeadNode.KeyLen );          PutKeyData( j, n2 );         PutLeftNodeNo( j, n2, GetLeftNodeNo( i, n1 ));      }      PutLeftNodeNo( j, n2, GetLeftNodeNo( i, n1 ));         n2->Leaf.NoOfKeysThisNode = n1->Leaf.NoOfKeysThisNode -         n1->CurKeyNo - 1;      n1->Leaf.NoOfKeysThisNode = n1->Leaf.NoOfKeysThisNode -          n2->Leaf.NoOfKeysThisNode;      /* attach the new leaf to the original parent */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -