// $Id: CompHash.h,v 1.10 2002/10/11 02:20:15 leres Exp $
//
// Copyright (c) 1995, 1997, 1998, 1999, 2001, 2002
//      The Regents of the University of California.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that: (1) source code distributions
// retain the above copyright notice and this paragraph in its entirety, (2)
// distributions including binary code include the above copyright notice and
// this paragraph in its entirety in the documentation or other materials
// provided with the distribution, and (3) all advertising materials mentioning
// features or use of this software display the following acknowledgement:
// ``This product includes software developed by the University of California,
// Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
// the University nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#ifndef comphash_h
#define comphash_h

#include "Hash.h"
#include "Type.h"

class ListVal;

class CompositeHash {
public:
	CompositeHash(TypeList* composite_type);
	~CompositeHash();

	// Compute the hash corresponding to the given index val,
	// or 0 if it fails to typecheck.
	HashKey* ComputeHash(const Val* v, int type_check) const;

	// Given a hash key, recover the values used to create it.
	ListVal* RecoverVals(const HashKey* k) const;

protected:
	HashKey* ComputeSingletonHash(const Val* v, int type_check) const;

	// Rounds the given pointer up to the nearest multiple of the
	// given size, if not already a multiple.
	const char* Align(const char* ptr, unsigned int size) const;

	// Rounds the given pointer up to the nearest multiple of the
	// given size, padding the skipped region with 0 bytes.
	char* AlignAndPad(char* ptr, unsigned int size) const;

	// Returns offset+size rounded up so it can correctly align data
	// of the given size.
	int SizeAlign(int offset, unsigned int size) const;

	// Compute the size of the composite key.  If v is non-nil then
	// the value is computed for the particular list of values.
	// Returns 0 if the key has an indeterminant size (if v not given),
	// or if v doesn't match the index type (if given).
	int ComputeKeySize(const Val* v = 0, int type_check = 1) const;

	TypeList* type;
	char* key;	// space for composite key
	int size;
	int is_singleton;	// if just one type in index
	InternalTypeTag singleton_tag;
};

#endif
