/* FILE pladt.c     Wed Jul  6 16:49:47 PDT 1988    w.klas      */
/* 	$Header: pladt.c,v 1.2 89/02/02 16:20:56 aoki Exp $*/
/* TabWidth = 4 */

#include "c.h"

#include "pladt.h"
#include "pldebug.h"

/************************************************************************/
/* The structure of the shared memory segment	    	    	    	*/
/************************************************************************/

/*
A ----- Header Information ------------------  B-A = SizeLockTableHeader --
    criticalSectionSemaphoreId (int)	   
    generalSemaphoreId (int)
    semaphore[0] (bool)
    ....
    semaphore[NMAXSEM-1] (bool)
    lockTableSet  --->	numberOfTables (int)
    	    	    	tableInfo[0]	 --->	startTableFrame (Offset)[B-A]
    	    	    	    	    	    	startHashFrame (Offset)[D-A]
    	    	    	    	    	    	numTableEntries (int)
    	    	    	    	    	    	maxNumTableEntries (int)
    	    	    	...
    	    	    	tableInfo[NMAXLTABLE-1] --> startTableFrame (Offset)
    	    	    	    	    	    	    startHashFrame (Offset)
    	    	    	    	    	    	    numTableEntries (int)
    	    	    	    	    	    	    maxNumTableEntries (int)
    startLockTableFrameSection (Offset relative to A) [B - A]
    startLockTableHashSection (Offset relative to A) [D - A]
a   endOfSharedLockTable (Offset relative to A) [Z - A]
B -----First Lock Table Frame --------------------------------------------   
    lockTableType (LockTable)
    lockTableMode (LockTableMode)
    lockTableNameData (LockTableNameData)
b1  currentTableEntries (int)
    tableEntry[0] -->	entryData -->	lockMode
    	    	    	    	    	lockSrcRel
    	    	    	    	    	lockSrcPage
    	    	    	    	    	lockSrcLine
    	    	    	    	    	xid
    	    	    	    	    	lockType
    	    	    	    	    	semIndex
    	    	    	free
    .....
    tableEntry[i] -->	entryData -->	lockMode
    	    	    	    	    	lockSrcRel
    	    	    	    	    	lockSrcPage
    	    	    	    	    	lockSrcLine
    	    	    	    	    	xid
    	    	    	    	    	lockType
    	    	    	    	    	semIndex
    	    	    	free
b   .....
C ----- Second Lock Table Frame ------------------------------------------   
    .....
D -----First Hash Table Region (associated with first Lock Table Frame) ---   
    startXidHash (Offset relative to D)	
    startXidFreeSpace (offset relative to D1)
    endXidFreeSpace (offset relative to D1)
    numXidEntries (int)
    maxNumXidEntries (int)  
    startOidHash (Offset relative to D)	 
    startOidFreeSpace (Offset relative to D2)
    endOidFreeSpace (Offset relative to D2)
    numOidEntries (int)
    maxNumOidEntries (int)
    entryXidBucket[0] (Offset relative to D1)
    ...	    	    	    	    	    	    	(limited number of
    ...	    	    	    	    	    	    	     transactions!)
    entryXidBucket[NMAXXIDHASH-1] (Offset relative to D1) 
    entryOidBucket[0] (Offset relative to D2) 
    ...
    entryOidBucket[i] (Offset relative to D2)
    ...
    ...
    (fixed length for a specific segment, but no maximal number of buckets)
    ...
d1  
D1  ------- Start Xid Hash section for this region   --------------------
    EntryXidData    -->	entryIndex
    	    	    	xid
    	    	    	free
    	    	    	next (Offset relative to D1)
     .... (dynamically growing down)
d2   
D2  ------- Start Oid Hash section for this region  ----------------------
    EntryOidData    -->	entryIndex
    	    	    	lockSrcRel
    	    	    	lockSrcPage
    	    	    	lockSrcLine
    	    	    	free
    	    	    	next (Offset relative to D2)
     .... (dynamically growing down)
e
E ----- Second Hash Table Region (associated with second Lock Table Frame) --   
    .....
    .....

Z ---------- End of shared segemnt -------------------------------------------  
*/  

/************************************************************************/
/* LtComputeOffsets(tableSizeOut)   - returns the table structure   	*/
/*  	    	    	    	      offsets and the size of the table	*/
/* Parameter:	INPUT	none	    	    	    	    	    	*/
/*  	    	OUTPUT	tableSizeOut	size required for lock table  	*/
/************************************************************************/
TableOffsets *
LtComputeOffsets(tableSizeOut)
int *tableSizeOut;  	    	/* the computed size of the lock table	*/
{
    TableOffsets    *toP;
    int	    a,b1,b,c,d,d0,d1,d2,e;  	    /* offsets e.g. a = B - A	*/
    int	    A,B,C,D,D1,D2,E,Z;	/* addresses relative to baseaddress A	*/
    int	    TotalSize;

    A = 0;
    a = SizeLockTableHeader;	    /* offset to first lock table frame	*/
    B = A + a;	    	    	/* Address of first Lock Table frame	*/
    
    b1 = SizeLockTableFrameHeader;
    b = b1 + (NumberOfLockTableEntries * SizeLockTableEntry);
    C = B + b;	    	    	/* Address of second Lock Table frame	*/
/*  Ci = B + (i-1) * b;*/   	/*    Addr. for the ith Lock Table frame*/
    
    d0 = (NMAXLTABLE * b);  	/* offset   	    	    	    	*/
    D = B + d0;     	    	/* Address of first hash table region	*/
    
    d1 = SizeLockHashFrameWithoutOidBuckets +        
    	(NumberOfEntryOidBuckets * SizeOfOneEntryOidBucket);
    D1 = D + d1;    	    	/* Address of Xid hash Data 	    	*/
    
    d2 = (NumberOfEntryXidData * SizeOfOneEntryXidData);
    D2 = D1 + d2;   	    	/* Address of OID hash data 	    	*/
    
    e = (NumberOfEntryOidData * SizeOfOneEntryOidData);
    E = D2 + e;	    	    	/* Address of second hash table region	*/ 
    
    d = d1 + d2 + e;	    	/* offset of a hash table region    	*/
    
/*  Ei = D + (i-1) * d;         /* Address for the ith hash table region*/
    Z = D + (NMAXLTABLE * d);	/* Address of the end of the segment 	*/
    
    TotalSize = Z - A;
    *tableSizeOut = TotalSize;
    
    toP = new(TableOffsets);
    toP->startSegment = 0;
    toP->offsetToFirstLockTableFrame  = a;  /* relative to start of segment */
    toP->offsetOfALockTableFrame      = b;  /* offset of a lock table frame */
    toP->offsetToFirstHashTableRegion = a + d0; /* relative to start of seg.*/
    toP->offsetToXidHashData          = d1; /* relative to start of hash    */
    	    	    	    	    	    /*   table region  	    	    */
    toP->offsetToOidHashData    = d1 + d2;  /* relative to start of hash    */
    	    	    	    	    	    /*   table region 	    	    */
    toP->offsetOfAHashTableRegion     = d;  /* offset of a hash table region*/
    toP->offsetToEndOfSegment         = Z-A;/* relative to start of segment */

    if (DebugStatisticIsOn()) {
    	printf("\nThe lock table structure has been computed");
    	printf("\nin respect of its start address:\n");
    	printf("\nWith %d NumberOfLockTableEntries", NumberOfLockTableEntries);
    	printf("\n     %d NumberOfEntryOidBuckets", NumberOfEntryOidBuckets);
    	printf("\n     %d NumberOfEntryOidData", NumberOfEntryOidData);
    	printf("\n     %d NumberOfEntryXidData", NumberOfEntryXidData);
    	printf("\n and %d maximal number of lock tables", NMAXLTABLE);
    	printf("\n--------------------------------------------------");
    	printf("\nA (start table segment)           ... %d", A);
    	printf("\nB (start first lock table frame)  ... %d", B);
    	printf("\nC (start second lock table frame) ... %d", C);
    	printf("\n  ...  (ith lock table frame)           ");
    	printf("\nD (start first hash table region) ... %d", D);
    	printf("\n  D1 (start XID hash data)	          %d", D1);
    	printf("\n  D2 (start OID hash data)	          %d", D2);
    	printf("\nE (start second hash table region)... %d", E);
    	printf("\n  ...  (ith hash table region)          ");
    	printf("\nZ (end of shared segment)         ... %d", Z);
    	printf("\n-------------------------------------------------");
    	printf("\nTotal size of shared segment: %d bytes", TotalSize);
    	printf("\n");
    }
    return(toP);
}   /*end LtComputeOffsets */





/***********************************************************************/
/************      Access to the lock table header     *****************/
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/

/************************************************************************/
/*  semaphore numbers range between 0 and NMAXSEM - 1	    	    	*/
/************************************************************************/

/************************************************************************/
/*  LtGetSemaphoreId	    - returns the general semaphore identifier	    */
/************************************************************************/
SemId
LtGetSemaphoreId(tableP)
LockTableMemory	*tableP;
{
    return(tableP->generalSemaphoreId);
}


/************************************************************************/
/*  LtSemaphoreIsFree	- returns true, iff semaphore semNum 	    	*/
/*  	    	    	     is unused	    	    	    	    	*/
/************************************************************************/
bool
LtSemaphoreIsFree(tableP, semNum)
LockTableMemory	*tableP;
int semNum;
{   
    return(tableP->semIsFree[semNum]);
/*  if (tableP->semIsFree[semNum] == true) */
/*  	return(true);	    */	/* semaphore unused */
/*  return(false);*/	
}

/************************************************************************/
/*  LtSetSemaphoreUsed	- semaphore semNum is set to be used	    	*/
/************************************************************************/
void
LtSetSemaphoreUsed(tableP, semNum)
LockTableMemory	*tableP;
int semNum;
{
    tableP->semIsFree[semNum] = false;
    return;
}

