/* (C) Copyright International Business Machines Corporation 23 January */
/* 1990.  All Rights Reserved. */
/*  */
/* See the file USERAGREEMENT distributed with this software for full */
/* terms and conditions of use. */
/* SCCS Info: @(#)table.h	1.11 3/13/90 */

#ifndef table_included

#define DEEP TRUE
#define SHALLOW FALSE

#define ORDER_TBL 0
#define FIRST_TBL 0

#include "avltree.h"
#include "tblrep.h"

typedef struct tbldes_struct tbldes;


typedef struct {
    tbldes *des;		/* pointer to table representation */
				/*  descriptor. */

    tblrep rep;			/* representation of the table */

} tblinfo;



/* 

A table consists of some generic fields which include a list of keys,
a list of indices, and a flag which determines whether it is ordered.
*/

struct dfd_table_struct {
    counter refcount;		/* how many objects are sharing this table? */
    datarep *tsdr;		/* data representation of table elements */
    counter size;		/* number of elements in the table */
    flag ordered;		/* is it an ordered table? */
    counter tblcount;		/* how many different tblreps? */
    valcell keyset;		/* the set of keys (itself an ordered table) */
    valcell indexset;		/* the set of indices (also a table) */
    tblinfo tbls[ARBSIZE];	/* array of self-describing table */
				/*  representations. */
} /* dfd_table */ ;


typedef int trepnum;

typedef enum {
    Bag_Table,
    Ordered_Table,
    Keyed_Table,
    Indexed_Table

} tblrep_types;

/*

Two parameters are always supplied: 
    dfd_table *table;	-- the table itself
    trepnum infonum;    -- which table rep to operate on

*/

struct tbldes_struct {

    trepnum number;		/* number of this descriptor */
    char *name;			/* name for debugging purposes */
    tblrep_types reptype;	/* bag, ordered, or keyed/indexed? */

    /* ubiquitous table functions */

    status (*alloc)( /* valcell newinfo; */ );
				/* function to allocate a new table. */
				/*  initializes info; fails on */
				/*  depletion.  newinfo is auxiliary */
				/*  information for new'ing this table */
				/*  type; undone by shallow */
				/*  finalization (cf finalize below) */ 

    status (*precopy)( /* dfd_table *sourcetable; */ );
				/* copy the representation-dependent parts */
				/*  the table to result.  may fail with */
				/*  Depletion.  like alloc but gets its */
				/*  new'ing info from the existing table. */

    predef_exception (*insert)( /* valcell val; */ );
				/* inserts a value into the table.  may */
				/*  return Depletion.  if the table is */
				/*  keyed, may return DuplicateKey. */
				/*  if the table is ordered, inserts at */
				/*  the end. */

    void (*uninsert)( /* valcell val; */ );
				/* undoes the effect of the most */
				/* recent insert. */ 

    int (*foreach)( /* int (*func)(); counter *elemcounter; */
		     /* int expectedval; varargs */ );
				/* generic traversal routine.  this routine  */
				/* calls func once for each element of the */
				/* table, using a canonical ordering of the */
				/* elements.  the number of the current */
				/* element is in elemcounter. optional */
				/* additional arguments come afterwards, */
				/* when func is invoked it can use va_arg */
				/* to extract these optional arguments. */

				/* func() is called with the following: */
				/*   dfd_table *table */
				/*   trepnum tblnum */
				/*   valcell val */
				/*   counter elemcount */
				/*   va_list *argv */
				/* where argv "points" to the varargs passed */
				/*  to the foreach function. */

				/* func() returns an int.  if it is not */
				/*  equal to expectedval, the foreach */
				/*  is terminated and the value */
				/*  returned by func() is returned by */
				/*  the foreach.  If func() returns */
				/*  expectedval for each element, */
				/*  expectedval is returned by the foreach */
/* Standard return values for most uses of foreach... use CONT_FOREACH */
/* for expectedval, and have func() return STOP_FOREACH to terminate */
#define CONT_FOREACH 0
#define STOP_FOREACH -1

