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

📄 ntx.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
📖 第 1 页 / 共 5 页
字号:
       temp  = n1->offsets[end];       for( i = end; i > start; i--)       {           n1->offsets[i] = n1->offsets[i-1];       }       n1->offsets[start] = temp;       // Insert new key       PutKeyData( start , n1 );       PutDbfNo  ( start , n1, d );   }   else    {       // If the passed-in key IS median key, just copy it.       if (pos == HeadNode.HalfKeysPerNode)       {           memcpy(PushItem.Key,                  KeyBuf,                  HeadNode.KeyLen);           PushItem.RecordNumber = d;           start = pos;           end = pos;       }       else       {           // Otherwise, the median key will be middle key becasue the           // new key will be inserted somewhere above the middle.           memcpy(PushItem.Key,                  GetKeyData(HeadNode.HalfKeysPerNode,  n1),                  HeadNode.KeyLen);           PushItem.RecordNumber = GetDbfNo(HeadNode.HalfKeysPerNode, n1);           start = HeadNode.HalfKeysPerNode ;           end = pos -1;       }       temp  = n1->offsets[start];       for( i = start; i < end; i++)       {           n1->offsets[i] = n1->offsets[i+1];       }       n1->offsets[end] = temp;       // Insert new key       PutKeyData( pos -1 , n1 );       PutDbfNo  ( pos -1 , n1, d );   }         // Dup the node data   memcpy(n2->Leaf.KeyRecs, n1->Leaf.KeyRecs, XB_NTX_NODE_SIZE);   // Dup the offsets   for ( i = 0; i < HeadNode.KeysPerNode +1; i++)   {       n2->offsets[i] = n1->offsets[i];   }   // Setup the second node   for (j = 0, i = HeadNode.HalfKeysPerNode; i < HeadNode.KeysPerNode; i++, j++ )   {       temp = n2->offsets[j];       n2->offsets[j] = n2->offsets[i];       n2->offsets[i] = temp;   }   // Get the last offset for both nodes   temp = n2->offsets[j];   n2->offsets[j] = n2->offsets[HeadNode.KeysPerNode];   n2->offsets[HeadNode.KeysPerNode] = temp;   // Set the new count of both nodes   n2->Leaf.NoOfKeysThisNode = HeadNode.HalfKeysPerNode;   n1->Leaf.NoOfKeysThisNode = HeadNode.HalfKeysPerNode;   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*/xbShort xbNtx::SplitINode( xbNodeLink *n1, xbNodeLink *n2, xbLong )                   /* parent, tempnode, tempnodeno */{   xbShort i,j,rc;   xbShort temp;      xbShort pos = n1->CurKeyNo;   xbShort start;   xbShort end;   xbLong n1LastNodeNo = 0;   NtxItem oldPushItem;   oldPushItem.Node = PushItem.Node;   oldPushItem.RecordNumber = PushItem.RecordNumber;   memcpy(oldPushItem.Key, PushItem.Key, sizeof(PushItem.Key));      //   n2->NodeNo = HeadNode.TotalNodes++;   n2->NodeNo = GetNextNodeNo();   // If the new key goes in the first node.   if (pos < HeadNode.HalfKeysPerNode)   {             // Setup key to insert into parent       memcpy(PushItem.Key,              GetKeyData(HeadNode.HalfKeysPerNode -1, n1),              HeadNode.KeyLen);       PushItem.RecordNumber = GetDbfNo(HeadNode.HalfKeysPerNode -1, n1);       PushItem.Node =  n2->NodeNo;              n1LastNodeNo = GetLeftNodeNo(HeadNode.HalfKeysPerNode -1, n1);              start = pos;       end = HeadNode.HalfKeysPerNode - 1;       // Insert the new key.       temp  = n1->offsets[end];       for( i = end; i > start; i--)       {           n1->offsets[i] = n1->offsets[i-1];       }       n1->offsets[start] = temp;   }      else   {       // If the passed-in key IS median key, just copy it.       if (pos == HeadNode.HalfKeysPerNode)       {           PutLeftNodeNo(0, n2, oldPushItem.Node);           // PushItem should remain the same, except for its left pointer           PushItem.Node = n2->NodeNo;           start = pos;           end = pos;       }       else        {           // Otherwise, the median key will be middle key becasue the           // new key will be inserted somewhere above the middle.           memcpy(PushItem.Key,                  GetKeyData(HeadNode.HalfKeysPerNode,  n1),                  HeadNode.KeyLen);           PushItem.RecordNumber = GetDbfNo(HeadNode.HalfKeysPerNode, n1);           PushItem.Node = n2->NodeNo;           n1LastNodeNo = GetLeftNodeNo(HeadNode.HalfKeysPerNode, n1);           //           start = HeadNode.HalfKeysPerNode + 1;            start = HeadNode.HalfKeysPerNode;            end = pos -1;           // Insert the new key.           temp  = n1->offsets[start];           for( i = start; i < end; i++)           {               n1->offsets[i] = n1->offsets[i+1];           }           n1->offsets[end] = temp;           pos--;       }   }   /* restore original key */   memcpy( KeyBuf, oldPushItem.Key, HeadNode.KeyLen + 1);   // Insert new key   PutKeyData( pos, n1 );   PutDbfNo  ( pos, n1, oldPushItem.RecordNumber);   PutLeftNodeNo( pos, n1, GetLeftNodeNo (pos + 1, n1));   PutLeftNodeNo( pos + 1  /* +1 ?*/, n1, oldPushItem.Node /* t */ );      // Dup the node data into the new page   memcpy(n2->Leaf.KeyRecs, n1->Leaf.KeyRecs, XB_NTX_NODE_SIZE);   // Dup the offsets   for ( i = 0; i < HeadNode.KeysPerNode +1; i++)   {       n2->offsets[i] = n1->offsets[i];   }   // Setup the second node   for (j = 0, i = HeadNode.HalfKeysPerNode; i < HeadNode.KeysPerNode; i++, j++ )   {       temp = n2->offsets[j];       n2->offsets[j] = n2->offsets[i];       n2->offsets[i] = temp;   }   // Get the last offset for both nodes   temp = n2->offsets[j];   n2->offsets[j] = n2->offsets[HeadNode.KeysPerNode];   n2->offsets[HeadNode.KeysPerNode] = temp;      PutLeftNodeNo(HeadNode.HalfKeysPerNode, n1, n1LastNodeNo);      // Set the new count of both nodes   n2->Leaf.NoOfKeysThisNode = HeadNode.HalfKeysPerNode;   n1->Leaf.NoOfKeysThisNode = HeadNode.HalfKeysPerNode;      if((rc = PutLeafNode( n1->NodeNo,n1 )) != 0) return rc;   if((rc = PutLeafNode( n2->NodeNo,n2 )) != 0) return rc;   return 0;}/************************************************************************///! Short description./*!  \param RecBufSw  \param KeyBufSw*/xbShort xbNtx::CreateKey( xbShort RecBufSw, xbShort KeyBufSw ){    /* RecBufSw   0   Use RecBuf    */   /*            1   Use RecBuf2   */   /* KeyBufSw   0   Use KeyBuf    */   /*            1   Use KeyBuf2   */   xbShort rc;   xbExpNode * TempNode;   if(( rc = dbf->xbase->ProcessExpression( ExpressionTree, RecBufSw )) != XB_NO_ERROR )      return rc;   TempNode = (xbExpNode *) dbf->xbase->Pop();   if( !TempNode ) xb_error( XB_INVALID_KEY );   if( KeyBufSw )   {       memset( KeyBuf2, 0x00, HeadNode.KeyLen + 1 );       memcpy( KeyBuf2, TempNode->StringResult, TempNode->DataLen );   }   else   {       memset( KeyBuf, 0x00, HeadNode.KeyLen + 1 );       memcpy( KeyBuf, TempNode->StringResult, TempNode->DataLen );   }//   if( !TempNode->InTree ) dbf->xbase->FreeExpNode( TempNode );   if( !TempNode->InTree ) delete TempNode;   return 0;}/************************************************************************///! Short description./*!  \param key*/xbShort  xbNtx::GetCurrentKey(char *key){  CreateKey(0, 0);  memcpy(key, KeyBuf, HeadNode.KeyLen + 1);      return 0;}/************************************************************************///! Short description./*!  \param DbfRec*/xbShort xbNtx::AddKey( xbLong DbfRec ){ /* This routine assumes KeyBuf contains the contents of the index to key */   xbShort i,rc;   xbNodeLink * TempNode;      xbNodeLink * Tparent;   xbLong TempNodeNo = 0L;          /* new, unattached leaf node no */   /* find node key belongs in */   rc = FindKey( KeyBuf, HeadNode.KeyLen, 0 );   if( rc == XB_FOUND && HeadNode.Unique )       xb_error(XB_KEY_NOT_UNIQUE);// 9/29/98// these lines commented out - compatibity wins over efficiency for this library//    /* 1.02 next statement moves to key match w/ space in nodes to reduce splits *///    if( !HeadNode.Unique && rc == XB_FOUND &&//         HeadNode.KeysPerNode == CurNode->Leaf.NoOfKeysThisNode )//    {//       if(( rc = CloneNodeChain()) != XB_NO_ERROR ) return rc;//       if(( rc = GetNextKey( 0 )) != XB_NO_ERROR )//          UncloneNodeChain();//       while( HeadNode.KeysPerNode == CurNode->Leaf.NoOfKeysThisNode &&//              rc == XB_NO_ERROR && //              (CompareKey( KeyBuf, GetKeyData( CurNode->CurKeyNo, CurNode ),//                 HeadNode.KeyLen ) == 0 )//            )//          if(( rc = GetNextKey( 0 )) != XB_NO_ERROR )//             UncloneNodeChain();//    }   /************************************************/   /* section A - if room in node, add key to node */   /************************************************/   if( CurNode->Leaf.NoOfKeysThisNode < HeadNode.KeysPerNode )   {      if(( rc = PutKeyInNode( CurNode,CurNode->CurKeyNo,DbfRec,0L,1)) != 0)         return rc;      if(( rc = PutHeadNode( &HeadNode, indexfp, 1 )) != 0)         return rc;      return XB_NO_ERROR;   }      /***********************************************************************/   /* section B - split leaf node if full and put key in correct position */   /***********************************************************************/   TempNode = GetNodeMemory();   // Create a new page   TempNode->NodeNo = GetNextNodeNo();   rc = SplitLeafNode( CurNode, TempNode, CurNode->CurKeyNo, DbfRec );   if( rc ) return rc;   /* TempNode is on disk, now we have to point someone above to      that node. Keep the NodeNo of the on disk new node.   */   TempNodeNo = TempNode->NodeNo;   ReleaseNodeMemory( TempNode );   /*     PushItem also contains the key to put into the parent     PushItem should point at TempNode    */   PushItem.Node = TempNodeNo;   /*****************************************************/   /* section C go up tree splitting nodes as necessary */   /*****************************************************/   Tparent = CurNode->PrevNode;   while( Tparent &&           Tparent->Leaf.NoOfKeysThisNode >= HeadNode.KeysPerNode )   {      TempNode = GetNodeMemory();      if( !TempNode )#ifdef HAVE_EXCEPTIONS          throw xbOutOfMemoryException();#else      return XB_NO_MEMORY;#endif      rc = SplitINode( Tparent, TempNode, TempNodeNo );      if( rc ) return rc;      TempNodeNo = TempNode->NodeNo;      ReleaseNodeMemory( TempNode );      ReleaseNodeMemory( CurNode );      CurNode = Tparent;      CurNode->NextNode = NULL;      Tparent = CurNode->PrevNode;   }   /************************************************************/   /* Section D  if CurNode is split root, create new root     */   /************************************************************/   /* at this point       CurNode = The node that was just split       TempNodeNo = The new node split off from CurNode */   if(CurNode->NodeNo == HeadNode.StartNode )    {      TempNode = GetNodeMemory();      if( !TempNode )#ifdef HAVE_EXCEPTIONS          throw xbOutOfMemoryException();#else      return XB_NO_MEMORY;#endif      memcpy( KeyBuf, PushItem.Key, HeadNode.KeyLen );      PutKeyData( 0, TempNode );             PutDbfNo ( 0, TempNode, PushItem.RecordNumber );             PutLeftNodeNo( 0, TempNode, CurNode->NodeNo );      PutLeftNodeNo( 1, TempNode, PushItem.Node );      TempNode->NodeNo = GetNextNodeNo();      TempNode->Leaf.NoOfKeysThisNode++;      HeadNode.StartNode = TempNode->NodeNo;      rc = PutLeafNode( TempNode->NodeNo, TempNode );      if( rc ) return rc;      rc = PutHeadNode( &HeadNode, indexfp, 1 );      if( rc ) return rc;      ReleaseNodeMemory( TempNode );      return XB_NO_ERROR;   }   /**********************************/   /* Section E  make room in parent */   /**********************************/   InsertKeyOffset(Tparent->CurKeyNo, Tparent);      /* put key in parent */   i = Tparent->CurKeyNo;   memcpy( KeyBuf, PushItem.Key, HeadNode.KeyLen);   PutKeyData( i, Tparent );   PutDbfNo( i, Tparent, PushItem.RecordNumber);      PutLeftNodeNo( i , Tparent, CurNode->NodeNo );   PutLeftNodeNo( i + 1 , Tparent, TempNodeNo );   Tparent->Leaf.NoOfKeysThisNode++;      rc = PutLeafNode( Tparent->NodeNo, Tparent );   if( rc ) return rc;   rc = PutHeadNode( &HeadNode, indexfp, 1 );   if( rc ) return rc;    return XB_NO_ERROR;}/***********************************************************************///! Short description./*!  \param n*/xbShort xbNtx::UpdateParentKey( xbNodeLink * n ){/* this routine goes backwards thru the node chain looking for a parent   node to update */   xbNodeLink * TempNode;      if( !n ) return XB_INVALID_NODELINK;   if( !GetDbfNo( 0, n ))   {      cout << "Fatal index error - Not a leaf node" << n->NodeNo << "\n";//      exit(0);      return XB_NOT_LEAFNODE;   }   TempNode = n->PrevNode;   while( TempNode )   {      if( TempNode->CurKeyNo < TempNode->Leaf.NoOfKeysThisNode )      {         memcpy(KeyBuf,GetKeyData(n->Leaf.NoOfKeysThisNode-1,n),HeadNode.KeyLen);         PutKeyData( TempNode->CurKeyNo, TempNode );         return PutLeafNode( TempNode->NodeNo, TempNode );      }      TempNode = TempNode->PrevNode;   }   return XB_NO_ERROR;}/***********************************************************************///! Short description./*!  \param n*//* This routine queues up a list of nodes which have been emptied      */void xbNtx::UpdateDeleteList( xbNodeLink *n ){   n->NextNode = DeleteChain;   DeleteChain = n;}/***********************************************************************///! Short description./*!*//* Delete nodes from the node list - for now we leave the empty nodes  *//* dangling in the file. Eventually we will remove nodes from the file */void xbNtx::ProcessDeleteList( void ){   if( DeleteChain )   {      ReleaseNodeMemory( DeleteChain );      DeleteChain = NULL;   }}/***********************************************************************///! Short description./*!*/xbShort xbNtx::KeyWasChanged( void ){   CreateKey( 0, 0 );            /* use KeyBuf,  RecBuf    */   CreateKey( 1, 1 );            /* use KeyBuf2, RecBuf2   */   if( CompareKey( KeyBuf, KeyBuf2, HeadNode.KeyLen ) != 0 )      return 1;   else      return 0;}// /******************************

⌨️ 快捷键说明

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