/*static char *SCCSID = "@(#)addhash.c	6.2 91/04/04";*/

#define	 INCL_DOSINFOSEG
#include <os2.h>
#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "volume.h"
#include "storage.h"
#include "tables.h"
#include "pb_ifs.h"
#include "pbmacros.h"
#include "superb.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"
#include "pr_CACHE.h"
#include "pr_debug.h"
#include "mmph.h"


/*
 *** AddHash -- Add a buffer to the hash table
 *
 *	HISTORY
 *	    21-Sep-1988 09:23:54 by Bill McJohn [t-billm]
 *				brought up to date with 9/15/88 assembly code
 */

void
AddHash(pbuf)
PBUFNODE pbuf;	/*  ptr to buffer to set up    */
{
	PBUFNODE pbufHashHead;
	USHORT h;

	MMPHPreAddHash();     /* performance hook (3301h) */

   _disable ();     //#114986

	h = HASHVAL(pbuf->lsnSec);

#ifdef DEBUG
	/* check that there are vol bits turned on */
	if ((pbuf->lsnSec & ~SECMASK) == 0) {
		dprintf ("AddHash: no vol bits, pbuf->lsnSec=0x%lx\n",
			 pbuf->lsnSec);
		Int3 ();
	}

	/*
	 * See if there already is a buffer in the hash table claiming to
	 * be the same LSN.
	 */
	if ((pbuf->lsnSec != LSN_BOGUS) &&
	    (HashFind (pbuf->lsnSec) != NULL)) {
		dprintf ("AddHash: attempting to redundantly add buffer\n");
		Int3 ();
	}
#endif

	/*  Set the buffer's hash table address pointer  */
	pbuf-> ppbufHTA = apbufHashTable + h;

	/*  Add to hash table  */
	pbufHashHead = apbufHashTable[h];
	if (pbufHashHead == NULL) {
		/*  the hash list is empty.  pbuf's hash
		 *  chain pointers are both set to pbuf
		 *  (a circular, doubly-linked chain with one
		 *  element)
		 */

		pbuf->dcbpHash.pbufFwd = pbuf;
		pbuf->dcbpHash.pbufBak = pbuf;

	}
	else {
#ifdef DEBUG
	    /*
	     * The hash bucket is not empty so let's check to see
	     * if the lsn already resides on the chain.
	     */
	    {
		PBUFNODE pbufWalker;

		pbufWalker = pbufHashHead;
		do {
		    if ((pbufWalker->lsnSec == pbuf->lsnSec) &&
			(pbufWalker->lsnSec != LSN_BOGUS)) {

			dprintf ("AddHash: add buf that's already on chain\n");
			dprintf ("pbuf to add=0x%x, lsn=0x%lx\n",
				 pbuf, pbuf->lsnSec);
			dprintf ("pbuf already on=0x%x, lsn=0x%lx\n",
				 pbufWalker, pbufWalker->lsnSec);
			dprintf ("hash bucket=%d\n", h);
			Int3 ();
		    }

		    /*
		     * Make sure that the current buf is on the right hash
		     * chain.
		     */
		    if (pbufWalker->lsnSec != LSN_BOGUS &&
			HASHVAL (pbufWalker->lsnSec) != h) {
			dprintf ("AddHash: buffer in wrong bucket\n");
			dprintf ("pbufWalker=0x%x, HASHVAL (0x%lx)=%d, h=%d\n",
				  pbufWalker, HASHVAL (pbufWalker), h);
			Int3 ();
		    }
		    pbufWalker = pbufWalker->dcbpHash.pbufFwd;
		} while (pbufWalker != pbufHashHead);
	    }
#endif
		/*  pbuf is inserted into the hash chain after
		 *  the first buffer node in the hash
		 *  chain.
		 *
		 *  This seems kind of odd--the former head becomes the
		 *  tail once the new buffer is made the head.
		 */
		DCADDF (pbuf, dcbpHash, *pbufHashHead);
	}

	/*  The new guy becomes the head of the hash chain.  */
	apbufHashTable[h] = pbuf;

#ifdef DEBUG
	ChkHashChain ();
#endif

	/*  The buffer header is now ready.  */
 _enable ();        //#114986

MMPHPostAddHash();     /* performance hook (3381h) */

}