    status (*initget)( /* position *pos; int initpos; */ );
				/* starts a get operation.  the initpos */
				/*  is used only by ordered tables, which */
				/*  can start a get at any position in the */
				/*  table.  Fails on depletion. */

    predef_exception (*get)( /* position *pos; valcell *val; */ );
				/* returns the table element pointed to by */
				/*  pos in val; updates pos to point to the */
				/*  next element.  if no more elements, */
				/*  returns NotFound. if no more storage, */
				/*  returns Depletion */

    void (*remove)( /* trepnum seltblnum; position *pos; valcell val; */ );
				/* removes the element selected by the last */
				/*  get or find operation.  updates position */
				/*  if the table is the one being selected */
				/*  in a get- or find-loop. */

    void (*endget)( /* position *pos; */ );
				/* ends a get by finalizing whatever state */
				/*  information is stored in pos. */

    /* table versions of the standard recursiv functions */

    void (*finalize)( /* flag depth; finalize_op f_op; schedblock *sched */ );
				/* finalize the table.  if depth is DEEP, */
				/*  finalize the valcells; otherwise, if */
				/*  SHALLOW, just do the table itself. */
				/* f_op is simply passed along to the */
				/*  finalize routine for the individual */
				/*  valcells when depth is DEEP. */

    status (*equal)( /* dfd_table *comptable; */ );
				/* returns SUCCESS if the two tables are */
				/*  equal.  tables are guaranteed to */
				/*  have the same nonzero size */

    comparison (*comparekeys)( /* dfd_table *comptable; */ );
				/* compare tables as keys. tables are */
				/* guaranteed to have the same nonzero size */

    /*************** operations for keyed/indexed tables *****************/

    status (*find)( /* object **lookupvals; valcell *val; */ );
				/* finds a single instance of the element */
				/*  that matches the lookupvals.  returns */
				/*  FAILURE if none.  returns SUCCESS with */
				/*  the value stored in *val if found. */

    /**************** operations for indexed tables *****************/

    status (*initfind)( /* position *pos; object **lookupvals; */ );
				/* initializes a keyed or indexed lookup */
				/*  on the table, using the objects in */
				/*  lookupvals to do the lookups. */
				/*  initializes pos, saves the lookupvals. */
				/*  Fails on storage depletion. */

    predef_exception (*findnext)( /* position *pos; valcell *val; */ );
				/* sets val to the next value matching the */
				/*  lookupvals set in the initfind. */
				/*  returns NotFound if none found, */
				/*  Depletion on storage depletion. */

    void (*endfind)( /* position *pos; */ );
				/* ends a find by finalizing any state */
				/*  stored in pos. */

    /**************** operations for ordered tables ****************/

    predef_exception (*insert_at)( /* valcell val; int intpos; */ );
				/* inserts the value at the given position */
				/*  in the table.  may return Depletion, */
				/*  in which case table is left unchanged. */
				/*  calling function is responsible for */
				/*  checking for RangeError prior to calling */
				/*  insert_at. */

    void (*remove_at)( /* valcell *val; int intpos; */ );
				/* removes the element at the given position */
				/*  in the table and puts the value in val. */

    void (*lookup_at)( /* valcell *val; int intpos; */ );
				/* returns the element at the given position */
				/*  in the table in val. does not change the */
				/*  table. */

    predef_exception (*merge_at)( /* dfd_table *mergetable; int intpos; */ );
				/* inserts the mergetable at position intpos */
				/*  in the table.  Can return */
				/*  Depletion. */

    void (*unmerge_at)( /* valcell val; int intpos; int count; */ );
				/* removes given number of elements */
				/* inserted by a merge_at or insert_at */
				/* operation */

    int (*position_of)( /* position pos; */ );
				/* returns the position of the currently */
				/*  get'd element. */

    predef_exception (*conc_at)( /* dfd_table *conctable;
				    dfd_table **result; */ );
				/* concatenates table and conctable, */
				/*  placing the result in result. */
				/*  may return Depletion or */
				/*  DuplicateKey. */ 

} /* tbldes */ ;



#endif
#define table_included
