#ifndef _T_JHashRecord
#define _T_JHashRecord

/******************************************************************************
 JHashRecord.tmpl

	JHashRecord encapsulates the per-entry information needed by JHashTable.
	JHashTable itself only requires the state information and treats the rest
	of the data (the template parameter) opaquely.  Only client code need
	understand the properties of the data and provide hash values and key
	comparisons.  Care must be taken to ensure that the hash value is the
	correct one for the given key.

	It is perhaps unusual that the hash value would be stored in the table
	itself, which uses considerable extra space in a large table.  For static
	tables it is unnecessary, since the location itself is the hash value.  To
	implement dynamic resizing, however, the location is essentially only a
	partial hash value (for JHashTable, the hash value modulo the tablesize),
	and the complete hash value must be cached to determine the new location of
	a record in a larger table.

	BASE CLASS = <NONE>

	Copyright © 1997 by Dustin Laurence.  All rights reserved.

	Base code generated by Codemill v0.1.0

 *****************************************************************************/

//Class Header
#include <JHashRecord.h>

#include <stddef.h> // For offsetof
#include <iostream.h>

#include <jAssert.h>

/******************************************************************************
 Constructor

 *****************************************************************************/

template <class V>
JHashRecord<V>::JHashRecord()
	:
	itsState(JHashRecordT::kEmpty),
	itsHashValue(0)
{
}

template <class V>
JHashRecord<V>::JHashRecord
	(
	JHashValue hash,
	const V&   value
	)
	:
	itsState(JHashRecordT::kFull),
	itsHashValue(hash)
{
	itsValue = value;
}

/******************************************************************************
 Destructor

 *****************************************************************************/

template <class V>
JHashRecord<V>::~JHashRecord()
{
}

/******************************************************************************
 Set

	Some fields cannot be set individually to make it harder to set the value
	incorrectly (such as accidentally marking it empty or giving it a hash
	value which does not match the value).

 *****************************************************************************/

template <class V>
void
JHashRecord<V>::Set
	(
	const JHashValue hash,
	const V&         value
	)
{
	itsState = JHashRecordT::kFull;
	itsHashValue = hash;
	itsValue = value;
}

template <class V>
void
JHashRecord<V>::Set
	(
	const V& value
	)
{
	assert( IsFull() );
	itsValue = value;
}


/******************************************************************************
 PrintLayout

	Prints the layout of a JHashRecord in memory.  Useful for optimizing the
	memory usage on a particular architecture, which can be important considering
	how many records can potentially be stored.

	This method ought to be static but isn't to accomodate how certain compilers
	implement sizeof() and/or offsetof().  It isn't very hard to use the default
	constructor to create a throwaway object anyway.

 *****************************************************************************/

template <class V>
void
JHashRecord<V>::PrintLayout()
{
	cout << "Memory layout of JHashRecord:" << endl;

	cout << "\n       itsState = " << offsetof(JHashRecord, itsState) << "-"
	     << offsetof(JHashRecord, itsState)+sizeof(JHashRecord::itsState)-1 << endl;
	cout << "   itsHashValue = " << offsetof(JHashRecord, itsHashValue) << "-"
	     << offsetof(JHashRecord, itsHashValue)+sizeof(JHashRecord::itsHashValue)-1 << endl;
	cout << "       itsValue = " << offsetof(JHashRecord, itsValue) << "-"
	     << offsetof(JHashRecord, itsValue)+sizeof(JHashRecord::itsValue)-1 << endl;

	cout << "\n       overhead = "
	     << offsetof(JHashRecord, itsValue)+sizeof(JHashRecord::itsValue) << "-"
	     << sizeof(JHashRecord)-1 << "\n" << endl;
}

#endif

// Instantiate the template for the specified type.

#if defined JTemplateType && ! defined JOnlyWantTemplateDefinition
	#define JTemplateName JHashRecord
	#include <instantiate_template.h>
	#undef JTemplateName
#endif