/************************************************************************/
/*  LtSetSemaphoreUnused    - semaphore semNum is set to be unused  	    */
/************************************************************************/
void
LtSetSemaphoreUnused(tableP, semNum)
LockTableMemory	*tableP;
int semNum;
{
    tableP->semIsFree[semNum] = true;
    return;
}


/************************************************************************/
/*  LtSemaphoreInit - initialize all semaphores to be unused  	    	*/
/************************************************************************/
void
LtSemaphoreInit(tableP)
LockTableMemory	*tableP;
{
    int	i;
    
    for (i=0; i< NMAXSEM; i++) 
    	LtSetSemaphoreUnused(tableP, i);
}
    
/************************************************************************/
/*  LtGetFreeSemaphore	- returns a semaphore number >= 0 which	    	*/
/*  	    	    	  is free   	     	    	    	    	*/
/*  	    	    	- returns a negative integer, iff no 	    	*/
/*  	    	    	  free semaphore is available	    	    	*/
/*  optimize search!	    	    	    	    	    	    	*/
/************************************************************************/
int
LtGetFreeSemaphore(tableP)
LockTableMemory	*tableP;
{   int	i;

    i = 0;
    while (i < NMAXSEM) {
        if (LtSemaphoreIsFree(tableP, i)) {
    	return(i);
        }
        i++;
    }
    return(-1); /* no free semaphore available */
}





/************************************************************************/
/*  LtGetNumberOfTables	- returns the current number of lock	    	*/
/*  	    	  tables    	     	    	    	    	    	*/
/************************************************************************/
int
LtGetNumberOfTables(tableP)
LockTableMemory	*tableP;
{
    return(tableP->lockTableSet.numberOfTables);
}

/************************************************************************/
/*  LtSetNumberOfTables	- sets the current number of lock   	    	*/
/*  	    	  tables    	     	    	    	    	    	*/
/************************************************************************/
void
LtSetNumberOfTables(tableP, num)
LockTableMemory	*tableP;
int 	num;
{
    tableP->lockTableSet.numberOfTables = num;
    return;
}

/************************************************************************/
/*  LtIncNumberOfTables	- increments the current number of lock	    	*/
/*  	    	  tables and returns it	     	    	    	    	*/
/*  	    	- returns -1, iff too many tables   	    	    	*/
/************************************************************************/
int
LtIncNumberOfTables(tableP, num)
LockTableMemory	*tableP;
int 	num;
{
    int	newNum;
    
    newNum = tableP->lockTableSet.numberOfTables + num;
    if (newNum > NMAXLTABLE)	{
    	Note("LtIncNumberOfTables: too many lock tables",DEBERR);
    	return(-1);
    }
    tableP->lockTableSet.numberOfTables = newNum;
    return(newNum);
}



/************************************************************************/
/*  LtDecNumberOfTables	- decrements the current number of lock	    	*/
/*  	    	    	    tables and returns it   	    	    	*/
/*  	    	    	- returns -1, iff no tables defined 	    	*/
/************************************************************************/
int
LtDecNumberOfTables(tableP, num)
LockTableMemory	*tableP;
int 	num;
{
    int	newNum;
    
    newNum = tableP->lockTableSet.numberOfTables - num;
    if (newNum < 0) {
    	Note("LtDecNumberOfTables: Cannot decrement number of tables",DEBERR);
    	return(-1);
    }
    tableP->lockTableSet.numberOfTables = newNum;
    return(newNum);
}

/************************************************************************/
/*  table numbers range between 1 and NMAXLTABLE    	    	    	*/
/************************************************************************/

/************************************************************************/
/*  LtSetTableFrameOffset   - sets offset for the lock table frame  	*/
/*  	    	    	    	 of table n 	    	    	    	*/
/************************************************************************/
void
LtSetTableFrameOffset(tableP, tableNumber, offset)
LockTableMemory	*tableP;
int 	tableNumber;	    	    /* the table number, not the index	*/
Offset	    offset;
{
    tableP->lockTableSet.tableInfo[tableNumber - 1].startTableFrame = offset;
    return;
}

/************************************************************************/
/*  LtGetTableFrameOffset   - gets offset for the lock table frame  	*/
/*  	    	    	      of table n    	    	    	    	*/
/************************************************************************/
Offset
LtGetTableFrameOffset(tableP, tableNumber)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
{
    return(tableP->lockTableSet.tableInfo[tableNumber - 1].startTableFrame);
}




/************************************************************************/
/*  LtSetHashFrameOffset    - sets offset for the lock table hash   	*/
/*  	    	    	      region of table n     	    	    	*/
/************************************************************************/
void
LtSetHashFrameOffset(tableP, tableNumber, offset)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
Offset	    offset;
{
    tableP->lockTableSet.tableInfo[tableNumber - 1].startHashFrame = offset;
    return;
}

/************************************************************************/
/*  LtGetHashFrameOffset    - gets offset for the lock table hash   	*/
/*  	    	    	      region of table n     	    	    	*/
/************************************************************************/
Offset
LtGetHashFrameOffset(tableP, tableNumber)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
{
    return(tableP->lockTableSet.tableInfo[tableNumber - 1].startHashFrame);
}



/************************************************************************/
/*  LtGetLockTable  - returns a pointer to a lock table	    	    	*/
/************************************************************************/
LockTableFrame *
LtGetLockTable(tableP, ltNumber)
LockTableMemory	*tableP;
int ltNumber;	/* the number of the lock table */
{
    LockTableFrame  *ltP;
    if ((ltNumber < 1) || (ltNumber > NMAXLTABLE)) {
    	/* invalid lock table number */
    	Note("LtGetLockTable: invalid lock table id", ERROR);
    	exit(-1);
    }
    ltP = (LockTableFrame *) ((Pointer) tableP + 
    	     LtGetTableFrameOffset(tableP, ltNumber));
    return(ltP);
}


/************************************************************************/
/*  LtSetMaxNumTableEntries - sets maximal number of table entries  	*/
/************************************************************************/
void
LtSetMaxNumTableEntries(tableP, tableNumber, numEntries)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
int 	numEntries;
{   
    LockTableFrame  	*ltP;
    LockTableFrame  	*LtGetLockTable();
    
    tableP->lockTableSet.tableInfo[tableNumber - 1].maxNumTableEntries = numEntries;
    ltP = LtGetLockTable(tableP, tableNumber);
    ltP->maxNumTableEntries = numEntries;
    return;
}

/************************************************************************/
/*  LtGetMaxNumTableEntries - gets maximal number of table entries  	*/
/*  	    	    	    	from the set of tables	    	    	*/
/*  This function returns the same value as LtGetMaxNumTableFrameEntries*/
/************************************************************************/
int
LtGetMaxNumTableEntries(tableP, tableNumber)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
{   
    return(tableP->lockTableSet.tableInfo[tableNumber - 1].maxNumTableEntries);
}


/************************************************************************/
/*  LtGetMaxNumTableFrameEntries  - gets maximal number of table entries*/
/*  	    	    	    	      from a table frame    	    	*/
/*  This function returns the same value as LtGetMaxNumTableEntries 	*/
/************************************************************************/
int
LtGetMaxNumTableFrameEntries(ltP)
LockTableFrame	*ltP;
{   
    return(ltP->maxNumTableEntries);
}


/************************************************************************/
/*  LtSetNumTableEntries    - sets the current number of table	    	*/
/*  	    	    	      entries  	    	    	    	    	*/
/************************************************************************/
void
LtSetNumTableEntries(tableP, tableNumber, numEntries)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
int 	numEntries;
{
    tableP->lockTableSet.tableInfo[tableNumber - 1].numTableEntries = numEntries;
    return;
}


/************************************************************************/
/*  LtGetNumTableEntries    - gets the current number of table	    	*/
/*  	    	    	    	 entries    	    	    	     	*/
/************************************************************************/
int
LtGetNumTableEntries(tableP, tableNumber)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
{
    return(tableP->lockTableSet.tableInfo[tableNumber - 1].numTableEntries);
}

/************************************************************************/
/*  LtIncNumTableEntries    - increments current number of table    	*/
/*  	    	    	      entries  	    	    	    	     	*/
/*  	    	    	    - returns -1, iff too many entries      	*/
/************************************************************************/
int
LtIncNumTableEntries(tableP, tableNumber, numEntries)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
int 	numEntries;
{   int	num;
    
    num = tableP->lockTableSet.tableInfo[tableNumber - 1].numTableEntries 
    	  + numEntries;
    if (num > LtGetMaxNumTableEntries(tableP, tableNumber)) {
    	Note("LtIncNumTableEntries: Too many table entries!",DEBERR);
    	return(-1);
    }
    tableP->lockTableSet.tableInfo[tableNumber - 1].numTableEntries = num;
    /* 'currentTableEntries' is modified in LtSetLockTableEntry (!) */
    return(0);
}

/************************************************************************/
/*  LtDecNumTableEntries    - decrements current number of table entries*/
/*  	    	    	    - returns -1, iff no entries in table   	*/
/************************************************************************/
int
LtDecNumTableEntries(tableP, tableNumber, numEntries)
LockTableMemory	*tableP;
int 	tableNumber;	    /* the table number */
int 	numEntries;
{   int	num;
    
    num = tableP->lockTableSet.tableInfo[tableNumber - 1].numTableEntries 
    	  - numEntries;
    if (num <  0) {
    	Note("LtDecNumTableEntries: Cannot decrement number of table entries!",
    	    	DEBERR);
    	return(-1);
    }
    tableP->lockTableSet.tableInfo[tableNumber - 1].numTableEntries = num;
    /* 'currentTableEntries' is modified in LtDelLockTableEntry (!) */
    return(0);
}



/************************************************************************/
/*  LtGetStartLockTableFrameSection - returns the offset of the	    	*/
/*  	    	    	    	      start of the lock table frame 	*/
/*  	    	     	    	      section	    	    	      	*/
/************************************************************************/
Offset
LtGetStartLockTableFrameSection(tableP)
LockTableMemory	*tableP;
{
    return(tableP->startLockTableFrameSection);
}


