#include "hash.h"
#include <stdio.h>
#include <assert.h>

#define D	if(0)

template<class K, class V>
BOOL readcache<K,V>::check(C K& k) C
{
 assert(n > 0);
 C int hv = (*hashfunction)(k, n);
 if(tbl[hv].filled())	{
	if(tbl[hv].key() == k)
		return TRUE;
	else if(!tbl[(hv+1)%n].filled())
		return FALSE;
	else if(tbl[(hv+1)%n].key() == k)
		return TRUE;
	}
 return FALSE;
}

template<class K, class V>
C V& readcache<K,V>::get(C K& k)
{
 assert(n > 0);
 int hv = (*hashfunction)(k, n);
 if(tbl[hv].filled())	{
	if(tbl[hv].key() == k)	{
		hits++;
		return tbl[hv].value();
		}
	else if(!tbl[(hv+1)%n].filled())
		hv = (hv+1)%n;
	else if(tbl[(hv+1)%n].key() == k)	{
		hits++;
		return tbl[(hv+1)%n].value();
		}
	}
 misses++;
 tbl[hv].set(k, (*getdata)(k, c, nc));
 return tbl[hv].value();
}

template<class K, class V>
int readcache<K,V>::count() C
{
 int c = 0;
 int i;
 for(i=0;i<n;i++)
	if(tbl[i].filled())
		c++;
 return c;
}

template <class K, class V>
readcache<K,V>::readcache(int nn, int(*hashf)(C K&, int),
								V (*getd)(C K&, void *, int),
								void *cc, int ncc)
: hashfunction(hashf), n(nn), getdata(getd), c(cc), nc(ncc), hits(0), misses(0)
{
 assert(getdata);
 assert(hashf);
 tbl = new hashitem<K,V> [ nn];
 if(!tbl)
	n = 0;
}


template <class K, class V>
void readcache<K,V>::flush()
{
 int i;
 for(i=0;i<n;i++)
	tbl[i].unset();
 hits = misses = 0;
}
