Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

ndx.h

Go to the documentation of this file.
00001 /*  $Id: ndx.h,v 1.11 2003/08/16 19:59:39 gkunkel Exp $
00002 
00003     Xbase project source code
00004 
00005     This file contains a header file for the xbNdx object, which is used
00006     for handling NDX type indices.
00007 
00008     Copyright (C) 1997  Gary A. Kunkel   
00009 
00010     This library is free software; you can redistribute it and/or
00011     modify it under the terms of the GNU Lesser General Public
00012     License as published by the Free Software Foundation; either
00013     version 2.1 of the License, or (at your option) any later version.
00014 
00015     This library is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018     Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public
00021     License along with this library; if not, write to the Free Software
00022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 
00024     Contact:
00025 
00026       Mail:
00027 
00028         Technology Associates, Inc.
00029         XBase Project
00030         1455 Deming Way #11
00031         Sparks, NV 89434
00032         USA
00033 
00034       Email:
00035 
00036         xbase@techass.com
00037         xdb-devel@lists.sourceforge.net
00038         xdb-users@lists.sourceforge.net
00039 
00040       See our website at:
00041 
00042         xdb.sourceforge.net
00043 
00044 */
00045 
00046 #ifndef __XB_NDX_H__
00047 #define __XB_NDX_H__
00048 
00049 #ifdef __GNUG__
00050 #pragma interface
00051 #endif
00052 
00053 #include <xbase/xbase.h>
00054 #include <string.h>
00055 
00059 //
00060 // Define the following to use inline versions of the respective methods.
00061 //
00062 #define XB_INLINE_COMPAREKEY
00063 #define XB_INLINE_GETDBFNO
00064 
00065 #define XB_NDX_NODE_BASESIZE            24      // size of base header data
00066 
00067 #define XB_VAR_NODESIZE                 // define to enable variable node sizes
00068 
00069 #ifndef XB_VAR_NODESIZE
00070 #define XB_NDX_NODE_SIZE 2048
00071 //#define XB_NDX_NODE_SIZE 512          // standard dbase node size
00072 #else
00073 #define XB_DEFAULT_NDX_NODE_SIZE        512
00074 #define XB_MAX_NDX_NODE_SIZE            4096
00075 #define XB_NDX_NODE_SIZE                NodeSize
00076 #define XB_NDX_NODE_MULTIPLE            512
00077 #endif // XB_VAR_NODESIZE
00078 
00080 
00083 struct XBDLLEXPORT xbNdxHeadNode {        /* ndx header on disk */
00084    xbLong   StartNode;                    /* header node is node 0 */
00085    xbLong   TotalNodes;                   /* includes header node */
00086    xbLong   NoOfKeys;                     /* actual count + 1 */
00087    xbUShort KeyLen;                       /* length of key data */
00088    xbUShort KeysPerNode;
00089    xbUShort KeyType;                      /* 00 = Char, 01 = Numeric */
00090    xbLong   KeySize;                      /* key len + 8 bytes */
00091    char   Unknown2;
00092    char   Unique;
00093 //   char   KeyExpression[488];
00094 #ifndef XB_VAR_NODESIZE
00095    char   KeyExpression[XB_NDX_NODE_SIZE - 24];
00096 #else
00097    char   KeyExpression[XB_MAX_NDX_NODE_SIZE - 24];
00098 #endif // XB_VAR_NODESIZE
00099 };
00100 
00102 
00105 struct XBDLLEXPORT xbNdxLeafNode {        /* ndx node on disk */
00106    xbLong   NoOfKeysThisNode;
00107 #ifndef XB_VAR_NODESIZE
00108    char   KeyRecs[XB_NDX_NODE_SIZE-4];
00109 #else
00110    char     KeyRecs[XB_MAX_NDX_NODE_SIZE - 4];
00111 #endif // XB_VAR_NODESIZE
00112 };
00113 
00115 
00118 struct XBDLLEXPORT xbNdxNodeLink {        /* ndx node memory */
00119    xbNdxNodeLink * PrevNode;
00120    xbNdxNodeLink * NextNode;
00121    xbLong       CurKeyNo;                 /* 0 - KeysPerNode-1 */
00122    xbLong       NodeNo;
00123    struct xbNdxLeafNode Leaf;
00124 };
00125 
00127 
00130 class XBDLLEXPORT xbNdx : public xbIndex
00131 {
00132 //   xbExpNode * ExpressionTree;    /* Expression tree for index */
00133 
00134 public:
00135    xbNdx();
00136    xbNdx(xbDbf *);
00137    virtual ~xbNdx();
00138 
00139 /* don't uncomment next line - it causes seg faults for some undiagnosed reason*/
00140 //   ~NDX() { if( NdxStatus ) CloseIndex(); }
00141 
00142    xbShort  OpenIndex ( const char * FileName );
00143    xbShort  CloseIndex();
00144    xbShort  CreateIndex( const char *IxName, const char *Exp,
00145                          xbShort Unique, xbShort OverLay );
00146    xbLong   GetTotalNodes();
00147    xbULong  GetCurDbfRec() { return CurDbfRec; }
00148    xbShort  CreateKey( xbShort, xbShort );
00149    xbShort  GetCurrentKey(char *key);
00150    xbShort  AddKey( xbLong );
00151    xbShort  UniqueIndex() { return HeadNode.Unique; }
00152    xbShort  DeleteKey( xbLong );
00153    xbShort  KeyWasChanged();
00154    xbShort  FindKey( const char *Key );
00155    xbShort  FindKey();
00156    xbShort  FindKey( xbDouble );
00157 #ifdef XBASE_DEBUG
00158    void     DumpHdrNode();
00159    void     DumpNodeRec( xbLong NodeNo );
00160    void     DumpNodeChain();
00161    xbShort  CheckIndexIntegrity( const xbShort Option );
00162 #endif
00163 
00164 
00166    xbShort  GetNextKey()  { return GetNextKey( 1 ); }
00168 
00170    xbShort  GetLastKey()  { return GetLastKey( 0, 1 ); }
00172 
00174    xbShort  GetFirstKey() { return GetFirstKey( 1 ); }
00176 
00178    xbShort  GetPrevKey()  { return GetPrevKey( 1 ); }
00179    xbShort  ReIndex(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
00180    xbShort  KeyExists( const char * Key ) { return FindKey( Key, strlen( Key ), 0 ); }
00181    xbShort  KeyExists( xbDouble );
00182 
00183    virtual void SetNodeSize(xbShort size);
00184 
00185    virtual void GetExpression(char *buf, int len);
00186 
00187 protected:
00188    xbNdxHeadNode HeadNode;
00189    xbNdxLeafNode LeafNode;
00190    xbLong xbNodeLinkCtr;
00191    xbLong ReusedxbNodeLinks;
00192 #if 0 // overrides IndexName in xbIndex
00193    xbString IndexName;
00194 #endif
00195 
00196 #ifndef XB_VAR_NODESIZE
00197    char  Node[XB_NDX_NODE_SIZE];
00198 #else
00199    char  Node[XB_MAX_NDX_NODE_SIZE];
00200 #endif // XB_VAR_NODESIZE
00201 //   FILE  *ndxfp;
00202 //   int   NdxStatus;                /* 0 = closed, 1 = open */
00203 
00204    xbNdxNodeLink * NodeChain;     /* pointer to node chain of index nodes */
00205    xbNdxNodeLink * FreeNodeChain; /* pointer to chain of free index nodes */
00206    xbNdxNodeLink * CurNode;       /* pointer to current node              */
00207    xbNdxNodeLink * DeleteChain;   /* pointer to chain to delete           */
00208    xbNdxNodeLink * CloneChain;    /* pointer to node chain copy (add dup) */
00209 #if 0 // these override those in xbIndex
00210    xbLong  CurDbfRec;             /* current Dbf record number */
00211    char  *KeyBuf;                 /* work area key buffer */
00212    char  *KeyBuf2;                /* work area key buffer */
00213 #endif
00214 
00215 /* private functions */
00216    xbLong     GetLeftNodeNo( xbShort, xbNdxNodeLink * );
00217 #ifndef XB_INLINE_COMPAREKEY
00218    xbShort    CompareKey( const char *Key1, const char *Key2, xbShort Klen );
00219 #else
00220 
00221 
00223    inline xbShort    CompareKey( const char *Key1, const char *Key2, xbShort Klen )
00224    {
00225 #if 0
00226      const  char *k1, *k2;
00227      xbShort  i;
00228 #endif
00229      xbDouble d1, d2;
00230      int c;
00231 
00232      if(!( Key1 && Key2 )) return -1;
00233 
00234      if( Klen > HeadNode.KeyLen ) Klen = HeadNode.KeyLen;
00235 
00236      if( HeadNode.KeyType == 0 )
00237      {
00238        c = memcmp(Key1, Key2, Klen);
00239        if(c < 0)
00240          return 2;
00241        else if(c > 0)
00242          return 1;
00243        return 0;
00244      }
00245      else      /* key is numeric */
00246      {
00247         d1 = dbf->xbase->GetDouble( Key1 );
00248         d2 = dbf->xbase->GetDouble( Key2 );
00249         if( d1 == d2 ) return 0;
00250         else if( d1 > d2 ) return 1;
00251         else return 2;
00252      }
00253    }
00254 #endif
00255 #ifndef XB_INLINE_GETDBFNO
00256    xbLong     GetDbfNo( xbShort, xbNdxNodeLink * );
00257 #else
00258 
00259 
00261    inline xbLong     GetDbfNo( xbShort RecNo, xbNdxNodeLink *n )
00262    {
00263      xbNdxLeafNode *temp;
00264      char *p;
00265      if( !n ) return 0L;
00266      temp = &n->Leaf;
00267      if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode - 1 )) return 0L;
00268      p = temp->KeyRecs + 4;
00269      p += RecNo * ( 8 + HeadNode.KeyLen );
00270      return( dbf->xbase->GetLong( p ));
00271    }
00272 #endif
00273    char *     GetKeyData( xbShort, xbNdxNodeLink * );
00274    xbUShort   GetKeysPerNode();
00275    xbShort    GetHeadNode();
00276    xbShort    GetLeafNode( xbLong, xbShort );
00277    xbNdxNodeLink * GetNodeMemory();
00278    void       ReleaseNodeMemory(xbNdxNodeLink *n, bool doFree = false);
00279    xbShort    BSearchNode(const char *key, xbShort klen,
00280                           const xbNdxNodeLink *node,
00281                           xbShort *comp);
00282    xbLong     GetLeafFromInteriorNode( const char *Tkey, xbShort Klen );
00283    xbShort    CalcKeyLen();
00284    xbShort    PutKeyData( xbShort, xbNdxNodeLink * );
00285    xbShort    PutLeftNodeNo( xbShort, xbNdxNodeLink *, xbLong );
00286    xbShort    PutLeafNode( xbLong, xbNdxNodeLink * );
00287    xbShort    PutHeadNode( xbNdxHeadNode *, FILE *, xbShort );
00288    xbShort    PutDbfNo( xbShort, xbNdxNodeLink *, xbLong );
00289    xbShort    PutKeyInNode( xbNdxNodeLink *, xbShort, xbLong, xbLong, xbShort );
00290    xbShort    SplitLeafNode( xbNdxNodeLink *, xbNdxNodeLink *, xbShort, xbLong );
00291    xbShort    SplitINode( xbNdxNodeLink *, xbNdxNodeLink *, xbLong );
00292    xbShort    AddToIxList();
00293    xbShort    RemoveFromIxList();
00294    xbShort    RemoveKeyFromNode( xbShort, xbNdxNodeLink * );
00295    xbShort    FindKey( const char *Tkey, xbShort Klen, xbShort RetrieveSw );
00296    xbShort    UpdateParentKey( xbNdxNodeLink * );
00297    xbShort    GetFirstKey( xbShort );
00298    xbShort    GetNextKey( xbShort );
00299    xbShort    GetLastKey( xbLong, xbShort );
00300    xbShort    GetPrevKey( xbShort );
00301    void       UpdateDeleteList( xbNdxNodeLink * );
00302    void       ProcessDeleteList();
00303    xbNdxNodeLink * LeftSiblingHasSpace( xbNdxNodeLink * );
00304    xbNdxNodeLink * RightSiblingHasSpace( xbNdxNodeLink * );
00305    xbShort    DeleteSibling( xbNdxNodeLink * );
00306    xbShort    MoveToLeftNode( xbNdxNodeLink *, xbNdxNodeLink * );
00307    xbShort    MoveToRightNode( xbNdxNodeLink *, xbNdxNodeLink * );
00308    xbShort    FindKey( const char *Tkey, xbLong DbfRec );   /* for a specific dbf no */
00309 
00310    xbShort    CloneNodeChain();          
00311    xbShort    UncloneNodeChain();        
00312    
00313 //#ifdef XB_LOCKING_ON
00314 //   xbShort  LockIndex( const xbShort, const xbShort ) const;
00315 //#else
00316 //   xbShort  LockIndex( const xbShort, const xbShort ) const { return NO_ERROR; }
00317 //#endif
00318 
00319 };
00320 #endif      /* __XB_NDX_H__ */

Generated on Wed Jan 26 11:45:09 2005 for Xbase Class Library by  doxygen 1.4.1