/************************************************************************/
/*  LtSetStartLockTableFrameSection 	- sets the offset of the    	*/
/*  	    	    	    	    	  start of the lock table frame	*/
/*  	    	    	    	    	  section   	    	    	*/
/************************************************************************/
void
LtSetStartLockTableFrameSection(tableP, offset)
LockTableMemory	*tableP;
Offset	    offset;
{
    tableP->startLockTableFrameSection = offset;
    return;
}




/************************************************************************/
/*  LtGetStartLockTableHashSection  	- returns the offset of the 	*/
/*  	    	     	    	    	  start of the lock table hash	*/
/*  	    	      	    	    	  section   	    	      	*/
/************************************************************************/
Offset
LtGetStartLockTableHashSection(tableP)
LockTableMemory	*tableP;
{
    return(tableP->startLockTableHashSection);
}


/************************************************************************/
/*  LtSetStartLockTableHashSection  - sets the offset of the	    	*/
/*  	    	    	    	      start of the lock table hash   	*/
/*  	    	    	    	      section	      	    	    	*/
/************************************************************************/
void
LtSetStartLockTableHashSection(tableP, offset)
LockTableMemory	*tableP;
Offset	    offset;
{
    tableP->startLockTableHashSection = offset;
    return;
}





/************************************************************************/
/*  LtGetEndOfSharedLockTable	- returns the offset of the 	    	*/
/*  	    	    	    	  end of the lock table     	    	*/
/************************************************************************/
Offset
LtGetEndOfSharedLockTable(tableP)
LockTableMemory	*tableP;
{
    return(tableP->endOfSharedLockTable);
}


/************************************************************************/
/*  LtSetEndOfSharedLockTable	- sets the offset of the    	    	*/
/*  	    	     	    	  end of the lock table     	    	*/
/************************************************************************/
void
LtSetEndOfSharedLockTable(tableP, offset)
LockTableMemory	*tableP;
Offset	    offset;
{
    tableP->endOfSharedLockTable = offset;
    return;
}


/***********************************************************************/
/************       Access to a lock table frame       *****************/
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/

/************************************************************************/
/*  LtGetLockTable  	    	- defined previously	    	    	*/
/************************************************************************/
/*LockTableFrame *
    LtGetLockTable(tableP, ltNumber)
    LockTableMemory *tableP;
    int	ltNumber;   
    {}
- defined previously
*/



/************************************************************************/
/*  LtGetLockTableType	- returns the type of a lock table  	    	*/
/************************************************************************/
LockTableType
LtGetLockTableType(ltP)
LockTableFrame	*ltP;
{
    return(ltP->lockTableType);
}

/************************************************************************/
/*  LtSetLockTableType	- sets the type of a lock table	    	    	*/
/************************************************************************/
void
LtSetLockTableType(ltP, type)
LockTableFrame	*ltP;
LockTableType	type;
{
    ltP->lockTableType = type;
    return;
}

/************************************************************************/
/*  LtGetLockTableName	- returns the name of a lock table  	    	*/
/************************************************************************/
LockTableName 
LtGetLockTableName(ltP)
LockTableFrame	*ltP;
{
    return(&ltP->lockTableNameData);
}
/************************************************************************/
/*  LtSetLockTableName	- sets the name of a lock table	    	    	*/
/************************************************************************/
void
LtSetLockTableName(ltP, tableName)
LockTableFrame	*ltP;
LockTableName   tableName;
{
    strncpy(&ltP->lockTableNameData, tableName, 16);
    /* ltP->lockTableNameData = tableName; */
    return;
}
/************************************************************************/
/*  LtLockTableTypeIsValid  - returns true, iff its a valid type    	*/
/************************************************************************/
bool
LtLockTableTypeIsValid(ltP)
LockTableFrame	*ltP;
{
    if (ltP->lockTableType != InvalidLockTable)
    	return(true);
    return(false);
}




/************************************************************************/
/*  LtGetLockTableMode	- returns the mode of a lock table  	    	*/
/************************************************************************/
LockTableMode
LtGetLockTableMode(ltP)
LockTableFrame	*ltP;
{
    return(ltP->lockTableMode);
}

/************************************************************************/
/*  LtSetLockTableMode	- sets the Mode of a lock table	    	    	*/
/************************************************************************/
void
LtSetLockTableMode(ltP, mode)
LockTableFrame	*ltP;
LockTableMode	mode;
{
    ltP->lockTableMode = mode;
    return;
}


/************************************************************************/
/*  LtGetNumLockTableEntries	- returns the current number  	    	*/
/*  	    	     	    	  of lock table entries	    	    	*/
/************************************************************************/
int
LtGetNumLockTableEntries(ltP)
LockTableFrame	*ltP;
{
    return(ltP->currentTableEntries);
}

/************************************************************************/
/*  LtSetNumLockTableEntries	- sets the number of lock table	    	*/
/*  	    	      	    	  entries   	    	    	    	*/
/************************************************************************/
void
LtSetNumLockTableEntries(ltP, num)
LockTableFrame	*ltP;
int 	num;
{
    ltP->currentTableEntries = num;
    return;
}

/************************************************************************/
/* lock table entry indexes range between 0 and ... 	    	    	*/
/************************************************************************/

/************************************************************************/
/*  LtGetLockTableEntry	- returns a pointer to a entry of the lock table*/
/************************************************************************/
LockTableEntryData *
LtGetLockTableEntry(ltP, i)
LockTableFrame	*ltP;
int 	i;
{   if (ltP->tableEntry[i].free == false) {
    	return(&ltP->tableEntry[i].entryData);
    } else {
    	return(NULL);
    }
}

/************************************************************************/
/*  LtSetLockTableEntry	    - returns the index  where the entry of 	*/
/*  	    	    	      the lock table has been set   	    	*/
/*  	    	    	      returns a negative integer, iff there 	*/
/*  optimize search !	      is no space in the table	    	    	*/
/************************************************************************/
int
LtSetLockTableEntry(ltP, data)
LockTableFrame	    *ltP;
LockTableEntryData  data;
{
    register	int 	i, maxi;
    
    i = 0;
    maxi = LtGetMaxNumTableFrameEntries(ltP);
    while ( (i < maxi) && 
    	    (ltP->tableEntry[i].free == false) )
       i++;
    /* i is a free index or no space in table */
    if (i >= maxi ) {  	/* not enough space */
    	Note("LtSetLockTableEntry: too many table entries",LDEBUG);
    	return(-1);
    }
    /* i is a free index */
    ltP->tableEntry[i].free = false;
    ltP->tableEntry[i].entryData = data;
    /* now increment number of current table entries */
    ltP->currentTableEntries++;
    return(i);
}

/************************************************************************/
/*  LtDelLockTableEntry	    - deletes the entry of the lock table   	*/
/*  	    	    	    - returns the corresponding semaphore number*/
/************************************************************************/
SemId
LtDelLockTableEntry(ltP, i)
LockTableFrame	    *ltP;
int 	    i;
{
    ltP->tableEntry[i].free = true;
    ltP->currentTableEntries--;
    return(ltP->tableEntry[i].entryData.semIndex);
}


/************************************************************************/
/*  LtLockTableInit 	- initialize a lock table   	    	    	*/
/************************************************************************/
void
LtLockTableInit(tableP, tableNumber, tableName, tableType, tableMode)
LockTableMemory	*tableP;
int 	    	tableNumber;
LockTableName	tableName;
LockTableType	tableType;
LockTableMode	tableMode;
{
    LockTableFrame  *ltP;
    register	int i, imax;
    
    ltP = LtGetLockTable(tableP, tableNumber);
    LtSetLockTableMode(ltP, tableMode);
    LtSetLockTableType(ltP, tableType);
    LtSetLockTableName(ltP, tableName);
    LtSetNumTableEntries(ltP, 0);
    /* maxNumTableEntries set in LMSegmentInit() */
    
    /* initialize all table entries as free entries */
    imax = LtGetMaxNumTableFrameEntries(ltP);
    for (i = 0; i < imax; i++) 
    	ltP->tableEntry[i].free = true;
    return;
}


    


/***********************************************************************/
/************    Access to a lock table hash region    *****************/
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/

/************************************************************************/
/*      LtGetLockTableHash  - returns a pointer to a lock table region  */
/************************************************************************/
LockHashFrame *
LtGetLockTableHash(tableP, ltNumber)
LockTableMemory *tableP;
int     ltNumber;       /* the number of the lock table */
{
        LockHashFrame  *lhP;
        lhP = (LockHashFrame *) ((Pointer) tableP + 
                       	    	  LtGetHashFrameOffset(tableP, ltNumber));
        return(lhP);
}

/************************************************************************/
/*      LtGetStartXidHash     - returns startXidHash offset 	    	*/
/************************************************************************/
Offset
LtGetStartXidHash(lhP)
LockHashFrame  *lhP;
{
        return(lhP->startXidHash);  /* relative to the start of this*/
            	    	    	    /*  hash table region   	    */
            	    	    	    /*  i.e. address D	    	    */
}

/************************************************************************/
/*      LtSetStartXidHash     - sets startXidHash offset    	    	*/
/************************************************************************/
void
LtSetStartXidHash(lhP, offset)
LockHashFrame  *lhP;
Offset	    offset;
{
        lhP->startXidHash = offset; /* relative to the start of this*/
            	    	    	    /*  hash table region   	    */
            	    	    	    /*  i.e. address D	    	    */
        return;	    	
}

/************************************************************************/
/*      LtGetStartOidHash     - returns startOidHash offset 	    	*/
/************************************************************************/
Offset
LtGetStartOidHash(lhP)
LockHashFrame  *lhP;
{
        return(lhP->startOidHash);  /* relative to the start of this*/
            	    	    	    /*  hash table region   	    */
            	    	    	    /*  i.e. address D	    	    */
}

