/*
** Copyright 1998 - 2000 Double Precision, Inc.
** See COPYING for distribution information.
*/

#ifndef	duphash_h
#define	duphash_h

#include	"msghash.h"


/* Dup detection calculation */

#define	MAXMSGIDSIZE	128		/* Max size of message ID */

/* A single hash info */

struct duphashinfo {
	struct duphashinfo *next,	/* Link list of unused duphashinfos,
					** or of all hashes in the same bucket
					*/
				*prev;	/* Double link list of hashes on same
					** bucket
					*/

	MD5_DIGEST	md5;		/* The hash value */
	struct	duphashmsginfo *firstmsg, *lastmsg;
					/* All messages with the same hash */
	unsigned nmsgs;			/* # of messages with the same hash */
	unsigned ndupmsgs;		/* # of messages here that were dupes
					** generated by submit due to too
					** many recipients
					*/
	} ;

struct duphashmsginfo {
	struct duphashmsginfo *next, *prev;	/* link list of msgs with same hash */
	struct duphashinfo *hash;	/* My hash */
	char	cancelled;		/* This message has been cancelled */
	char	dupmsg;			/* This is a second copy of a msg
					** that was split into multiple msgs
					** by submit
					*/
	char	msgid[MAXMSGIDSIZE];
	} ;

struct duphash {
	unsigned duphashbufsize;
	unsigned duplevel;
	struct duphashmsginfo		*msgsbuf;
	struct duphashinfo	*hashesbuf;

	struct duphashinfo	*hashbuckets[256];	/* Hash buckets */

	unsigned head, tail;	/* ptrs into duphashmsginfo circular buf */
	struct duphashinfo *freelist;	/* unused duphashinfos */

	} ;

void duphash_init(struct duphash *,
		unsigned,		/* Size of hash buffer */
		unsigned);
			/* # of dup messages before they are cancelled */

int duphash_check(struct duphash *,
		MD5_DIGEST *,
		const char *,	/* msgid */
		int,		/* isdupe */
		void (*)(const char *));	/* cancel function */
#endif
