/***********************************************************************

                      CSDB Library, Free Evaluation Version 2.0.5 
                                       Release: January 22th 1997 

       Header file of the TABLE class.

                                           Copyright(c) 1994-1997 
                                                          ComBits 
                                                  The Netherlands 
***********************************************************************/

#ifndef __CSTABLE_H
#define __CSTABLE_H

#include "cstools.h"
#include "csstr.h"
#include "stdio.h"
#include "csheap.h"



class TABLE
{

  public:

      typedef union
      {
         void * p;
         long    l;
      }dapo;


      typedef struct
      {
         long key;
         dapo data;
      }dast;           //Used in the Import & Export functions.


      typedef struct
      {
         void *up;
         void *le;
         void *ri;
         long key;
         void *dw;
         int  count;
      }  inbl;         //INdex Block

      typedef struct
      {
         void *up;
         void *le;
         void *ri;
         long key;
         dapo data;
      }  dabl;         //DAta Block


 protected:

      HEAP   data;
      csSTR  d_name;

      void  *anchor;
      int    max_lin_search;
      int    nr_layers;
      int    anco;
      long   daco;     // number of data blocks
      long   chle;     // chain length count
      long   nrse;     // number of searches
      void  *current;
      int    is_open;

public:
      long blocks(void)         { return data.blocks(); }

protected:
      int  locate(long l,void * &data,void * &index,int &depth);
      int  loc_near(long l,void *& p);
      void remove_d(void *p)    { data.vfree(p); }
      void remove_i(void *p)    { data.vfree(p); }
      dabl *create_d(long l,dapo d);
      inbl *create_i(long l);
      void inc_ia(void *i)      { if(i) ((inbl *)i)->count++; else anco++; }
      void dec_ia(void *i)      { if(i) ((inbl *)i)->count--; else anco--; }
      int  insert_i(void *ib,void *hi);
      void insert_nl(void *ne);
      int  c_mls(void)          { return max_lin_search; }
      void set_dc(long l)       { daco=l; }
      void inc_dc(void)         { daco++; }
      void dec_dc(void)         { daco--; }
      void reorg_i(void *p);
      void check_hole(void *ip);

      int  zap2(void);


      void connect_h(void *le,void *ri)  { if(ri) ((inbl *)ri)->le=le; if(le) ((inbl *)le)->ri=ri; }
      void connect_ud(void *up,void *dw) { ((inbl *)up)->dw=dw; ((inbl *)dw)->up=up; }
      void connect_ad(void *dw)          { anchor=dw; }
      void connect_uds(void *up,int count,void *dw);
      void connect_uds(void *up,void *dw) { ((inbl *)up)->dw=dw;  connect_uds(up, ((inbl *)up)->count, dw); }



   public:
      TABLE(void);
      virtual ~TABLE(void);

      void init_vars(void);
      void init_defaults(void);


//////////////////////// Work ///////////////////////////////


      int insert(long l,dapo  d,dapo  *& daddr);
      int insert(long l,void *d,void **& daddr);
      int insert(long l,long  d,long  *& daddr);

      int insert(long l,void *d) { void **ad; return insert(l,d,ad); }
      int insert(long l,dapo  d) { dapo  *ad; return insert(l,d,ad); }
      int insert(long l,long  d) { long  *ad; return insert(l,d,ad); }

      int delet(long l);
      int report(csCHAR *filename,int sub=10);
      void report(FILE *fp,int sub=10);

      int search(long l,dapo  &d,dapo *&daddr);
      int search(long l,void * &d,void **& daddr);
      int search(long l,void * &d) { void ** add; return search(l,d,add); }
      int search(long l,long   &d,long *& daddr);
      int search(long l,long   &d) { long * add; return search(l,d,add); }

      int search_lt(long key,long &l,void * &d);
      int search_le(long key,long &l,void * &d);
      int search_gt(long key,long &l,void * &d);
      int search_ge(long key,long &l,void * &d,void ** &addr);
      int next(long &l,void * &d,void ** &addr);
      int prev(long &l,void * &d);
      long number(void) { return daco; }

//////////////////////// Im/Ex-port ////////////////////////////////////

      long export(FILE *fp);
      long import(FILE *fp,long number);


//////////////////////// Setup //////////////////////////////
      int     set_mls(int l) { return max_lin_search=MAX(l,2); }
      void    name(csCHAR *s)  { debug_name(s); }
      void    debug_name(csCHAR *s);

      csCHAR *e_name(void) { return ((csCHAR *)d_name); }
      void    e_name(csCHAR *s) { debug_name(s);  }

//////////////////////// Control ////////////////////////////////////////
      int  empty(void);
      int  zap(void);
      int  open(void);
      int  close(void);

};

#endif