/************************************************************************/
/*      LtSetStartOidHash     - sets startOidHash offset    	    	*/
/************************************************************************/
void
LtSetStartOidHash(lhP, offset)
LockHashFrame  *lhP;
Offset	    offset;
{
        lhP->startOidHash = offset; /* relative to the start of this*/
            	    	    	    /*  hash table region   	    */
            	    	    	    /*  i.e. address D	    	    */
        return;
}

/************************************************************************/
/*      LtGetStartXidFreeSpace   - returns startXidFreeSpace offset 	*/
/************************************************************************/
Offset
LtGetStartXidFreeSpace(lhP)
LockHashFrame  *lhP;
{
        return(lhP->startXidFreeSpace);	/* relative to the start of this*/
            	    	    	    	/*  hash data section 	    	*/
            	    	    	    	/*  i.e. address D1 	    	*/
}

/************************************************************************/
/*      LtSetStartXidFreeSpace   - sets startXidFreeSpace offset    	*/
/************************************************************************/
void
LtSetStartXidFreeSpace(lhP, offset)
LockHashFrame  *lhP;
Offset	    offset;
{
        lhP->startXidFreeSpace = offset;/* relative to the start of this*/
            	    	    	    	/*  hash data section 	    	*/
            	    	    	    	/*  i.e. address D1 	    	*/
        return;
}


/************************************************************************/
/*      LtGetStartOidFreeSpace   - returns startOidFreeSpace offset 	*/
/************************************************************************/
Offset
LtGetStartOidFreeSpace(lhP)
LockHashFrame  *lhP;
{
        return(lhP->startOidFreeSpace);	/* relative to the start of this*/
            	    	    	    	/*  hash data section 	    	*/
            	    	    	    	/*  i.e. address D2 	    	*/
}

/************************************************************************/
/*      LtSetStartOidFreeSpace   - sets startOidFreeSpace offset    	*/
/************************************************************************/
void
LtSetStartOidFreeSpace(lhP, offset)
LockHashFrame  *lhP;
Offset	    offset;
{
        lhP->startOidFreeSpace = offset;/* relative to the start of this*/
            	    	    	    	/*  hash data section 	    	*/
            	    	    	    	/*  i.e. address D2 	    	*/
        return;
}

/************************************************************************/
/*      LtGetEndXidFreeSpace   - returns endXidFreeSpace offset	    	*/
/************************************************************************/
Offset
LtGetEndXidFreeSpace(lhP)
LockHashFrame  *lhP;
{
        return(lhP->endXidFreeSpace);
}

/************************************************************************/
/*      LtSetEndXidFreeSpace   - sets endXidFreeSpace offset	    	*/
/************************************************************************/
void
LtSetEndXidFreeSpace(lhP, offset)
LockHashFrame  *lhP;
Offset	    offset;
{
        lhP->endXidFreeSpace = offset;	/* relative to the start of this*/
            	    	    	    	/*  hash data section 	    	*/
    	    	    	    	    	/*  i.e. address D1 	    	*/
        return;
}


/************************************************************************/
/*      LtGetEndOidFreeSpace   - returns endOidFreeSpace offset	    	*/
/************************************************************************/
Offset
LtGetEndOidFreeSpace(lhP)
LockHashFrame  *lhP;
{
        return(lhP->endOidFreeSpace);	/* relative to the start of this*/
            	    	    	    	/*  hash table region 	    	*/
            	    	    	    	/*  i.e. address D  	    	*/
}

/************************************************************************/
/*      LtSetEndOidFreeSpace   - sets endOidFreeSpace offset	    	*/
/**
###**********************************************************************/
void
LtSetEndOidFreeSpace(lhP, offset)
LockHashFrame  *lhP;
Offset	    offset;
{
        lhP->endOidFreeSpace = offset;	/* relative to the start of this*/
            	    	    	    	/*  hash table region 	    	*/
            	    	    	    	/*  i.e. address D  	    	*/
        return;
}

/************************************************************************/
/*      LtSetNumXidEntries   - sets the current number of Xid entries	*/
/************************************************************************/
void
LtSetNumXidEntries(lhP, num)
LockHashFrame  *lhP;
int 	num;
{   
    lhP->numXidEntries = num;
    return;
}

/************************************************************************/
/*      LtGetNumXidEntries   - returns the current number of Xid entries*/
/************************************************************************/
int
LtGetNumXidEntries(lhP)
LockHashFrame  *lhP;
{   
    return(lhP->numXidEntries); 
}

/************************************************************************/
/*      LtSetMaxNumXidEntries   - sets the current number of Xid entries*/
/************************************************************************/
void
LtSetMaxNumXidEntries(lhP, num)
LockHashFrame  *lhP;
int 	num;
{   
    lhP->maxNumXidEntries = num;
    return;
}

/************************************************************************/
/*      LtGetMaxNumXidEntries   - returns the current number of Xid entries*/
/************************************************************************/
int
LtGetMaxNumXidEntries(lhP)
LockHashFrame  *lhP;
{   
    return(lhP->maxNumXidEntries); 
}

/************************************************************************/
/*      LtIncNumXidEntries    - increments the current number of Xid	*/
/*  	    	    	    	entries	    	    	    	    	*/
/*  	            	      - returns -1, iff too many entries    	*/
/************************************************************************/
int
LtIncNumXidEntries(lhP, num)
LockHashFrame  *lhP;
int 	num;
{   int	newNum;

    newNum = lhP->numXidEntries + num;
    if (newNum > LtGetMaxNumXidEntries(lhP)) {
       Note("LtIncNumXidEntries: too many (xid) hashed entries",DEBERR);
       return(-1);
    }
    lhP->numXidEntries = newNum;
    return(newNum);
}
/************************************************************************/
/*      LtDecNumXidEntries    - decrements the current number of Xid 	*/
/*  	    	    	    	entries	    	    	    	    	*/
/*  	     	    	      - returns -1, iff no entries defined  	*/
/************************************************************************/
int
LtDecNumXidEntries(lhP, num)
LockHashFrame  *lhP;
int 	num;
{   int	newNum;

    newNum = lhP->numXidEntries - num;
    if (newNum < 0) {
       Note("LtDecNumXidEntries: Cannot decrement (xid) hashed entries",DEBERR);
       return(-1);
    }
    lhP->numXidEntries = newNum;
    return(newNum);
}

/************************************************************************/
/*      LtSetNumOidEntries   - sets the current number of Oid entries	*/
/************************************************************************/
void
LtSetNumOidEntries(lhP, num)
LockHashFrame  *lhP;
int 	num;
{   
    lhP->numOidEntries = num;
    return;
}


/************************************************************************/
/*      LtGetNumOidEntries   - returns the current number of Oid entries*/
/************************************************************************/
int
LtGetNumOidEntries(lhP)
LockHashFrame  *lhP;
{   
    return(lhP->numOidEntries); 
}

/************************************************************************/
/*      LtSetMaxNumOidEntries   - sets the current number of Oid entries*/
/************************************************************************/
void
LtSetMaxNumOidEntries(lhP, num)
LockHashFrame  *lhP;
int 	num;
{   
    lhP->maxNumOidEntries = num;
    return;
}

/************************************************************************/
/*      LtGetMaxNumOidEntries   - returns the current number of Oid entries*/
/************************************************************************/
int
LtGetMaxNumOidEntries(lhP)
LockHashFrame  *lhP;
{   
    return(lhP->maxNumOidEntries); 
}

/************************************************************************/
/*      LtIncNumOidEntries    - increments the current number of Oid	*/
/*  	    	    	    	entries	    	    	    	    	*/
/*  	    	       	      - returns -1, iff too many entries    	*/
/************************************************************************/
int
LtIncNumOidEntries(lhP, num)
LockHashFrame  *lhP;
int 	num;
{   int	newNum;

    newNum = lhP->numOidEntries + num;
    if (newNum > LtGetMaxNumOidEntries(lhP)) {
       Note("LtIncNumOidEntries: too many (oid) hashed entries",DEBERR);
       return(-1);
    }
    lhP->numOidEntries = newNum;
    return(newNum);
}

/************************************************************************/
/*      LtDecNumOidEntries    - decrements the current number of Oid 	*/
/*  	    	    	    	entries	    	    	    	    	*/
/*  	            	      - returns -1, iff no entries defined  	*/
/************************************************************************/
int
LtDecNumOidEntries(lhP, num)
LockHashFrame  *lhP;
int 	num;
{   int	newNum;

    newNum = lhP->numOidEntries - num;
    if (newNum < 0) {
       Note("LtDecNumOidEntries: Cannot decrement (oid) hashed entries",DEBERR);
       return(-1);
    }
    lhP->numOidEntries = newNum;
    return(newNum);
}

/************************************************************************/
/*      LtGetHashEntryXid   - returns a Xid hash entry pointer	    	*/
/************************************************************************/
EntryXidData *
LtGetHashEntryXid(lhP, index)
LockHashFrame  *lhP;
int 	index;
{
    EntryXidData    *entry;

    entry =
    (EntryXidData *) ((Pointer) lhP + 
    	(LtGetStartXidHash(lhP) + lhP->entryXidBucket[index]));
    return(entry);
}


/************************************************************************/
/*      LtGetOidFreeSpace  - returns an offset to free Oid hash entry 	*/
/************************************************************************/
Offset
LtGetOidFreeSpace(lhP)
LockHashFrame	*lhP;
{   EntryOidData    *entry; 
    Offset  	    offsetToFreeEntry;	
    
    /* relative to the hash data section, not to lhP ! */
    offsetToFreeEntry = LtGetStartOidFreeSpace(lhP);
    entry = (EntryOidData *) ((Pointer) lhP +
    	    	    	      LtGetStartOidHash(lhP) +
    	    	    	      offsetToFreeEntry);
    /* set new free space offset correct */
    LtSetStartOidFreeSpace(lhP, entry->next);
    return(offsetToFreeEntry);
}

