Xbase64 Class Library 3.1.2
xbndx.h
Go to the documentation of this file.
00001 /*  xbndx.h
00002 
00003     Xbase64 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,2003  Gary A Kunkel
00009     
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU Lesser General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program 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
00018     GNU Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public License
00021     along with this program; 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      Email:
00027     
00028       xdb-devel@lists.sourceforge.net
00029       xdb-users@lists.sourceforge.net
00030       
00031     
00032      Regular Mail:
00033      
00034        XBase Support
00035        149C South Main St
00036        Keller Texas, 76248     
00037        USA
00038 
00039 */
00040 
00041 #ifndef __XB_NDX_H__
00042 #define __XB_NDX_H__
00043 
00044 #ifdef __GNU LesserG__
00045 #pragma interface
00046 #endif
00047 
00048 #include <xbase64/xbase64.h>
00049 #include <string.h>
00050 
00054 //
00055 // Define the following to use inline versions of the respective methods.
00056 //
00057 #define XB_INLINE_GETDBFNO
00058 
00059 #define XB_NDX_NODE_BASESIZE            24      // size of base header data
00060 
00061 #define XB_VAR_NODESIZE                 // define to enable variable node sizes
00062 
00063 #ifndef XB_VAR_NODESIZE
00064 #define XB_NDX_NODE_SIZE 2048
00065 //#define XB_NDX_NODE_SIZE 512          // standard dbase node size
00066 #else
00067 #define XB_DEFAULT_NDX_NODE_SIZE        512
00068 #define XB_MAX_NDX_NODE_SIZE            4096
00069 #define XB_NDX_NODE_SIZE                NodeSize
00070 #define XB_NDX_NODE_MULTIPLE            512
00071 #endif // XB_VAR_NODESIZE
00072 
00074 
00077 struct XBDLLEXPORT xbNdxHeadNode {        /* ndx header on disk */
00078    xbLong   StartNode;                    /* header node is node 0 */
00079    xbLong   TotalNodes;                   /* includes header node */
00080    xbLong   NoOfKeys;                     /* actual count + 1 */
00081                                           /* not updated by borland dbe? */
00082    xbUShort KeyLen;                       /* length of key data */
00083    xbUShort KeysPerNode;
00084    xbUShort KeyType;                      /* 00 = Char, 01 = Numeric */
00085    xbLong   KeySize;                      /* key len + 8 bytes */
00086    char     Unknown2;
00087    char     Unique;
00088 // char     KeyExpression[488];
00089 #ifndef XB_VAR_NODESIZE
00090    char     KeyExpression[XB_NDX_NODE_SIZE - 24];
00091 #else
00092    char     KeyExpression[XB_MAX_NDX_NODE_SIZE - 24];
00093 #endif // XB_VAR_NODESIZE
00094 };
00095 
00097 
00100 struct XBDLLEXPORT xbNdxLeafNode {        /* ndx node on disk */
00101    xbLong   NoOfKeysThisNode;
00102 #ifndef XB_VAR_NODESIZE
00103    char   KeyRecs[XB_NDX_NODE_SIZE-4];
00104 #else
00105    char   KeyRecs[XB_MAX_NDX_NODE_SIZE - 4];
00106 #endif // XB_VAR_NODESIZE
00107 };
00108 
00110 
00113 struct XBDLLEXPORT xbNdxNodeLink {        /* ndx node memory */
00114    xbNdxNodeLink * PrevNode;
00115    xbNdxNodeLink * NextNode;
00116    xbLong       CurKeyNo;                 /* 0 - KeysPerNode-1 */
00117    xbLong       NodeNo;
00118    struct xbNdxLeafNode Leaf;
00119 };
00120 
00122 
00125 class XBDLLEXPORT xbNdx : public xbIndex
00126 {
00127  public:
00128    xbNdx();
00129    xbNdx(xbDbf *);
00130    virtual ~xbNdx();
00131 
00132 /* don't uncomment next line - it causes seg faults for some undiagnosed reason*/
00133 //   ~NDX() { if( NdxStatus ) CloseIndex(); }
00134 
00135    xbShort  CreateIndex( const char *IxName, const char *Exp,
00136                          xbShort Unique, xbShort OverLay );
00137    xbLong   GetTotalNodes();
00138    xbULong  GetCurDbfRec() { return CurDbfRec; }
00139    xbShort  CreateKey( xbShort, xbShort );
00140    xbShort  GetCurrentKey(char *key);
00141    xbShort  AddKey( xbLong );
00142    xbShort  UniqueIndex() { return HeadNode.Unique; }
00143    xbShort  DeleteKey( xbLong );
00144    xbShort  KeyWasChanged();
00145    xbShort  FindKey( const char *Key );
00146    xbShort  FindKey();
00147    xbShort  FindKey( xbDouble );
00148 #ifdef XBASE_DEBUG
00149    void     DumpHdrNode( xbShort Option );
00150    void     DumpNodeRec( xbLong NodeNo );
00151    void     DumpNodeChain();
00152    xbShort  CheckIndexIntegrity( xbShort Option );
00153 #endif
00154 
00155 
00157    xbShort  GetNextKey()  { return GetNextKey( 1 ); }
00159 
00161    xbShort  GetLastKey()  { return GetLastKey( 0, 1 ); }
00163 
00165    xbShort  GetFirstKey() { return GetFirstKey( 1 ); }
00167 
00169    xbShort  GetPrevKey()  { return GetPrevKey( 1 ); }
00170    xbShort  ReIndex(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
00171    xbShort  KeyExists( const char * Key ) { return FindKey( Key, strlen( Key ), 0 ); }
00172    xbShort  KeyExists( xbDouble );
00173 
00174    virtual void SetNodeSize(xbShort size);
00175 
00176    virtual void GetExpression(char *buf, int len);
00177    virtual const char* GetExtWithDot(bool lower);
00178 
00179   protected:
00180     virtual xbUShort GetKeyLen();
00181     virtual const char* GetKeyExpression();
00182     virtual void FreeNodesMemory();
00183 
00184   protected:
00185    xbNdxHeadNode HeadNode;
00186    xbNdxLeafNode LeafNode;
00187    xbLong xbNodeLinkCtr;
00188    xbLong ReusedxbNodeLinks;
00189 
00190 #ifndef XB_VAR_NODESIZE
00191    char  Node[XB_NDX_NODE_SIZE];
00192 #else
00193    char  Node[XB_MAX_NDX_NODE_SIZE];
00194 #endif // XB_VAR_NODESIZE
00195 
00196    xbNdxNodeLink * NodeChain;     /* pointer to node chain of index nodes */
00197    xbNdxNodeLink * FreeNodeChain; /* pointer to chain of free index nodes */
00198    xbNdxNodeLink * CurNode;       /* pointer to current node              */
00199    xbNdxNodeLink * DeleteChain;   /* pointer to chain to delete           */
00200 //   xbNdxNodeLink * CloneChain;    /* pointer to node chain copy (add dup) */
00201 
00202 /* private functions */
00203    xbLong     GetLeftNodeNo( xbShort, xbNdxNodeLink * );
00204 
00205 
00206    // in line functions for performance reasons
00208 
00210    inline xbShort    CompareKey( const char *Key1, const char *Key2, xbShort Klen )
00211    {
00212      xbDouble d1, d2;
00213      int c;
00214 
00215      if(!( Key1 && Key2 )) return -1;
00216 
00217      if( Klen > HeadNode.KeyLen ) Klen = HeadNode.KeyLen;
00218 
00219      if( HeadNode.KeyType == 0 )
00220      {
00221        c = memcmp(Key1, Key2, Klen);
00222        if(c < 0)
00223          return 2;
00224        else if(c > 0)
00225          return 1;
00226        return 0;
00227      }
00228      else      /* key is numeric */
00229      {
00230         d1 = dbf->xbase->GetDouble( Key1 );
00231         d2 = dbf->xbase->GetDouble( Key2 );
00232         if( d1 == d2 ) return 0;
00233         else if( d1 > d2 ) return 1;
00234         else return 2;
00235      }
00236    }
00237 
00238 #ifndef XB_INLINE_GETDBFNO
00239    xbLong     GetDbfNo( xbShort, xbNdxNodeLink * );
00240 #else
00241 
00242 
00244    inline xbLong     GetDbfNo( xbShort RecNo, xbNdxNodeLink *n )
00245    {
00246      xbNdxLeafNode *temp;
00247      char *p;
00248      if( !n ) return 0L;
00249      temp = &n->Leaf;
00250      if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode - 1 )) return 0L;
00251      p = temp->KeyRecs + 4;
00252      p += RecNo * ( 8 + HeadNode.KeyLen );
00253      return( dbf->xbase->GetLong( p ));
00254    }
00255 #endif
00256    char *     GetKeyData( xbShort, xbNdxNodeLink * );
00257    xbUShort   GetKeysPerNode();
00258    virtual xbShort    GetHeadNode();
00259    xbShort    GetLeafNode( xbLong, xbShort );
00260    xbNdxNodeLink * GetNodeMemory();
00261    void       ReleaseNodeMemory(xbNdxNodeLink *n, xbBool doFree = false);
00262    xbShort    BSearchNode(const char *key, xbShort klen,
00263                          const xbNdxNodeLink *node, xbShort *comp);
00264    xbLong     GetLeafFromInteriorNode( const char *Tkey, xbShort Klen );
00265    xbShort    CalcKeyLen();
00266    xbShort    PutKeyData( xbShort, xbNdxNodeLink * );
00267    xbShort    PutLeftNodeNo( xbShort, xbNdxNodeLink *, xbLong );
00268    xbShort    PutLeafNode( xbLong, xbNdxNodeLink * );
00269    xbShort    PutHeadNode( xbNdxHeadNode *, FILE *, xbShort );
00270    xbShort    PutDbfNo( xbShort, xbNdxNodeLink *, xbLong );
00271    xbShort    PutKeyInNode( xbNdxNodeLink *, xbShort, xbLong, xbLong, xbShort );
00272    xbShort    SplitLeafNode( xbNdxNodeLink *, xbNdxNodeLink *, xbShort, xbLong );
00273    xbShort    SplitINode( xbNdxNodeLink *, xbNdxNodeLink *, xbLong );
00274    xbShort    AddToIxList();
00275    xbShort    RemoveFromIxList();
00276    xbShort    RemoveKeyFromNode( xbShort, xbNdxNodeLink * );
00277    xbShort    FindKey( const char *Tkey, xbShort Klen, xbShort RetrieveSw );
00278    xbShort    UpdateParentKey( xbNdxNodeLink * );
00279    xbShort    GetFirstKey( xbShort );
00280    xbShort    GetNextKey( xbShort );
00281    xbShort    GetLastKey( xbLong, xbShort );
00282    xbShort    GetPrevKey( xbShort );
00283    void       UpdateDeleteList( xbNdxNodeLink * );
00284    void       ProcessDeleteList();
00285    xbNdxNodeLink * LeftSiblingHasSpace( xbNdxNodeLink * );
00286    xbNdxNodeLink * RightSiblingHasSpace( xbNdxNodeLink * );
00287    xbShort    DeleteSibling( xbNdxNodeLink * );
00288    xbShort    MoveToLeftNode( xbNdxNodeLink *, xbNdxNodeLink * );
00289    xbShort    MoveToRightNode( xbNdxNodeLink *, xbNdxNodeLink * );
00290    xbShort    FindKey( const char *Tkey, xbLong DbfRec );   /* for a specific dbf no */
00291 };
00292 #endif      /* __XB_NDX_H__ */