//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//
// Created: MBN 06/06/89 -- Initial implementation
// Updated: LGO 09/19/89 -- Split into one file per method
// Updated: MBN 10/12/89 -- Changed "current_position" to "curpos"; converted
//                          state from bit set to #define macros for get/set
// Updated: MBN 01/10/89 -- Fixed iteration problem

#include <cool/Generic.h>
#include <cool/Base_Hash.h>

// next -- Increment current position. If INVALID, set to first
// Input:  this*
// Output: TRUE/FALSE

Boolean Hash_Table::next () {
  long prime = this->get_bucket_count ();	// Prime number of buckets
  if (this->curpos == INVALID) {		// If INVALID current position
    if (this->entry_count == 0)			// If no entries in table
      return FALSE;				// Return failure
    for (long i = 0; i < this->get_bucket_count(); i++)	// For each bucket
      if (this->get_count_in_bucket(i) != 0)	// If the bucket has an item
	break;
    this->curpos = SET_BUCKET_NUMBER(i);	// Set bucket number
    this->curpos |= SET_BUCKET_INDEX(0);	// Set index into bucket
    return TRUE;				// Return success
  }
  else if (TRAVERSED(this->curpos))		// If already traversed set
    return FALSE;				// Inidicate failure
  else {
    long hash = BUCKET_NUMBER(this->curpos);	// Get bucket number
    long index = BUCKET_INDEX(this->curpos);	// Get index in bucket
    if (++index < this->get_count_in_bucket(hash)){// If more items in bucket
      this->curpos = SET_BUCKET_NUMBER(hash);	   // Update bucket hash bits
      this->curpos |= SET_BUCKET_INDEX(index);  // Update bucket index bits
      return TRUE;				// And return success
    }
    for (long i = hash+1; i < prime; i++)	// For remaining buckets
      if (this->get_count_in_bucket(i) != 0)	// If the bucket has item
	break;
    if (i == prime) {				// If no more items
      this->curpos = INVALID;			// Invalidate pointer
      return FALSE;				// Return failure
    }
    this->curpos = SET_BUCKET_NUMBER(i);	// Set bucket number
    this->curpos |= SET_BUCKET_INDEX(0);	// Set index into bucket
    return TRUE;				// Return success
  }
}
    