/************************************************************************/
/*      LtGetXidFreeSpace  - returns an offset to free Xid hash entry 	*/
/************************************************************************/
Offset
LtGetXidFreeSpace(lhP)
LockHashFrame	*lhP;
{   EntryXidData    *entry; 
    Offset  	    offsetToFreeEntry;	
    
    /* relative to the hash data section, not to lhP ! */
    offsetToFreeEntry = LtGetStartXidFreeSpace(lhP);
    entry = (EntryXidData *) ((Pointer) lhP +
    	    	    	      LtGetStartXidHash(lhP) +
    	    	    	      offsetToFreeEntry);
    /* set new free space offset correct */
    LtSetStartXidFreeSpace(lhP, entry->next);
    return(offsetToFreeEntry);
}


/************************************************************************/
/*      LtGetFirstHashEntryXid  - returns a pointer to first Xid    	*/
/*  	    	    	    	    	hash entry  	    	    	*/
/************************************************************************/
EntryXidData *
LtGetFirstHashEntryXid(lhP, index)
LockHashFrame	*lhP;
int 	    	index;
{
    EntryXidData    *entry;
    Offset  	    offset;
    
    offset = lhP->entryXidBucket[index];
    if (offset == InvalidOffset) {
    	return(NULL);
    } else {
    	entry = (EntryXidData *) ((Pointer) lhP + 
    	    	    	    	    LtGetStartXidHash(lhP) +
    	    	    	    	    offset);
    	return(entry);
    }
}

/************************************************************************/
/*      LtSetFirstHashEntryXid  - sets  first Xid hash entry	    	*/
/************************************************************************/
void
LtSetFirstHashEntryXid(lhP, index, entry)
LockHashFrame	*lhP;
int 	    	index;
EntryXidData	*entry;
{
    lhP->entryXidBucket[index] = (Offset) ((Pointer) entry -
    	    	    	    	    	    (Pointer) lhP  -
    	    	    	    	    	    LtGetStartXidHash(lhP));
    return;
}

/************************************************************************/
/*      LtGetFirstHashEntryOid  - returns a pointer to first Oid    	*/
/*  	    	    	    	    	hash entry  	    	    	*/
/************************************************************************/
EntryOidData *
LtGetFirstHashEntryOid(lhP, index)
LockHashFrame	*lhP;
int 	    	index;
{
    EntryOidData    *entry;
    Offset  	    offset;
    offset = lhP->entryOidBucket[index];
    if (offset == InvalidOffset) {
    	return(NULL);
    } else {
    	entry = (EntryOidData *) ((Pointer) lhP + 
    	    	    	    	    LtGetStartOidHash(lhP) +
    	    	    	    	    offset);
    	return(entry);
    }
}

/************************************************************************/
/*      LtSetFirstHashEntryOid  - sets  first Oid hash entry	    	*/
/************************************************************************/
void
LtSetFirstHashEntryOid(lhP, index, entry)
LockHashFrame	*lhP;
int 	    	index;
EntryOidData	*entry;
{
    lhP->entryOidBucket[index] = (Offset) ((Pointer) entry -
    	    	    	    	    	    (Pointer) lhP  -
    	    	    	    	    	    LtGetStartOidHash(lhP));
    return;
}

/************************************************************************/
/*      LtOffsetXidHashEntry   - returns a Xid hash entry offset    	*/
/************************************************************************/
Offset
LtOffsetXidHashEntry(lhP, entry)
LockHashFrame	*lhP;
EntryXidData	*entry;
{   return( (Offset) ((Pointer) entry - (Pointer) lhP -
    	    	    	LtGetStartXidHash(lhP)) );
}

/************************************************************************/
/*      LtOffsetOidHashEntry   - returns a Oid hash entry offset    	*/
/************************************************************************/
Offset
LtOffsetOidHashEntry(lhP, entry)
LockHashFrame	*lhP;
EntryOidData	*entry;
{   return( (Offset) ((Pointer) entry - (Pointer) lhP -
    	    	    	LtGetStartOidHash(lhP)) );
}

/************************************************************************/
/*      LtPointerXidHashEntry   - returns an Xid hash entry pointer 	*/
/************************************************************************/
EntryXidData *
LtPointerXidHashEntry(lhP, offset)
LockHashFrame	*lhP;
Offset	    	offset;
{
    return((EntryXidData *) ((Pointer) lhP +
    	    	    	    	LtGetStartXidHash(lhP) +
    	    	    	    	offset));
}

/************************************************************************/
/*      LtPointerOidHashEntry   - returns an Oid hash entry pointer 	*/
/************************************************************************/
EntryOidData *
LtPointerOidHashEntry(lhP,offset)
LockHashFrame	*lhP;
Offset	    	offset;
{
    return((EntryOidData *) ((Pointer) lhP +
    	    	    	    	LtGetStartOidHash(lhP) +
    	    	    	    	offset));
}
/************************************************************************/
/*      LtHashXid   	       - returns an index of a hashed Xid   	*/
/************************************************************************/
int
LtHashXid(key)
TransactionIdData   key;
{   register	int 	    	k, k1;
    register	int 	    	i;
    register	int 	    	p;
    
    p = 1;
    k = 0;
    for (i = 0; i <= 4; i++) {
    	k1 = key.data[i]; 
    	k = k + k1 * p;
    	p = p * 2;
    }
    i = k % NMAXXIDHASH;
    return(i);
}

/************************************************************************/
/*      LtHashRelId   	       - returns an index of a hashed RelId   	*/
/************************************************************************/
int
LtHashRelId(key)
LRelId 	key;   /* if LRelId changes, adapt this function !! 	    	*/
{   register	unsigned long	k;
    register	int 	    	i;
    k = (unsigned long) key.relId + (2 * (unsigned long) key.dbId);
    i = k % NumberOfEntryOidBuckets; /* defined as parameter, prime 	*/
    return(i);
}

/************************************************************************/
/*      LtCreateRelId              - creates a relation id for the lmgr	*/
/************************************************************************/
LRelId
LtCreateRelId(dbId, relId)
OID 	dbId;
OID 	relId;
{   LRelId  temp;
    temp.dbId = dbId;
    temp.relId= relId;
    return(temp);
}

/************************************************************************/
/*      LtGetRelId   	       - gets a relation id for the lmgr    	*/
/************************************************************************/
OID
LtGetRelId(rel)
LRelId	*rel;
{   return(rel->relId);
}

/************************************************************************/
/*      LtGetDbIdRelId   - gets a db-id of a relation id for the lmgr	*/
/************************************************************************/
OID
LtGetDbIdRelId(rel)
LRelId	*rel;
{   return(rel->dbId);
}

/************************************************************************/
/*      LtEqualsRelId              - returns true, if '=' holds       	*/
/************************************************************************/
bool
LtEqualsRelId(lmrelId1, lmrelId2)
LRelId	lmrelId1;
LRelId	lmrelId2;
{   return((bool) ((lmrelId1.relId == lmrelId2.relId) && 
            (lmrelId1.dbId  == lmrelId2.dbId )));
}

/************************************************************************/
/*      LtSetHashEntryXid   - sets a Xid hash entry 	    	    	*/
/*  	    	    	      returns 1 iff it succeeds,    	    	*/
/*  	    	    	      	     -1 iff there was an error	    	*/
/************************************************************************/
int
LtSetHashEntryXid(lhP, data, tableIndex)
LockHashFrame	    *lhP;
LockTableEntryData  data;
int 	    	    tableIndex; /* index for tableEntry array */
{
    int	    	    bucket, ignore;
    EntryXidData    *entry, *eP;
    Offset  	    offsetToNewData, o;
    
    if ( (LtGetNumXidEntries(lhP) + 1) > LtGetMaxNumXidEntries(lhP)) {
    	Note("LtSetHashEntryXid: too many entries in Xid hash data section");
    	return(-1);
    }
    /* determine hash bucket */
    bucket = LtHashXid(data.xidData);
    
    /* get an offset to free space for data */
    /*  relative to hash data section	*/  
    offsetToNewData = LtGetXidFreeSpace(lhP); 
    entry = LtPointerXidHashEntry(lhP, offsetToNewData);
    entry->entryIndex = tableIndex;
    entry->xidData = data.xidData;
    entry->free = false;
    entry->next = InvalidOffset;  /* default value for next-offset  	    */
    
    /* handle insertion point for this hash data entry 	    	    	    */
    /* search for end of chain or the right position 	    	    	    */
    
    if (lhP->entryXidBucket[bucket] == InvalidOffset) {	
    	/* there is no chain on this bucket 	    */
    	/* set the correct offset in the hash array */
    	LtSetFirstHashEntryXid(lhP, bucket, entry);
    }
    else {  	    	    /* there exists a chain for this bucket 	*/
    	eP = LtGetFirstHashEntryXid(lhP, bucket);   
    	while (eP->next != InvalidOffset)   {	/* while not end of chain*/
    	    /* search for the right position in the chain comparing xid's*/
    	/* ... (ordered chain, or insert on first position?)optimize here*/
    	    /* otherwise go to the next entry in the chain */
    	    eP = LtPointerXidHashEntry(lhP,eP->next);
    	}
    	/* reached end of chain or right position,  	    	    	*/
    	/*    eP points to predecessor data entry   	    	    	*/
    	entry->next = eP->next;	    /* thats NIL or its the new successor*/
    	eP->next = offsetToNewData; 	/* now chain is closed 	    	*/
    }
    /*increment current number of entries */
    ignore = LtIncNumXidEntries(lhP, 1);
    return(1);
}

/************************************************************************/
/*      LtFindHashEntryXid   - search for a Xid hash entry  	    	*/
/*  	    	    	       returns the entryIndex, iff it succeeds,	*/
/*  	     	    	      	    	 -1 iff there was an error  	*/
/*  	    	    	    	    	 -2 iff there is no entry   	*/
/************************************************************************/
int
LtFindHashEntryXid(lhP, ltP, data, testAll,
    	    	   isFirstEntry, bucketIndex, prevP, curP)
