//-----------------------------------------------------------------------------
// 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.
//
//-----------------------------------------------------------------------------
// 
// Description:
//	 cdevIntHash: cdev hash table keyed by an integer
//                    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
//
// Author: Danjin Wu (Modified from cdevStrHash class)
//
// Revision History:
//   cdevIntHash.h,v
// Revision 1.2  1996/08/26  21:12:35  akers
// Added getData method to iterator
//
// Revision 1.1  1995/08/21  15:45:36  danjin
// integer hash table
//
//
//     
#ifndef _CDEV_INT_HASH_H
#define _CDEV_INT_HASH_H

#include <cdevSlist.h>

//======================================================================
//  One simple integer hash function
//           This hash function is used in cdevData.
//           It returns integer value between 0 to table size
//======================================================================

typedef int cdevIntKeyItem;
typedef void* cdevHashItem;
//======================================================================
//	class cdevIntHash
//		collection of buckets indexed by hashed values
//======================================================================
class cdevIntHashIterator;

class CDEV_CLASS_SPEC cdevIntHash
{
public:
  // constructor, construct a table with entry max 
  cdevIntHash (unsigned int max);
  // destructor
  virtual ~cdevIntHash (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 (cdevIntKeyItem key, cdevHashItem ele);

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

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

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

 protected:
  friend class cdevIntHashIterator;

  // 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 cdevIntKeyItem key) const;

};

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

  // iterator protocol 
  int             init       (void);
  cdevHashItem    operator ()(void);
  cdevHashItem    getData    (void);       
  int             operator ! (void);
  int             operator ++(void);
  void            operator = (cdevHashItem value);
  
protected:
  cdevIntHash&    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
