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

📄 ndx.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************                          ndx.cpp  -  description                             -------------------    begin                : Thu Jan 17 2002    copyright            : (C) 2002 by     email                :  ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//*  $Id: ndx.cpp,v 1.10 2001/03/21 00:28:53 dbryson Exp $    Xbase project source code    NDX indexing routines for X-Base    Copyright (C) 1997 StarTech, Gary A. Kunkel       This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Contact:      Mail:        Technology Associates, Inc.        XBase Project        1455 Deming Way #11        Sparks, NV 89434        USA      Email:        xbase@techass.com      See our website at:        xdb.sourceforge.net    V 1.0     10/10/97   - Initial release of software    V 1.3     11/30/97   - Moved GetLong and GetShort to DBF class    V 1.5     1/2/98     - Added Dbase IV memo field support    V 1.6a    4/1/98     - Added expression support    V 1.6b    4/8/98     - Numeric index keys    V 1.7.4b  6/2/98     - Big Endian fix in PutLeafNode - JAM                         - Fix in Reindex  - PS                         - Fix in Findkey( Tkey, DbfRec )              9/29/98    - Fix in CreateIndex to calculate KeyLen & size                            Paul Koufalis pkoufalis@cogicom.com                         - sequence duplicate keys in dbf# order    V 1.8     11/30/98   - Version 1.8 upgrade    V 1.9      4/12/99   - Added fix to AddKey routine for dup keys                          - Modified CreateIndex logic - KeySize field */#ifdef __GNUG__  #pragma implementation "ndx.h"#endif#ifdef __WIN32__#include "xbconfigw32.h"#else#include "xbconfig.h"#endif#include "xbase.h"#include <iostream.h>#ifdef XB_INDEX_NDX#ifdef HAVE_IO_H#include <io.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include "xbexcept.h"/*! \file ndx.cpp*/#define USE_BSEARCH/***********************************************************************///! Short description/*!*/xbShort xbNdx::CloneNodeChain(){   xbNdxNodeLink * TempNodeS;   xbNdxNodeLink * TempNodeT;   xbNdxNodeLink * TempNodeT2;   if( CloneChain ) ReleaseNodeMemory( CloneChain );   CloneChain = NULL;   if( !NodeChain ) return XB_NO_ERROR;   TempNodeS = NodeChain;   TempNodeT2 = NULL;   while( TempNodeS )   {      if(( TempNodeT = GetNodeMemory()) == NULL ) {    xb_memory_error;      }      memcpy( TempNodeT, TempNodeS, sizeof( struct xbNdxNodeLink ));      TempNodeT->NextNode = NULL;      TempNodeT->PrevNode = TempNodeT2;      if( !CloneChain )      {         TempNodeT2 = TempNodeT;         CloneChain = TempNodeT;      }      else      {         TempNodeT2->NextNode = TempNodeT;         TempNodeT2 = TempNodeT2->NextNode;      }      TempNodeS = TempNodeS->NextNode;   }   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!*/xbShort xbNdx::UncloneNodeChain(){   if( NodeChain )      ReleaseNodeMemory( NodeChain );   NodeChain = CloneChain;   CloneChain = NULL;   CurNode = NodeChain;   while( CurNode->NextNode )      CurNode = CurNode->NextNode;   return XB_NO_ERROR;}/***********************************************************************///! Short description/*!*//* This routine dumps the node chain to stdout                         */#ifdef XBASE_DEBUGvoid xbNdx::DumpNodeChain(){   xbNdxNodeLink  *n;   cout << "\n*************************\n";   cout <<   "xbNodeLinkCtr = " << xbNodeLinkCtr;   cout << "\nReused      = " << ReusedxbNodeLinks << "\n";   n = NodeChain;   while(n)   {      cout << "xbNodeLink Chain" << n->NodeNo << "\n";      n = n->NextNode;   }   n = FreeNodeChain;   while(n)   {      cout << "FreexbNodeLink Chain" << n->NodeNo << "\n";      n = n->NextNode;   }   n = DeleteChain;   while(n)   {      cout << "DeleteLink Chain" << n->NodeNo << "\n";      n = n->NextNode;   }}#endif/***********************************************************************///! Short description/*!  \param n*//* This routine returns a chain of one or more index nodes back to the *//* free node chain                                                     */void xbNdx::ReleaseNodeMemory( xbNdxNodeLink * n ){   xbNdxNodeLink * temp;   if( !FreeNodeChain )      FreeNodeChain = n;   else    /* put this list at the end */   {      temp = FreeNodeChain;      while( temp->NextNode )         temp = temp->NextNode;      temp->NextNode = n;   }   return;}/***********************************************************************///! Short description/*!*//* This routine returns a node from the free chain if available,       *//* otherwise it allocates new memory for the requested node             */xbNdxNodeLink * xbNdx::GetNodeMemory( void ){   xbNdxNodeLink * temp;   if( FreeNodeChain )   {      temp = FreeNodeChain;      FreeNodeChain = temp->NextNode;      ReusedxbNodeLinks++;   }   else   {      temp = (xbNdxNodeLink *) malloc( sizeof( xbNdxNodeLink ));      xbNodeLinkCtr++;   }   memset( temp, 0x00, sizeof( xbNdxNodeLink ));   return temp;}/***********************************************************************///! Short description/*!*/#ifdef XBASE_DEBUGvoid xbNdx::DumpHdrNode(){   cout << "\nStart node    = " << HeadNode.StartNode;   cout << "\nTotal nodes   = " << HeadNode.TotalNodes;   cout << "\nNo of keys    = " << HeadNode.NoOfKeys;   cout << "\nKey Length    = " << HeadNode.KeyLen;   cout << "\nKeys Per Node = " << HeadNode.KeysPerNode;   cout << "\nKey type      = " << HeadNode.KeyType;   cout << "\nKey size      = " << HeadNode.KeySize;   cout << "\nUnknown 2     = " << HeadNode.Unknown2;   cout << "\nUnique        = " << HeadNode.Unique;   cout << "\nKeyExpression = " << HeadNode.KeyExpression;#ifdef XB_VAR_NODESIZE   cout << "\nNodeSize      = " << NodeSize;#endif // XB_VAR_NODESIZE   cout << "\n";#if 0   FILE * log;   if(( log = fopen( "xbase.log", "a+t" )) == NULL ) return;   fprintf( log, "\n-------------------" );   fprintf( log, "\nStart node    =%ld ",  HeadNode.StartNode );   fprintf( log, "\nTotal nodes   =%ld ",  HeadNode.TotalNodes );   fprintf( log, "\nNo of keys    =%ld ",  HeadNode.NoOfKeys );   fprintf( log, "\nKey Length    =%d ",   HeadNode.KeyLen );   fprintf( log, "\nKeys Per Node =%d ",   HeadNode.KeysPerNode );   fprintf( log, "\nKey type      =%d ",   HeadNode.KeyType );   fprintf( log, "\nKey size      =%ld ",  HeadNode.KeySize );   fprintf( log, "\nUnknown 2     =%d ",   HeadNode.Unknown2 );   fprintf( log, "\nUnique        =%d ",   HeadNode.Unique );   fprintf( log, "\nKeyExpression =%s \n", HeadNode.KeyExpression );   fclose( log );#endif}#endif/***********************************************************************///! Short description/*!  \param pdbf*/xbNdx::xbNdx(xbDbf *pdbf) : xbIndex(pdbf) {#ifndef XB_VAR_NODESIZE   memset( Node, 0x00, XB_NDX_NODE_SIZE );#else   memset( Node, 0x00, XB_MAX_NDX_NODE_SIZE );#endif   memset( &HeadNode, 0x00, sizeof( xbNdxHeadNode ));    NodeChain       = NULL;   CloneChain      = NULL;   FreeNodeChain   = NULL;   DeleteChain     = NULL;   CurNode         = NULL;   xbNodeLinkCtr     = 0L;   ReusedxbNodeLinks = 0L;#ifndef XB_VAR_NODESIZE   NodeSize = XB_NDX_NODE_SIZE;#else   NodeSize = XB_DEFAULT_NDX_NODE_SIZE;#endif // XB_VAR_NODESIZE}/***********************************************************************///! Short description/*!  \param FileName*/xbShort xbNdx::OpenIndex( const char * FileName ){   int NameLen, rc;   NameLen = strlen( FileName ) + 1;   if(( rc = dbf->NameSuffixMissing( 2, FileName )) > 0 )     if(( rc = dbf->NameSuffixMissing( 4, FileName )) > 0 )       NameLen += 4;   IndexName = FileName;   if( rc == 1 )     IndexName += ".ndx";   else     if ( rc == 2 )       IndexName += ".NDX";   /* open the file */   if(( indexfp = fopen( IndexName, "r+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_RDLCK)) != 0)        return rc;#endif          IndexStatus = 1;    if(( rc = GetHeadNode()) != 0)    { #ifdef XB_LOCKING_ON      if( dbf->GetAutoLock() )         LockIndex(F_SETLKW, F_UNLCK);#endif      fclose( indexfp );      return rc;   }   /* parse the expression */   if(( rc = dbf->xbase->BuildExpressionTree( HeadNode.KeyExpression,      strlen( HeadNode.KeyExpression ), 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(); //dbf->xbase->DumpExpressionTree(ExpressionTree);      KeyBuf  = (char *) malloc( HeadNode.KeyLen + 1 );    KeyBuf2 = (char *) malloc( HeadNode.KeyLen + 1);   memset( KeyBuf,  0x00, HeadNode.KeyLen + 1 );   memset( KeyBuf2, 0x00, HeadNode.KeyLen + 1 );   rc = dbf->AddIndexToIxList( index, IndexName );#ifdef XB_LOCKING_ON   if( dbf->GetAutoLock() )      LockIndex(F_SETLKW, F_UNLCK);#endif   return rc;}/***********************************************************************///! Short description/*!*/xbShort xbNdx::CloseIndex( void ){   if( KeyBuf )    { free ( KeyBuf );    KeyBuf = NULL;    }   if( KeyBuf2 )   { free ( KeyBuf2 );   KeyBuf2 = NULL;   }   dbf->RemoveIndexFromIxList( index );   fclose( indexfp );   IndexStatus = 0;   return 0;}/***********************************************************************///! Short description/*!*/xbShort xbNdx::GetHeadNode( void ){   char *p, *q;   xbShort i;   if( !IndexStatus )     xb_error(XB_NOT_OPEN);   if( fseek( indexfp, 0, SEEK_SET ))     xb_io_error(XB_SEEK_ERROR, IndexName);   if(( fread( Node, XB_NDX_NODE_SIZE, 1, indexfp )) != 1 )     xb_io_error(XB_READ_ERROR, IndexName);   /* load the head node structure */   p = Node;   HeadNode.StartNode   = dbf->xbase->GetLong ( p ); p+=4;   HeadNode.TotalNodes  = dbf->xbase->GetLong ( p ); p+=4;   HeadNode.NoOfKeys    = dbf->xbase->GetLong ( p ); p+=4;   HeadNode.KeyLen      = dbf->xbase->GetShort( p ); p+=2;   HeadNode.KeysPerNode = dbf->xbase->GetShort( p ); p+=2;   HeadNode.KeyType     = dbf->xbase->GetShort( p ); p+=2;   HeadNode.KeySize     = dbf->xbase->GetLong ( p ); p+=4;   HeadNode.Unknown2    = *p++;   HeadNode.Unique      = *p++;   #ifdef XB_VAR_NODESIZE   //   //  Automagically determine the node size.  Note the (2 * sizeof(xbLong))   //  is taken directly from CreateIndex().  I don't understand it exactly,   //  but this is the value used to calculate the number of keys per node.   //  DTB.   //   NodeSize = (2 * sizeof(xbLong)) + HeadNode.KeySize * HeadNode.KeysPerNode;//printf("NodeSize = %d\n", NodeSize);   if(NodeSize % XB_NDX_NODE_MULTIPLE)     NodeSize = ((NodeSize + XB_NDX_NODE_MULTIPLE) / XB_NDX_NODE_MULTIPLE) *                  XB_NDX_NODE_MULTIPLE;//printf("NodeSize = %d\n", NodeSize);#endif   q = HeadNode.KeyExpression;   for( i = XB_NDX_NODE_BASESIZE; i < XB_NDX_NODE_SIZE && *p; i++ )      *q++ = *p++;   return 0;}/***********************************************************************///! Short description/*!  \param NodeNo  \param SetNodeChain*//* This routine reads a leaf node from disk                            *//*                                                                     *//*  If SetNodeChain 2, then the node is not appended to the node chain *//*                     but the CurNode pointer points to the node read *//*  If SetNodeChain 1, then the node is appended to the node chain     *//*  If SetNodeChain 0, then record is only read to Node memory         */xbShort xbNdx::GetLeafNode( xbLong NodeNo, xbShort SetNodeChain ){   xbNdxNodeLink *n;   if( !IndexStatus )     xb_error(XB_NOT_OPEN);   if( fseek( indexfp, NodeNo * XB_NDX_NODE_SIZE, SEEK_SET ))     xb_io_error(XB_SEEK_ERROR, IndexName);   if(( fread( Node, XB_NDX_NODE_SIZE, 1, indexfp )) != 1 )     xb_io_error(XB_READ_ERROR, IndexName);   if( !SetNodeChain ) return 0;   if(( n = GetNodeMemory()) == NULL )     xb_memory_error;   n->NodeNo = NodeNo;   n->CurKeyNo = 0L;   n->NextNode = NULL;   n->Leaf.NoOfKeysThisNode = dbf->xbase->GetLong( Node );   memcpy( n->Leaf.KeyRecs, Node+4, XB_NDX_NODE_SIZE - 4 );   /* put the node in the chain */   if( SetNodeChain == 1 )   {      if( NodeChain == NULL )      /* first one ? */      {          NodeChain = n;         CurNode = n;         CurNode->PrevNode = NULL;      }

⌨️ 快捷键说明

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