LockHashFrame	    *lhP;   	    	/* input parameter  */
LockTableFrame	    *ltP;   	    	/* input parameter  */
LockTableEntryData  data;   	    	/* input parameter  */
bool	    	    testAll;	    	/* input parameter  */
bool	    	    *isFirstEntry;  	/* output parameter */
int 	    	    *bucketIndex;   	/* output parameter */
EntryXidData	    **prevP, **curP; 	/* output parameter */
{
    int	    	    	bucket, index, ignore;
    bool    	    	endOfChain;
    LockTableEntryData	*eP;
    Offset  	    	offset;
    LockTableEntryData	*LtGetLockTableEntry();
    EntryXidData    	*startP, *helpP;

    /* determine hash bucket */
    bucket = LtHashXid(data.xidData);
    *bucketIndex = bucket;
    /* give me the first entry pointer */
    startP = LtGetFirstHashEntryXid(lhP, bucket);
    /* is there a valid bucket entry	    	    	    	    	*/
    if (startP == NULL) {
    	/* there is no hash entry for this data	    	    	    	*/
    	return(-2); /* nothing found */
    }

    *curP = startP;
    /* get the corresponding lock table entry */
    eP = LtGetLockTableEntry(ltP, (*curP)->entryIndex);
    if (eP == NULL) { /* for this entry index entry data was expected 	*/
    	Note("LtFindHashEntryXid: Could not find lock entry data (FATAL)",
    	    	ERROR);
    	return(-1);
    }
    
    if (!testAll) { /* do not test the locktype variable    	    	*/
    	data.lockType = eP->lockType; /* that suppresses the test   	*/
    	data.xidData = eP->xidData;
    }
    endOfChain = false;
    while (((eP->lockType != data.lockType) ||
    	    !LtEqualsRelId(eP->lockSrcRel, data.lockSrcRel) ||
            (eP->lockSrcPage != data.lockSrcPage) ||
            !TransactionIdEquals(&eP->xidData, &data.xidData) ||
            (eP->lockSrcLine != data.lockSrcLine)  ) &&
           ( !endOfChain )
          ) {
    	if ((*curP)->next != InvalidOffset) { /* there is a 'next' entry*/
    	    helpP = *curP;
    	    *curP = LtPointerXidHashEntry(lhP, (*curP)->next);
    	    *prevP = helpP;
    	    eP = LtGetLockTableEntry(ltP, (*curP)->entryIndex);
    	    if (eP == NULL) { /*  entry data was expected   	    	*/
    	    	Note("LtFindHashEntryXid: Could not find lock entry data (FATAL)",
    	    	    	ERROR);
    	    	return(-1);
    	    }
    	    if (!testAll) { /* do not test the locktype variable    	*/
    	    	data.lockType = eP->lockType; /* that supresses the test*/
    	    	data.xidData = eP->xidData;
    	    }
    	} else { /* there is no 'next' entry in the chain */
    	    endOfChain = true;
    	}
    }
    if (endOfChain) {
    	/* entry not found */
    	Note("LtFindHashEntryXid: Could not find Xid hash entry",DEBERR);
    	return(-1);
    }
    if (*curP == startP) {  /* found entry is the first in the chain	*/
    	*isFirstEntry = true;
    } else {
    	*isFirstEntry = false;
    }
    /* entry found, pointed to by *curP,    	    	    	    	*/
    /* previous entry pointed to by *prevP  	    	    	    	*/
    return ((*curP)->entryIndex);
}




/************************************************************************/
/*      LtDelHashEntryXid   - removes a Xid hash entry 	    	    	*/
/*  	    	    	      returns the entryIndex, iff it succeeds, 	*/
/*  	    	    	      	     -1 iff there was an error	    	*/
/************************************************************************/
int
LtDelHashEntryXid(lhP, ltP, data)
LockHashFrame	    *lhP;
LockTableFrame	    *ltP;
LockTableEntryData  data;
{
    int	    	    	bucket, index, ignore;
    bool    	    	endOfChain, isFirstEntry;
    EntryXidData    	*startP, *helpP, *prevP, *curP;
    LockTableEntryData	*eP;
    Offset  	    	offset;
    LockTableEntryData	*LtGetLockTableEntry();
    int	    	    	LtFindHashEntryXid();
    
    index = LtFindHashEntryXid(lhP, ltP, data, true, &isFirstEntry, 
    	    	    	    	&bucket, &prevP, &curP);
    if ((index == -1) || (index == -2)) {
    	Note("LtDelHashEntryXid: entry to be deleted not found", DEBERR);
    	return(-1);
    }
    /* entry found, pointed to by curP, previous entry  by prevP    */
    if (isFirstEntry) {  /* found entry is the first in the chain   */
    	/* set the second entry to be first in the chain    	    */
    	lhP->entryXidBucket[bucket] = curP->next;   /* maybe that's NIL	*/
    } else { /* found entry is not the first one in the chain 	    */
    	prevP->next = curP->next;   	    	/* maybe that's NIL */
    }
    /* now put the entry pointed to by curP to the free space chain */
    curP->next = LtGetStartXidFreeSpace(lhP);
    LtSetStartXidFreeSpace(lhP, LtOffsetXidHashEntry(lhP, curP));
    curP->free = true;
    curP->xidData = *NullTransactionId;
    curP->entryIndex = -1;
    
    /* decrement the current number of  xid hash data entries	    	*/
    ignore = LtDecNumXidEntries(lhP, 1);
    return(index);
}

/************************************************************************/
/*   LtFindNextHashEntryXid   - search for a Xid hash entry  	    	*/
/*                              comparing only the Xid Data             */
/*   special implementation for 'release all locks for a Xid'           */
/*  	    	    	       returns the entryIndex, iff it succeeds,	*/
/*  	     	    	      	    	 -1 iff there was an error  	*/
/*  	    	    	    	    	 -2 iff there is no entry   	*/
/************************************************************************/
int  
LtFindNextHashEntryXid(lhP, ltP, xidData, isFirstEntry,
                       bucketIndex, prevP, curP)
LockHashFrame	    *lhP;   	    	/* input parameter  */
LockTableFrame	    *ltP;   	    	/* input parameter  */
TransactionIdData   xidData;   	    	/* input parameter  */
bool	    	    *isFirstEntry;  	/* output parameter */
int 	    	    *bucketIndex;   	/* output parameter */
EntryXidData	    **prevP, **curP; 	/* output parameter */
{  
    int	    	    	bucket, index, ignore;
    bool    	    	endOfChain;
    LockTableEntryData	*eP;
    Offset  	    	offset;
    EntryXidData    	*startP, *helpP;
    LockTableEntryData	*LtGetLockTableEntry();
   
    /* determine hash bucket */
    bucket = LtHashXid(xidData);
    *bucketIndex = bucket;
    /* give me the first entry pointer */
    startP = LtGetFirstHashEntryXid(lhP, bucket);
    /* is there a valid bucket entry	    	    	    	    	*/
    if (startP == NULL) {
    	/* there is no hash entry for this data	    	    	    	*/
    	return(-2); /* nothing found, it's not fatal!	    	    	*/
    }
    *curP = startP;
    /* get the corresponding lock table entry */
    eP = LtGetLockTableEntry(ltP, (*curP)->entryIndex);
    if (eP == NULL) { /* for this entry index entry data was expected 	*/
    	Note("LtFindNextHashEntryXid: Could not find lock entry data (FATAL)",
    	    	ERROR);
    	return(-1);
    }
    endOfChain = false;
    while ( !TransactionIdEquals(&eP->xidData, &xidData) &&
            !endOfChain )
    {
    	if ((*curP)->next != InvalidOffset) { /* there is a 'next' entry*/
    	    helpP = *curP;
    	    *curP = LtPointerXidHashEntry(lhP, (*curP)->next);
    	    *prevP = helpP;
    	    eP = LtGetLockTableEntry(ltP, (*curP)->entryIndex);
    	    if (eP == NULL) { /*  entry data was expected   	    	*/
    	    	Note("LtFindNextHashEntryXid: Could not find lock entry data (FATAL)",
    	    	    	ERROR);
    	    	return(-1);
    	    }
    	} else { /* there is no 'next' entry in the chain */
    	    endOfChain = true;
    	}
    } /* while */
    if (endOfChain) {
    	/* entry not found */
    	return(-2);
    }
    if (*curP == startP) {  /* found entry is the first in the chain	*/
    	*isFirstEntry = true;
    } else {
    	*isFirstEntry = false;
    }
    /* entry found, pointed to by *curP,    	    	    	    	*/
    /* previous entry pointed to by *prevP  	    	    	    	*/
    return ((*curP)->entryIndex);
}


