//-----------------------------------------------------------------------------
// 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:
//	 rsvcStrHash: rsvc 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
//
//
//
//
#ifndef _RSVC_HASH_H
#define _RSVC_HASH_H

#include <stdio.h>
#include <string.h>
#include <rsvcHashable.h>
#include <rsvcHSlist.h>


//======================================================================
//	class rsvcHash
//		collection of buckets indexed by hashed values
//======================================================================
class rsvcHashIterator;

class rsvcHash
{
public:
  // constructor

  // construct a hash table with estimate max entry and load fator
  rsvcHash (unsigned int estimatemax, unsigned int lf = 5);

  // destructor
  virtual ~rsvcHash (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 (rsvcHashable* ele);

  // dump all hash distribution
  void          asciiDump (FILE* fd = stdout);

  // return a reference to a particular bucket according to the key
  rsvcHSlist&    bucketRef (rsvcHashable* ele);

  // return a reference to a particular bucket according to a hash value
  rsvcHSlist&    bucketRef (unsigned int hashcode);       

  // return a pointer to an array of linked list
  void bucketList          (rsvcHSlist* &list, unsigned int& size);

protected:
  friend class rsvcHashIterator;

  // the actual table itself is a vector of buckets
  unsigned int          tablesize;
  unsigned int          lf;
  // current index of prime number table
  int                   primeindex;
  // buckets
  rsvcHSlist*           buckets;
  
  // convert key into unsigned integer value in range
  unsigned int          hash(rsvcHashable* ele) const;

  // expand the hash table size to next prime number when
  // load factor reaches the preset value
  void                  rehash (void);

private:

#if defined (RSVC_USE_THREAD) && defined (_REENTRANT)
  cpMutex               lock_;
#endif
};

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

  // iterator protocol 
  int             init       (void);
  rsvcHashable*   operator ()(void);
  int             operator ! (void);
  int             operator ++(void);
  
  // change value at this position
  // make sure the hash key are the same inside the value
  void            operator = (rsvcHashable* value);

  // new operations
  // remove current item pointed by this cursor
  void            removeCurrent (void);

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

#if defined (RSVC_USE_THREAD) && defined (_REENTRANT)
  cpMutex                    lock_;
#endif
};
#endif
