//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
// CEBAF Data Acquisition Group, 12000 Jefferson Ave., Newport News, VA 23606
// Email: coda@cebaf.gov  Tel: (804) 249-7101  Fax: (804) 249-7363
//-----------------------------------------------------------------------------
// 
// Description:
//	 cdevStrHash: cdev hash table keyed by a variable length string
//                    Open Hash with buckets implemented by single linked lists
//    
//              Note: void *s are stored inside the table. This class
//                    will not manage these pointers. Callers have to
//                    manage these pointers
// 
//              Note: this is unsafe C++ practice. Use at your own risk
//              
//            Reason: It is so difficult to use a template class inside
//                    a shared library. (Cfront based C++ compiler cannot
//                    instantiate a template class during compilation time
//	
// Author:  Jie Chen
//       CEBAF Data Acquisition Group
//
// Revision History:
//   cdevStrHash.h,v
// Revision 1.3  1996/08/26  21:12:38  akers
// Added getData method to iterator
//
// Revision 1.2  1995/07/05  18:38:30  chen
// add simple str hash function
//
// Revision 1.1  1995/06/30  15:08:42  chen
// string hash table
//
//
#ifndef _CDEV_STR_HASH_H
#define _CDEV_STR_HASH_H

#include <cdevSlist.h>

//======================================================================
//  One simple string hash function
//           This hash function is used in cdevDevice and caChannel.
//           It returns integer value between 0 to MAX_INTEGER_VALUE
//           and this value will be moded with the size of the hash
//           table. 
//           It may be changed to a different hash function in
//           release 1.1
//======================================================================
extern CDEVAPI unsigned int cdevStrHashFunc (char *str);

typedef char* cdevKeyItem;
typedef void* cdevHashItem;

//======================================================================
//	class cdevStrHash
//		collection of buckets indexed by hashed values
//======================================================================
class cdevStrHashIterator;

class CDEV_CLASS_SPEC cdevStrHash
{
public:
  // constructor
  // construct a table with entry max and hash function *f
  // hash function return any integer from 0 to MAX_INT_VALUE
  cdevStrHash (unsigned int max, unsigned int (*f)(cdevKeyItem));
  // destructor
  virtual ~cdevStrHash (void);

  // operations

  // is the table empty: return 1: yes. return 0: no
  virtual int   isEmpty();

  // clear the elements of the set
  virtual void  deleteAllValues();

  // add an element to the collection
  virtual void  add (cdevKeyItem key, cdevHashItem ele);

  // test to see whether this hash table includes one particular element
  virtual int   find (cdevKeyItem key, cdevHashItem ele) const;

  // remove an element. return 0: ele is not inside table. return 1: success
  virtual int   remove (cdevKeyItem key, cdevHashItem ele);

  // return a reference to a particular bucket according to the key
  cdevSlist&  bucketRef (cdevKeyItem key);

 protected:
  friend class cdevStrHashIterator;

  // the actual table itself is a vector of buckets
  const unsigned int    tablesize;
  cdevSlist*            buckets;

  // convert key into unsigned integer value in range
  unsigned int          hash(const cdevKeyItem& key) const;

 private:
  unsigned int          (*hashCode_)(cdevKeyItem);
};

//======================================================================
//	class cdevStrHashIterator
//		iterator protocol for hash tables
//======================================================================
class CDEV_CLASS_SPEC cdevStrHashIterator
{
public:
  // constructor and destructor
  cdevStrHashIterator  (cdevStrHash& v);
  ~cdevStrHashIterator (void);

  // iterator protocol 
  int             init       (void);
  cdevHashItem    operator ()(void);
  cdevHashItem    getData    (void);       
  int             operator ! (void);
  int             operator ++(void);
  void            operator = (cdevHashItem value);

protected:
  cdevStrHash&    base;
  unsigned int    currentIndex;
  // Single iterator within a bucket
  cdevSlistIterator*         itr;
  // getNextIterator used to set internal iterator pointer
  // return 1: got it. return 0: no more iterator
  int             getNextIterator (void);
};
#endif