/************************************************************************/
/*  LtDelNextHashEntryXid   - removes a Xid hash entry next in a chain  */
/*  	    	    	    	    	    	    	    	    	*/
/*  special implementation for 'release all locks for a Xid'            */
/*  	    	    	    	    	    	    	    	    	*/
/*  	    	    	      returns a pointer to corresponding table  */
/*                                    entryIndex, iff it succeeds    	*/
/*                                 NULL iff there is no entry           */
/*  	       (LockTableEntryData *)-1 iff there was an error	    	*/
/************************************************************************/
LockTableEntryData *
LtDelNextHashEntryXid(lhP, ltP, xidData)
LockHashFrame	    *lhP;
LockTableFrame	    *ltP;
TransactionIdData   xidData;
{
    int	    	    	bucket, index, ignore;
    bool    	    	endOfChain, isFirstEntry;
    EntryXidData    	*startP, *helpP, *prevP, *curP;
    LockTableEntryData  *entry;

    
    index = LtFindNextHashEntryXid(lhP, ltP, xidData, &isFirstEntry,
                                   &bucket, &prevP, &curP);
    if ((index == -2) ) {
    	/* end of chain found */
    	return(NULL);
    }
    if ((index == -1) ) {
        Note("LtDelNextHashEntryXid: FATAL: cannot find table entry", ERROR);
        return( (LockTableEntryData *)-1);
    }
    /* entry found, pointed to by curP, previous entry  by prevP    */
    entry = LtGetLockTableEntry(ltP, curP->entryIndex);
    if (isFirstEntry) {  /* found entry is the first in the chain   */
    	/* set the second entry to be first in the chain    	    */
    	lhP->entryXidBucket[bucket] = curP->next;   /* maybe that's NIL	*/
    } else { /* found entry is not the first one in the chain 	    */
    	prevP->next = curP->next;   	    	/* maybe that's NIL */
    }
    /* now put the entry pointed to by curP to the free space chain */
    curP->next = LtGetStartXidFreeSpace(lhP);
    LtSetStartXidFreeSpace(lhP, LtOffsetXidHashEntry(lhP, curP));
    curP->free = true;
    curP->xidData = *NullTransactionId;
    curP->entryIndex = -1;
    
    /* decrement the current number of  xid hash data entries	    	*/
    ignore = LtDecNumXidEntries(lhP, 1);
    
    return(entry);
}



/************************************************************************/
/*      LtFindNextHashEntryOid   - search for a Oid hash entry 	    	*/
/*  	    	    	       returns the entryIndex, iff it succeeds,	*/
/*  	     	    	      	    	 -1 iff there was an error  	*/
/*  	    	    	    	    	 -2 iff there is no entry   	*/
/************************************************************************/
int
LtFindNextHashEntryOid(lhP, ltP, data, bucket, oldCurP, testAll, 
    	    srcCompLevel, isFirstEntry,  prevP, curP)
LockHashFrame	    *lhP;   	    	/* input parameter  */
LockTableFrame	    *ltP;   	    	/* input parameter  */
LockTableEntryData  data;   	    	/* input parameter  */
int 	    	    bucket; 	    	/* input parameter  */
EntryOidData	    *oldCurP; 	    	/* input parameter  */
bool	    	    testAll;	    	/* input parameter  */
int 	    	    srcCompLevel;   	/* input parameter  */	    
bool	    	    *isFirstEntry;  	/* output parameter */
EntryOidData	    **prevP; 	    	/* output parameter */
EntryOidData	    **curP; 	    	/* output parameter */
{
    int	    	    	index, ignore;
    bool    	    	endOfChain;
    LockTableEntryData	*eP;
    Offset  	    	offset;
    LockTableEntryData	*LtGetLockTableEntry();
    EntryOidData    	*startP, *helpP;

    if (oldCurP->next == InvalidOffset) { /* there is no 'next' entry	*/
    	return(-2); /* nothing found */
    }
    
    startP = LtPointerOidHashEntry(lhP, oldCurP->next);
    *curP = startP;
    /* get the corresponding lock table entry */
    eP = LtGetLockTableEntry(ltP, (*curP)->entryIndex);
    if (eP == NULL) { /* for this entry index entry data was expected 	*/
    	Note("LtFindNextHashEntryOid: Could not find lock entry data (FATAL)",
    	    	ERROR);
    	return(-1); /* fatal error */
    }
    
    
    if (!testAll) { /* do not test the locktype variable    	    	*/
    	data.lockType = eP->lockType; /* that supresses the test    	*/
    	switch (srcCompLevel) {
    	  case RelationLevel: 	/* suppress page comparision	    	*/
    	    	    	    	data.lockSrcPage = eP->lockSrcPage;
    	                      	/* fall through */
    	  case PageLevel:   	/* suppress line comparision	    	*/
    	    	    	    	data.lockSrcLine = eP->lockSrcLine;
    	    	    	    	/* fall through */
    	  case LineLevel:   	;
    	    	    	    	/* do not suppress any comparision  	*/
    	    	    	    	break;
    	  default: ;
        }
    }
    endOfChain = false;
    while (((eP->lockType != data.lockType) ||
    	    !LtEqualsRelId(eP->lockSrcRel, data.lockSrcRel) ||
            (eP->lockSrcPage != data.lockSrcPage) ||
            (eP->lockSrcLine != data.lockSrcLine) ) &&
           ( !endOfChain )
          ) {
    	if ((*curP)->next != InvalidOffset) { /* there is a 'next' entry*/
    	    helpP = *curP;
    	    *curP = LtPointerOidHashEntry(lhP, (*curP)->next);
    	    *prevP = helpP;
    	    eP = LtGetLockTableEntry(ltP, (*curP)->entryIndex);
    	    if (eP == NULL) { /*  entry data was expected   	    	*/
    	    	Note("LtFindNextHashEntryOid: Could not find lock entry data (FATAL)",
    	    	    	ERROR);
    	    	return(-1); /* fatal error */
    	    }
    	    if (!testAll) { /* do not test the locktype variable    	*/
    	    	data.lockType = eP->lockType; /* that supresses the test*/
    	    	switch (srcCompLevel) {
    	    	    case RelationLevel:     /* suppress page comparisio	*/
    	    	    	    	    data.lockSrcPage = eP->lockSrcPage;
    	                      	    /* fall through */
    	    	    case PageLevel: 	    /* suppress line comparision*/
    	    	    	    	    data.lockSrcLine = eP->lockSrcLine;
    	    	    	    	    /* fall through */
    	    	    case LineLevel: ;	    /* do not suppress any  	*/
    	    	    	    	    	    /* comparision  	    	*/
    	    	    	    	    break;
    	    	    default:        ;
            	} /* end switch */
    	    }
    	} else { /* there is no 'next' entry in the chain */
    	    endOfChain = true;
    	}
    }
    if (endOfChain) {
    	/* entry not found */
    	Note("LtFindNextHashEntryOid: Could not find Oid hash entry",LDEBUG);
    	return(-2);
    }
    if (*curP == startP) {  /* found entry is the first in the chain	*/
    	*isFirstEntry = true;
    } else {
    	*isFirstEntry = false;
    }
    /* entry found, pointed to by *curP,    	    	    	    	*/
    /* previous entry pointed to by *prevP  	    	    	    	*/
    return ((*curP)->entryIndex);
}




/************************************************************************/
/*      LtFindHashEntryOid   - search for a Oid hash entry  	    	*/
/*  	    	    	       returns the entryIndex, iff it succeeds,	*/
/*  	     	    	      	    	 -1 iff there was an error  	*/
/*  	    	    	    	    	 -2 iff there is no entry   	*/
/************************************************************************/
int
LtFindHashEntryOid(lhP, ltP, data, testAll, srcCompLevel,
    	    	   isFirstEntry, bucketIndex, prevP, curP)
LockHashFrame	    *lhP;   	    	/* input parameter  */
LockTableFrame	    *ltP;   	    	/* input parameter  */
LockTableEntryData  data;   	    	/* input parameter  */
bool	    	    testAll;	    	/* input parameter  */
int 	    	    srcCompLevel;   	/* input parameter  */
bool	    	    *isFirstEntry;  	/* output parameter */
int 	    	    *bucketIndex;   	/* output parameter */
EntryOidData	    **prevP; 	    	/* output parameter */
EntryOidData	    **curP; 	    	/* output parameter */
{
    int	    	    	bucket, index, ignore;
    bool    	    	endOfChain;
    LockTableEntryData	*eP;
    Offset  	    	offset;
    LockTableEntryData	*LtGetLockTableEntry();
    EntryOidData    	*startP, *helpP;

    /* determine hash bucket */
    bucket = LtHashRelId(data.lockSrcRel);
    *bucketIndex = bucket;
    /* give me the first entry pointer 	    	    	    	    	*/
    startP = LtGetFirstHashEntryOid(lhP, bucket);
    /* is there a valid bucket entry	    	    	    	    	*/
    if (startP == NULL) {
    	/* there is no hash entry for this data	    	    	    	*/
    	return(-2); /* nothing found */
    }

    *curP = startP;
    /* get the corresponding lock table entry */
    eP = LtGetLockTableEntry(ltP, (*curP)->entryIndex);
    if (eP == NULL) { /* for this entry index entry data was expected 	*/
    	Note("LtFindHashEntryOid: Could not find lock entry data (FATAL)",
    	    	ERROR);
    	return(-1);
    }
    
    
    if (!testAll) { /* do not test the locktype and xidData variable	*/
    	data.lockType = eP->lockType; 	/* that suppresses the test 	*/
     	data.xidData = eP->xidData;  	/* that suppresses the test 	*/
    	switch (srcCompLevel) {
    	  case RelationLevel: 	/* suppress page comparision	    	*/
    	    	    	    	data.lockSrcPage = eP->lockSrcPage;
    	                      	/* fall through */
    	  case PageLevel:   	/* suppress line comparision	    	*/
    	    	    	    	data.lockSrcLine = eP->lockSrcLine;
    	    	    	    	/* fall through */
    	  case LineLevel:   	;
    	    	    	    	/* do not suppress any comparision  	*/
    	    	    	    	break;
    	  default: ;
        }
    	  
    }
    endOfChain = false;
    while (((eP->lockType != data.lockType) ||
            !TransactionIdEquals(&eP->xidData, &data.xidData) ||
    	    !LtEqualsRelId(eP->lockSrcRel, data.lockSrcRel) ||
            (eP->lockSrcPage != data.lockSrcPage) ||
            (eP->lockSrcLine != data.lockSrcLine) ) &&
           ( !endOfChain )
          ) {
    	if ((*curP)->next != InvalidOffset) { /* there is a 'next' entry*/
    	    helpP = *curP;
    	    *curP = LtPointerOidHashEntry(lhP, (*curP)->next);
    	    *prevP = helpP;
    	    eP = LtGetLockTableEntry(ltP, (*curP)->entryIndex);
    	    if (eP == NULL) { /*  entry data was expected   	    	*/
    	    	Note("LtFindHashEntryOid: Could not find lock entry data (FATAL)",
    	    	    	ERROR);
    	    	return(-1);
    	    }
    	    if (!testAll) { /* do not test the locktype variable    	*/
    	    	data.lockType = eP->lockType; /*that suppresses the test*/
     	    	data.xidData = eP->xidData;    /* suppresse the test 	*/
    	    	switch (srcCompLevel) {
    	    	    case RelationLevel:     /* suppress page comparisio	*/
    	    	    	    	    data.lockSrcPage = eP->lockSrcPage;
    	                      	    /* fall through */
    	    	    case PageLevel: 	    /* suppress line comparision*/
    	    	    	    	    data.lockSrcLine = eP->lockSrcLine;
    	    	    	    	    /* fall through */
    	    	    case LineLevel: ;	    /* do not suppress any  	*/
    	    	    	    	    	    /* comparision  	    	*/
    	    	    	    	    break;
    	    	    default: ;
            	} /* end switch */
    	    } /* end if  !testALL */
    	} else { /* there is no 'next' entry in the chain */
    	    endOfChain = true;
    	} /* end else  */
    } /* end while */
    if (endOfChain) {
    	/* entry not found */
    	Note("LtFindHashEntryOid: Could not find Oid hash entry",LDEBUG);
    	return(-2);
    }
    if (*curP == startP) {  /* found entry is the first in the chain	*/
    	*isFirstEntry = true;
    } else {
    	*isFirstEntry = false;
    }
    /* entry found, pointed to by *curP,    	    	    	    	*/
    /* previous entry pointed to by *prevP  	    	    	    	*/
    return ((*curP)->entryIndex);
}






/************************************************************************/
/*      LtDelHashEntryOid   - removes an Oid hash entry     	    	*/
/*  	    	    	      returns the entryIndex, iff it succeeds, 	*/
/*  	    	    	      	     -1 iff there was an error	    	*/
/************************************************************************/
int
LtDelHashEntryOid(lhP, ltP, data)
LockHashFrame	    *lhP;
LockTableFrame	    *ltP;
LockTableEntryData  data;
{
    int	    	    	bucket, index, ignore;
    bool    	    	endOfChain, isFirstEntry;
    EntryOidData    	*startP, *helpP, *prevP, *curP;
    LockTableEntryData	*eP;
    Offset  	    	offset;
    LockTableEntryData	*LtGetLockTableEntry();
    int	    	    	LtFindHashEntryOid();
    
    index = LtFindHashEntryOid(lhP, ltP, data, true, DummyInteger,
    	    	    	    &isFirstEntry, &bucket, &prevP, &curP);
    if (index == -1) {
    	Note("LtDelHashEntryOid: entry to be deleted not found", DEBERR);
    	return(-1);
    }
    /* entry found, pointed to by curP,     	    	    	    */
    /* previous entry pointed to by prevP   	    	    	    */
    if (isFirstEntry) {  /* found entry is the first in the chain   */
    	/* set the second entry to be first in the chain    	    */
    	lhP->entryOidBucket[bucket] = curP->next;   /* maybe that's NIL	*/
    } else { /* found entry is not the first one in the chain 	    */
    	prevP->next = curP->next;   	    	/* maybe that's NIL */
    }
    /* now put the entry pointed to by curP to the free space chain */
    curP->next = LtGetStartOidFreeSpace(lhP);
    LtSetStartOidFreeSpace(lhP, LtOffsetOidHashEntry(lhP, curP));
    curP->free = true;
    curP->lockSrcRel = LtCreateRelId(InvalidObjectId, InvalidObjectId);
    curP->lockSrcPage = InvalidObjectId;
    curP->lockSrcLine = InvalidObjectId;
    curP->entryIndex = -1;
    
    /* decrement the current number of  oid hash data entries	    	*/
    ignore = LtDecNumOidEntries(lhP, 1);
    return(index);
}


/************************************************************************/
/*      LtSetHashEntryOid   - sets a Oid hash entry 	    	    	*/
/*  	    	    	    - returns 1, iff it succeeds    	    	*/
/*  	    	    	    	     -1, iff there was an error	    	*/
/************************************************************************/
int
LtSetHashEntryOid(lhP, data, tableIndex)
LockHashFrame	    *lhP;
LockTableEntryData  data;
int 	    	    tableIndex;	/* index for tableEntry array */
{
    int	    	    bucket, ignore;
    EntryOidData    *entry, *eP;
    Offset  	    offsetToNewData, o;
    
    if ( (LtGetNumOidEntries(lhP) + 1) > LtGetMaxNumOidEntries(lhP)) {
    	Note("LtSetHashEntryOid: too many entries in Oid hash data section");
    	return(-1);
    }
    /* determine hash bucket	    	    	    	    	    	*/
    bucket = LtHashRelId(data.lockSrcRel);
    
    /* get an offset to free space for data 	    	    	    	*/
    /*   relative to start of corresponding hash section    	    	*/
    offsetToNewData = LtGetOidFreeSpace(lhP);
    entry = LtPointerOidHashEntry(lhP, offsetToNewData);
    entry->entryIndex = tableIndex;
    entry->lockSrcRel = data.lockSrcRel;
    entry->lockSrcPage = data.lockSrcPage;
    entry->lockSrcLine = data.lockSrcLine;
    entry->free = false;
    entry->next = InvalidOffset;    /* default value for next-offset	*/
    
    /* handle insertion point for this hash data section    	    	*/
    /* search for end of chain or the right position	    	    	*/
    if (lhP->entryOidBucket[bucket] == InvalidOffset)	{
    	/* there is nor chain on this bucket	    	    	    	*/
    	/* set the correct offset in the hash array 	    	    	*/
    	LtSetFirstHashEntryOid(lhP, bucket, entry);
    }
    else {  	/* there exists a chain for this bucket	    	    	*/
    	eP = LtGetFirstHashEntryOid(lhP, bucket);
    	while (eP->next != InvalidOffset)   {	/*while not end of chain*/
    	    /* search for the right position in the chain   	    	*/
    	    /* ..(ordered?, or insert on first position	(optimize here)	*/
    	    /* otherwise go to the next entry in the chain  	    	*/
    	    eP = LtPointerOidHashEntry(lhP, eP->next);
    	}
    	/* reached end of chain or right position   	    	    	*/
    	/*  eP points to predecessor data entry	    	    	    	*/
    	entry->next = eP->next; /* that's nil or it's the new successor	*/
    	eP->next = offsetToNewData; /* now chain is cloed   	    	*/
    }
    /* increment current number of entries */
    ignore = LtIncNumOidEntries(lhP, 1);
    return(1);
}


/************************************************************************/
/*      LtLockTableHashInit       - initialize a lock table hash region */
/************************************************************************/
void
LtLockTableHashInit(tableP, tableNum)
LockTableMemory	*tableP;
int 	tableNum;
{
    LockHashFrame   *lhP;
    int	    size, i;
    TableOffsets    *toP;
    EntryXidData    *eXidP;
    EntryOidData    *eOidP;
    
    /* get the right region */
    lhP = LtGetLockTableHash(tableP, tableNum); 
    toP = LtComputeOffsets(&size);
    /* initialize Xid hash control section within region */
    LtSetStartXidHash(lhP, toP->offsetToXidHashData);
    LtSetStartXidFreeSpace(lhP, 0); /* all free, offset relative to D1 	    */
    LtSetEndXidFreeSpace(lhP, toP->offsetToOidHashData);    /*end of section*/
    LtSetNumXidEntries(lhP, 0);
    LtSetMaxNumXidEntries(lhP, NumberOfEntryXidData);
    for (i = 0; i < NMAXXIDHASH; i++) 	    	 /* initialize buckets 	    */
    	lhP->entryXidBucket[i] = InvalidOffset;  /* that is the end of chain*/
    
    /* initialize Oid hash control section within region */
    LtSetStartOidHash(lhP, toP->offsetToOidHashData);
    LtSetStartOidFreeSpace(lhP, 0); /* all free , offset relative to D2	    */
    LtSetEndOidFreeSpace(lhP, toP->offsetOfAHashTableRegion); /* -"- 	    */
    LtSetNumOidEntries(lhP, 0);
    LtSetMaxNumOidEntries(lhP, NumberOfEntryOidData);
    for (i = 0; i < NumberOfEntryOidBuckets; i++)   /* initialize buckets   */
    	lhP->entryOidBucket[i] = InvalidOffset;	/* that is the end of chain */
    
    /* initialize Xid hash data section within region */
    for (i = 1; i<= LtGetMaxNumXidEntries(lhP); i++) {
    	eXidP = (EntryXidData *) ((Pointer) lhP  +
    	    	      LtGetStartXidHash(lhP) +
    	    	      (i - 1) * sizeof(EntryXidData));
    	eXidP->entryIndex = -1;
    	eXidP->xidData = *NullTransactionId; /* invalid transaction id 	*/
/* !integration!  ?? PointerStoreInvalidTransactionId(eXidP->xid);  */
    	eXidP->free = true;
    	/* chain all entries, relative to D1 ! */
    	eXidP->next = i  * sizeof(EntryXidData); /* all entries chained     */
    }
    
    /* initialize Oid hash data section within region */
    for (i = 1; i<= LtGetMaxNumOidEntries(lhP); i++) {
    	eOidP = (EntryOidData *) ((Pointer) lhP  +
    	    	      LtGetStartOidHash(lhP) +
    	    	      (i - 1) * sizeof(EntryOidData));
    	eOidP->entryIndex = -1;
    	eOidP->lockSrcRel = LtCreateRelId(InvalidObjectId, InvalidObjectId);
    	eOidP->lockSrcPage = InvalidObjectId;
    	eOidP->lockSrcLine = InvalidObjectId;
    	eOidP->free = true;
    	eOidP->next = i * sizeof(EntryOidData);     /* all entries chained */
    }	    	    
}


